diff --git a/README.md b/README.md index 5caa0fe..1a527e4 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,22 @@ Please refer to processor specific building instructions that will be included. For the 65816 and 68000 computers, the project will be built using the VBCC compiler. +### Building for the M68000 CPU + +Building this project requires the [VBCC](http://www.compilers.de/vbcc.html) compiler and the +```MAKE``` utility. Using your command line, go into the ```src``` directory and type: + +``` +make all +``` +to build the kernel. + +To remove binaries and intermediate files: + +``` +make clean +``` + ## License Most of the source code for this kernel is made available under the open source diff --git a/src/Makefile b/src/Makefile index e337780..c251075 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,18 +1,30 @@ -AS=vasmm68k_mot -CC=vc -CFLAGS=+../vbcc/config/m68k-foenix -I. -Iinclude -k -DEPS=syscalls_m68k.h +export AS = vasmm68k_mot +export ASFLAGS = -quiet -Fvobj -nowarn=62 +export CC = vc +export CFLAGS = +../vbcc/config/m68k-foenix -I. -Iinclude +export RM = cmd /C del /Q /F -foenixmcp.s68: foenixmcp.o bios_m68k.o syscalls_m68k.o startup_m68k.o - $(CC) $(CFLAGS) -o foenixmcp.s68 foenixmcp.o bios_m68k.o syscalls_m68k.o +cpu = m68k +cpu_assembly_src := $(wildcard $(cpu)/*.s) +cpu_c_src := $(wildcard $(cpu)/*.c) +cpu_assembly_obj := $(subst .s,.o,$(cpu_assembly_src)) +cpu_c_obj := $(subst .c,.o,$(cpu_c_src)) -startup_m68k.o: startup_m68k.s - $(AS) -Fvobj -o $@ $< +.PHONY: all $(cpu) + +all: foenixmcp.s68 $(cpu) + +$(cpu): + $(MAKE) --directory=$@ + +foenixmcp.s68: foenixmcp.o $(cpu) + $(CC) $(CFLAGS) -o foenixmcp.s68 foenixmcp.o $(cpu_c_obj) %.o: %.c $(DEPS) $(CC) -S -c -o $@ $< $(CFLAGS) -PHONEY: clean +.PHONEY: clean clean: - del *.o + $(RM) *.s68 *.o + $(MAKE) --directory=$(cpu) clean diff --git a/src/bios_m68k.asm b/src/bios_m68k.asm deleted file mode 100644 index eb2a9ba..0000000 --- a/src/bios_m68k.asm +++ /dev/null @@ -1,48 +0,0 @@ - idnt "bios_m68k.c" - opt o+,ol+,op+,oc+,ot+,oj+,ob+,om+ - section "CODE",code - public _impl_bconout - cnop 0,4 -_impl_bconout - movem.l l3,-(a7) - move.b (7+l5,a7),d1 - move.l _text_cursor_0,d0 - addq.l #1,_text_cursor_0 - move.l #16384,a0 - move.b d1,(0,a0,d0.l) - moveq #0,d0 -l1 -l3 reg -l5 equ 0 - rts -; stacksize=0 - opt o+,ol+,op+,oc+,ot+,oj+,ob+,om+ - public _bios_dispatch - cnop 0,4 -_bios_dispatch - movem.l l11,-(a7) - move.l (8+l13,a7),d3 - move.l (4+l13,a7),d2 - move.l d2,d0 - subq.l #1,d0 - beq l9 - bra l10 -l9 - move.l d3,-(a7) - jsr _impl_bconout - addq.w #4,a7 - bra l6 -l10 - moveq #-1,d0 -l8 -l6 -l11 reg d2/d3 - movem.l (a7)+,d2/d3 -l13 equ 8 - rts -; stacksize=16 - public _text_cursor_0 - section "DATA",data - cnop 0,4 -_text_cursor_0 - dc.l 0 diff --git a/src/foenixmcp b/src/foenixmcp deleted file mode 100755 index 89cb440..0000000 --- a/src/foenixmcp +++ /dev/null @@ -1,22 +0,0 @@ -S00C0000666F656E69786D63702A -S2240100004FF90002000041F900010224203C0000000467104298598066FA41FA001A327C42 -S22401002000B422884EB90001010060FE4E7370004E754E4D4E7548A73F3E3C4F4E6F3F0EA2 -S224010040302F00040C4000066C08E5484EBB00146004700144803C5F4E673E4E4C9F7CFC4F -S2240100604E730001002E000101740001002E0001002E0001002E00010194000048E7203072 -S22401008047F90001020A203C0001020A672674014AAB0004670C52822002E5884AB30800CE -S2240100A066F45382670E2002E588247308004E92538266F22F2F00104EB90001002A584F14 -S2240100C04CDF0C044E754E7148E700304AB90001021C6626267900010224700123C0000135 -S2240100E0021C200B670C246B00044E922653200B66F42F2F000C6184584F4CDF0C004E75DD -S22401010048E7003047F900010216203C00010212670C4A936708245B4E924A9366F82F2FF9 -S22401012000102F2F00104EB90001013C2F0061984FEF000C4CDF0C004E75000048E700302B -S22401014047FA0026244B60121012488048C02F004EB9000101EC584F528A200A66EA60FEE0 -S22401016070004CDF0C004E75466F656E69782F4D43500000122F000B20390001022052B9C4 -S22401018000010220207C00AFA0001181080070004E754E712F02322F000E226F001091C825 -S2240101A07400B27C00016316B27C0100641070003001D08020402410200967022089200298 -S2240101C0241F4E7548E72020342F000E246F00102F0A700030022F00487800054EB90001B9 -S2240101E000324FEF000C4CDF04044E752F02142F000B1002488048C02F00487800014EB92F -S20E01020000010032504F241F4E7516 -S20C01020A0000000000000000E6 -S20C0102120000000000000000DE -S20C01021C0000000000000000D4 -S804010000FA diff --git a/src/foenixmcp.asm b/src/foenixmcp.asm deleted file mode 100644 index d3cb64c..0000000 --- a/src/foenixmcp.asm +++ /dev/null @@ -1,23 +0,0 @@ - idnt "foenixmcp.c" - opt o+,ol+,op+,oc+,ot+,oj+,ob+,om+ - section "CODE",code - public _main - cnop 0,4 -_main - movem.l l6,-(a7) - move.l #65,-(a7) - jsr _bconout - move.l #66,-(a7) - jsr _bconout - move.l #67,-(a7) - jsr _bconout - add.w #12,a7 -l3 - bra l3 -l5 - moveq #0,d0 -l1 -l6 reg -l8 equ 0 - rts - public _bconout diff --git a/src/foenixmcp.c b/src/foenixmcp.c index c7e8466..f7f9b12 100644 --- a/src/foenixmcp.c +++ b/src/foenixmcp.c @@ -2,7 +2,7 @@ * Startup file for the Foenix/MCP */ -#include "syscalls_m68k.h" +#include "m68k/syscalls_m68k.h" int main(int argc, char * argv[]) { bconout('A'); diff --git a/src/foenixmcp.s68 b/src/foenixmcp.s68 deleted file mode 100644 index 46234cf..0000000 --- a/src/foenixmcp.s68 +++ /dev/null @@ -1,19 +0,0 @@ -S0100000666F656E69786D63702E73363817 -S2240100004FF90002000041F9000101C4203C0000000467104298598066FA41FA0038327C85 -S22401002000B422884EB9000100E860FE48E77F002E2F00122C2F00162A2F001A282F001E98 -S224010040262F002C242F0030222F002A4E4D4CDF00FE4E752F022F014EB900010168508FE3 -S2240100604E73000048E7203047F9000101AA203C000101AA672674014AAB0004670C528204 -S2240100802002E5884AB3080066F45382670E2002E588247308004E92538266F22F2F001079 -S2240100A04EB90001002A584F4CDF0C044E754E7148E700304AB9000101BC66262679000158 -S2240100C001C4700123C0000101BC200B670C246B00044E922653200B66F42F2F000C6184E5 -S2240100E0584F4CDF0C004E7548E7003047F9000101B6203C000101B2670C4A936708245BB4 -S2240101004E924A9366F82F2F00102F2F00104EB9000101242F0061984FEF000C4CDF0C000C -S2240101204E750000487800414EB90001018C487800424EB90001018C487800434EB90001BE -S224010140018C4FEF000C60FE70004E75122F00072039000101C052B9000101C0307C400015 -S2240101601181080070004E7548E73000262F0010242F000C20025380670260082F0361CC64 -S224010180584F600270FF4CDF000C4E752F02142F000B1002488048C02F00487800014EB98F -S20E0101A00001002C504F241F4E757D -S20C0101AA000000000000000047 -S20C0101B200000000000000003F -S20C0101BC000000000000000035 -S804010000FA diff --git a/src/include/stdarg.h b/src/include/stdarg.h deleted file mode 100644 index de69fa8..0000000 --- a/src/include/stdarg.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __STDARG_H -#define __STDARG_H - -typedef unsigned char *va_list; -#define __va_align(type) (__alignof(type)>=4?__alignof(type):4) -#define __va_do_align(vl,type) ((vl)=(char *)((((unsigned int)(vl))+__va_align(type)-1)/__va_align(type)*__va_align(type))) -#define __va_mem(vl,type) (__va_do_align((vl),type),(vl)+=sizeof(type),((type*)(vl))[-1]) -#define va_start(ap, lastarg) ((ap)=(va_list)(&lastarg+1)) -#define va_arg(vl,type) __va_mem(vl,type) -#define va_end(vl) ((vl)=0) -#define va_copy(new,old) ((new)=(old)) - -#endif diff --git a/src/include/types.h b/src/include/types.h new file mode 100644 index 0000000..ce91974 --- /dev/null +++ b/src/include/types.h @@ -0,0 +1,19 @@ +/* + * Definitions of types used by the kernel + */ + +#ifndef __TYPES_H +#define __TYPES_H + +/* + * Integer types in their standard sizes, signed and unsigned. + */ + +typedef char int8_t; +typedef unsigned char uint8_t; +typedef short int16_t; +typedef unsigned short uint16_t; +typedef int int32_t; +typedef unsigned int uint32_t; + +#endif diff --git a/src/m68k/Makefile b/src/m68k/Makefile index 877e159..a31dad8 100644 --- a/src/m68k/Makefile +++ b/src/m68k/Makefile @@ -1,10 +1,20 @@ -AS=vasmm68k_mot -CC=vc -CFLAGS=+../../vbcc/config/m68k-foenix -I. -I../include -DEPS=syscalls_m68k.h +override CFLAGS = +../../vbcc/config/m68k-foenix -I. -I../include -startup.o: startup.s - $(AS) -o $@ $< +asources = startup_m68k.s +aobjects = $(subst .s,.o,$(asources)) +csources = bios_m68k.c syscalls_m68k.c +cobjects = $(subst .c,.o,$(csources)) -%.o: %.c $(DEPS) +.PHONY: all +all: $(aobjects) $(cobjects) + +%.o: $.s + $(AS) $(ASFLAGS) -o $@ $< + +%.o: %.c $(CC) -c -o $@ $< $(CFLAGS) + +.PHONY: clean + +clean: + $(RM) $(aobjects) $(cobjects) diff --git a/src/bios_m68k.c b/src/m68k/bios_m68k.c similarity index 64% rename from src/bios_m68k.c rename to src/m68k/bios_m68k.c index ea9e263..604a7a0 100644 --- a/src/bios_m68k.c +++ b/src/m68k/bios_m68k.c @@ -4,13 +4,15 @@ * NOTE: these routines are not called directly but are instead called through TRAP#13 */ +#include "types.h" + #define TEXT_MATRIX_0 ((volatile char *)0x00004000) -typedef void (* interrupt_handler)(); +typedef void (* int32_terrupt_handler)(); -int text_cursor_0 = 0; +int32_t text_cursor_0 = 0; -int impl_bconout(char c) { +int32_t impl_bconout(char c) { TEXT_MATRIX_0[text_cursor_0++] = c; return 0; } @@ -18,20 +20,20 @@ int impl_bconout(char c) { // /* // * Set an exception handler // * -// * If handler is the nil pointer, just return the current value. +// * If handler is the nil point32_ter, just return the current value. // * // * Inputs: // * number = the number of the 68000 exception vector (2 - 255) -// * handler = pointer to the handler (must be coded as an interrupt handler) +// * handler = point32_ter to the handler (must be coded as an int32_terrupt handler) // * // * Return: // * the previous value // */ // long impl_setexc(unsigned short number, void (* handler)()) { -// interrupt_handler * address = 0; +// int32_terrupt_handler * address = 0; // long result = 0; // if ((number > 1) && (number < 256)) { -// address = (interrupt_handler *)(number * 2); +// address = (int32_terrupt_handler *)(number * 2); // result = (long)(*address); // if (handler != 0) { // *address = handler; @@ -44,7 +46,7 @@ int impl_bconout(char c) { /* * Determine the correct BIOS function implementation to call and call it. */ -int bios_dispatch(int function, int param0, int param1, int param2, int param3, int param4, int param5) { +int32_t bios_dispatch(int32_t function, int32_t param0, int32_t param1, int32_t param2, int32_t param3, int32_t param4, int32_t param5) { switch (function) { case 1: return impl_bconout(param0); diff --git a/src/startup_m68k.s b/src/m68k/startup_m68k.s similarity index 89% rename from src/startup_m68k.s rename to src/m68k/startup_m68k.s index 1b05f83..4f7cbdd 100644 --- a/src/startup_m68k.s +++ b/src/m68k/startup_m68k.s @@ -1,5 +1,6 @@ - xref ___exit xref ___main + xdef _bios + xdef ___exit code @@ -25,10 +26,10 @@ ___exit: ; ; Function to make a BIOS system call based on the number of the BIOS function: -; int bios(int number, int p0, int p1, int p2, int p3, int p4, int p5) +; int32_t bios(int32_t number, int32_t p0, int32_t p1, int32_t p2, int32_t p3, int32_t p4, int32_t p5) ; -_bios:: movem.l d1-d7,-(sp) - +_bios: + movem.l d1-d7,-(sp) move.l (18,sp),d7 ; Parameter 5 to D7 move.l (22,sp),d6 ; Parameter 4 to D6 move.l (26,sp),d5 ; Parameter 3 to D5 @@ -55,4 +56,3 @@ h_trap_13: addq.l #8,a7 rte ; Return to the caller - diff --git a/src/syscalls_m68k.c b/src/m68k/syscalls_m68k.c similarity index 88% rename from src/syscalls_m68k.c rename to src/m68k/syscalls_m68k.c index 35ffb4c..92da8bd 100644 --- a/src/syscalls_m68k.c +++ b/src/m68k/syscalls_m68k.c @@ -2,12 +2,13 @@ * Definitions for calling into the Foenix/MCP BIOS on the 68000 series */ +#include "types.h" #include "syscalls_m68k.h" /* * Call into the BIOS by issuing a TRAP #13 */ -extern int bios(int function, ...); +extern int32_t bios(int32_t function, ...); // /* // * Set an exception handler @@ -31,6 +32,6 @@ extern int bios(int function, ...); * Inputs: * c = character to print */ -int bconout(char c) { +int32_t bconout(char c) { return bios(1, c); } \ No newline at end of file diff --git a/src/syscalls_m68k.h b/src/m68k/syscalls_m68k.h similarity index 92% rename from src/syscalls_m68k.h rename to src/m68k/syscalls_m68k.h index 56ca9b6..7f2151f 100644 --- a/src/syscalls_m68k.h +++ b/src/m68k/syscalls_m68k.h @@ -10,6 +10,8 @@ #ifndef __SYSCALLS_M68K_H #define __SYSCALLS_M68K_H +#include "types.h" + // /* // * Set an exception handler // * @@ -25,6 +27,6 @@ * Inputs: * c = character to print */ -extern int bconout(char c); +extern int32_t bconout(char c); #endif diff --git a/src/mapfile b/src/mapfile deleted file mode 100644 index 0444f17..0000000 --- a/src/mapfile +++ /dev/null @@ -1,103 +0,0 @@ -..\vbcc\targets\m68k-foenix\lib\libvc.a (_main.o) needed due to ___main - -Files: - startup_m68k.o: CODE 10000(62) hex - ..\vbcc\targets\m68k-foenix\lib\libvc.a (_main.o): CODE 10064(be), DATA 101bc(4), BSS 101c4(4) hex - foenixmcp.o: CODE 10124(28) hex - bios_m68k.o: CODE 1014c(40), DATA 101c0(4) hex - syscalls_m68k.o: CODE 1018c(1e) hex - INITEXIT: .dtors 101aa(8), .ctors 101b2(8) hex - - -Section mapping (numbers in hex): ------------------------------- - 00010000 text (size 1aa) - 00010000 - 00010062 startup_m68k.o(CODE) - 00010064 - 00010122 _main.o(CODE) - 00010124 - 0001014c foenixmcp.o(CODE) - 0001014c - 0001018c bios_m68k.o(CODE) - 0001018c - 000101aa syscalls_m68k.o(CODE) ------------------------------- - 000101aa .dtors (size 8, allocated 0) - 000101aa - 000101b2 INITEXIT(.dtors) ------------------------------- - 000101b2 .ctors (size 8, allocated 0) - 000101b2 - 000101ba INITEXIT(.ctors) ------------------------------- - 000101bc data (size 8, allocated 4) - 000101bc - 000101c0 _main.o(DATA) - 000101c0 - 000101c4 bios_m68k.o(DATA) ------------------------------- - 000101c4 bss (size 4, allocated 0) - 000101c4 - 000101c8 _main.o(BSS) - - -Symbols of text: - 0x00000000 l8: local abs, size 0 - 0x00000000 l5: local abs, size 0 - 0x00000000 l3: local abs, size 0 - 0x00000000 l6: local abs, size 0 - 0x00000004 l5: local abs, size 0 - 0x00000004 l3: local abs, size 0 - 0x00000008 l43: local abs, size 0 - 0x00000008 l13: local abs, size 0 - 0x00000008 l31: local abs, size 0 - 0x0000000c l11: local abs, size 0 - 0x0000000c l18: local abs, size 0 - 0x00000c00 l41: local abs, size 0 - 0x00000c00 l29: local abs, size 0 - 0x00000c04 l16: local abs, size 0 - 0x00010000 coldboot: local reloc, size 0 - 0x00010014 clrloop: local reloc, size 0 - 0x00010024 callmain: local reloc, size 0 - 0x0001002a ___exit: global reloc, size 0 - 0x0001002c _bios: global reloc, size 0 - 0x00010054 h_trap_13: local reloc, size 0 - 0x00010064 __Exit: global reloc, size 0 - 0x0001007e l12: local reloc, size 0 - 0x0001008a l14: local reloc, size 0 - 0x0001008e l13: local reloc, size 0 - 0x0001009c l15: local reloc, size 0 - 0x000100b0 _exit: global reloc, size 0 - 0x000100ce l27: local reloc, size 0 - 0x000100da l28: local reloc, size 0 - 0x000100e2 l23: local reloc, size 0 - 0x000100e8 ___main: global reloc, size 0 - 0x000100fe l39: local reloc, size 0 - 0x00010106 l40: local reloc, size 0 - 0x00010124 _main: global reloc, size 0 - 0x00010146 l3: local reloc, size 0 - 0x00010148 l5: local reloc, size 0 - 0x0001014a l1: local reloc, size 0 - 0x0001014c _impl_bconout: global reloc, size 0 - 0x00010166 l1: local reloc, size 0 - 0x00010168 _bios_dispatch: global reloc, size 0 - 0x0001017c l9: local reloc, size 0 - 0x00010184 l10: local reloc, size 0 - 0x00010186 l6: local reloc, size 0 - 0x00010186 l8: local reloc, size 0 - 0x0001018c _bconout: global reloc, size 0 - 0x000101a6 l1: local reloc, size 0 - -Symbols of .dtors: - 0x000101aa ___DTOR_LIST__: global reloc object, size 8 - -Symbols of .ctors: - 0x000101b2 ___CTOR_LIST__: global reloc object, size 8 - -Symbols of data: - 0x000101bc l21: local reloc, size 0 - 0x000101c0 _text_cursor_0: global reloc, size 0 - -Symbols of bss: - 0x000101c4 ___firstexit: global reloc, size 0 - -Linker symbols: - 0x00010000 RAMSTART: global abs, size 0 - 0x00010000 RAMSIZE: global abs, size 0 - 0x00000400 STACKLEN: global abs, size 0 - 0x000101c8 ___heap: global abs, size 0 - 0x0001fc00 ___heapend: global abs, size 0 - 0x000101c4 ___BSSSTART: global abs, size 0 - 0x00000004 ___BSSSIZE: global abs, size 0 - 0x00020000 ___STACK: global abs, size 0 diff --git a/src/memory.c b/src/memory.c new file mode 100644 index 0000000..cd01004 --- /dev/null +++ b/src/memory.c @@ -0,0 +1,256 @@ +/* + * Memory mangament system + * + * Memory will be managed in 4KB "pages". A program can allocate blocks of these pages. + * While a program my request so many bytes of storage, it will be allocated complete pages. + * + * Memory can be allocated, in which case, the kernel will find and return the memory, + * or memory can be reserved, in which case the program specifies which memory pages it is using. + */ + +#include "memory.h" + +#define MEM_PAGE_SIZE 4096 /* The size of a page in bytes */ +#define MEM_MAX_PAGES 0x40 /* The maximum number of pages of system RAM on this computer */ +#define MEM_OWN_KERNEL 1 /* "PID" of the kernel */ +#define MEM_OWN_NULL 2 /* "PID" of memory not in the system */ +#define MEM_TAG_VECTORS 1 /* Tag for the vector block */ + +/* + * Structure to track who owns a page of memory + */ +typedef struct s_mem_ownership { + unsigned short pid; + unsigned short tag; +} t_mem_ownership, * p_mem_ownership; + +t_mem_ownership mem_pages[MEM_MAX_PAGES]; /* Array containing the information about who owns a page */ + +/* + * Convert an address to a page number + */ +short mem_addr_to_page(uint32_t address) { + return (address >> 12) & 0xffff; +} + +/* + * Convert a page number to the address of its first byte + */ +uint32_t mem_page_to_addr(short page) { + return ((page & 0xffff) << 12); +} + +/* + * Initialize the memory management system + */ +void mem_init() { + int page; + + /* Initialize the page ownership for all pages to "unowned" */ + for (page = 0; page < MEM_MAX_PAGES; page++) { + mem_pages[page].pid = 0; + mem_pages[page].tag = 0; + } + + /* The kernel should now claim the memory it needs to operate */ + mem_reserve(MEM_OWN_KERNEL, MEM_TAG_VECTORS, 0, mem_page_to_addr(1)); /* Reserve the first page for system vectors */ + + /* TODO: scan the system for memory or set it based on the machine ID */ + /* TODO: reserve the kernel's working memory */ +} + +/* + * Fill out an s_memory_info structure detailing how much memory is available. + * + * Inputs: + * info = pointer to an s_memory_info structure to be filled out + */ +void mem_statistics(p_memory_info info) { + short page; + short contiguous_free_count = 0; + short first_free = -1; + + info->total_pages = 0; + info->allocated_pages = 0; + info->free_pages = 0; + info->max_contiguous_free = 0; + + for (page = 0; page < MEM_MAX_PAGES; page++) { + if (mem_pages[page].pid == MEM_OWN_NULL) { + /* If we've reached a non-existant page, we're done. */ + break; + } + + info->total_pages++; + if (mem_pages[page].pid == 0) { + /* We have a free page... count it and see if it's the first of a block */ + info->free_pages++; + contiguous_free_count++; + if (first_free == -1) { + first_free = page; + } + + } else { + /* We have an allocated page... count it and see if we need to close out a contiguous free block */ + info->allocated_pages++; + + if (first_free != -1) { + /* The previous page was free... check to see if the free block before it is largest */ + if (contiguous_free_count > info->max_contiguous_free) { + info->max_contiguous_free = contiguous_free_count; + } + + contiguous_free_count = 0; + first_free = -1; + } + } + } + + /* If the end of memory is free... check if it's the biggest free block */ + if (contiguous_free_count > info->max_contiguous_free) { + info->max_contiguous_free = contiguous_free_count; + } +} + +/* + * Allocate a block of memory for a program. + * + * Inputs: + * pid = the ID of the process that will own this memory + * tag = a number that must be unique per allocated block in a process + * bytes = the number of bytes to allocate + * + * Returns: + * the address of the first byte of the allocated block, 0 for failure + */ +uint32_t mem_alloc(unsigned short pid, unsigned short tag, uint32_t bytes) { + short page; + short i; + short first_free = -1; + short free_count = 0; + + for (page = 0; page < MEM_MAX_PAGES; page++) { + if (mem_pages[page].pid != 0) { + /* Page is not free... reset our tracking information */ + if (first_free != -1) { + free_count = 0; + first_free = -1; + } + + } else { + /* Page is free... */ + if (first_free == -1) { + /* If the last one was taken, this is the first free page */ + first_free = page; + } + + free_count++; + + if (free_count * MEM_PAGE_SIZE >= bytes) { + /* We have found enough pages to hold the requested amount of memory... */ + + /* Allocate the memory to this process */ + for (i = first_free; i < free_count + first_free - 1; i++) { + mem_pages[i].pid = pid; + mem_pages[i].tag = tag; + } + + /* Return the starting address for the block */ + return mem_page_to_addr(first_free); + } + } + } + + /* We did not find a block big enough... return 0 */ + return 0; +} + +/* + * Reserve a block of memory for a program. + * + * NOTE: although the caller specifies the starting and ending addresses + * needed, these addresses may not be page aligned. The FULL pages + * containing the addresses will be reserved. + * + * Inputs: + * pid = the ID of the process that will own this memory + * tag = a number that must be unique per allocated block in a process + * start_addr = the address of the first byte to reserve + * end_addr = the address of the last byte to reserve + * + * Returns: + * 0 on success, any other number is a failure + */ +int mem_reserve(unsigned short pid, unsigned short tag, uint32_t start_addr, uint32_t end_addr) { + short page; + short start_page = mem_addr_to_page(start_addr); + short end_page = mem_addr_to_page(end_addr); + + /* Check to see if all the pages are free */ + for (page = start_page; page <= end_page; page++) { + if (mem_pages[page].pid != 0) { + /* If not, return an error */ + /* TODO: return a real error number */ + return -1; + } + } + + /* Reserve the pages */ + for (page = start_page; page <= end_page; page++) { + mem_pages[page].pid = 0; + mem_pages[page].tag = 0; + } + + return 0; +} + +/* + * Return a block of memory to the kernel. + * + * Inputs: + * pid = the ID of the process that will own this memory + * address = the address of the first byte to return + */ +void mem_free(unsigned short pid, uint32_t address) { + short tag, p, start_page, end_page; + short page = mem_addr_to_page(address); + + if (mem_pages[page].pid == pid) { + /* If this page is owned by the calling process, get the tag for this block */ + tag = mem_pages[page].tag; + + /* Scan the previous pages until we find a page not in this block */ + for (p = page; (mem_pages[p].pid == pid) && (mem_pages[p].tag == tag); p--) { + start_page = p; + } + + /* Scan the next pages until we find a page not in this block */ + for (p = page; (mem_pages[p].pid == pid) && (mem_pages[p].tag == tag); p++) { + end_page = p; + } + + /* Mark all pages from start to end as unowned */ + for (p = start_page; p <= end_page; p++) { + mem_pages[p].pid = 0; + mem_pages[p].tag = 0; + } + } +} + +/* + * Return all memory allocated by a process. + * + * Inputs: + * pid = the ID of the process that will own this memory + */ +void mem_free_all(unsigned short pid) { + int page; + + /* Reset all pages owned by this PID to unowned */ + for (page = 0; page < MEM_MAX_PAGES; page++) { + if (mem_pages[page].pid = pid) { + mem_pages[page].pid = 0; + mem_pages[page].tag = 0; + } + } +} diff --git a/src/memory.h b/src/memory.h new file mode 100644 index 0000000..234d8e3 --- /dev/null +++ b/src/memory.h @@ -0,0 +1,84 @@ +/* + * Memory mangament system + * + * Memory will be managed in 4KB "pages". A program can allocate blocks of these pages. + * While a program my request so many bytes of storage, it will be allocated complete pages. + * + * Memory can be allocated, in which case, the kernel will find and return the memory, + * or memory can be reserved, in which case the program specifies which memory pages it is using. + */ + +#ifndef __MEMORY_H +#define __MEMORY_H + +#include "types.h" + +typedef struct s_memory_info { + short total_pages; + short allocated_pages; + short free_pages; + short max_contiguous_free; +} t_memory_info, * p_memory_info; + +/* + * Initialize the memory management system + */ +extern void mem_init(); + +/* + * Fill out an s_memory_info structure detailing how much memory is available. + * + * Inputs: + * info = pointer to an s_memory_info structure to be filled out + */ +extern void mem_statistics(p_memory_info info); + +/* + * Allocate a block of memory for a program. + * + * Inputs: + * pid = the ID of the process that will own this memory + * tag = a number that must be unique per allocated block in a process + * bytes = the number of bytes to allocate + * + * Returns: + * the address of the first byte of the allocated block, 0 for failure + */ +extern uint32_t mem_alloc(unsigned short pid, unsigned short tag, uint32_t bytes); + +/* + * Reserve a block of memory for a program. + * + * NOTE: although the caller specifies the starting and ending addresses + * needed, these addresses may not be page aligned. The FULL pages + * containing the addresses will be reserved. + * + * Inputs: + * pid = the ID of the process that will own this memory + * tag = a number that must be unique per allocated block in a process + * start_addr = the address of the first byte to reserve + * end_addr = the address of the last byte to reserve + * + * Returns: + * 0 on success, any other number is a failure + */ +extern int mem_reserve(unsigned short pid, unsigned short tag, uint32_t start_addr, uint32_t end_addr); + +/* + * Return a block of memory to the kernel. + * + * Inputs: + * pid = the ID of the process that will own this memory + * address = the address of the first byte to return + */ +extern void mem_free(unsigned short pid, uint32_t address); + +/* + * Return all memory allocated by a process. + * + * Inputs: + * pid = the ID of the process that will own this memory + */ +extern void mem_free_all(unsigned short pid); + +#endif \ No newline at end of file diff --git a/src/proc.h b/src/proc.h new file mode 100644 index 0000000..2506a11 --- /dev/null +++ b/src/proc.h @@ -0,0 +1,45 @@ +/* + * Processes + */ + +#ifndef __PROC_H +#define __PROC_H + +#define PROC_NAME_SIZE 8 + +#define PROC_STAT_RUNNING 0x01 +#define PROC_STAT_IDLE 0x02 + +typedef struct s_proc_info { + short status; /* The status of the process */ + short pid; /* The ID of the process */ + char name[PROC_NAME_SIZE]; /* A readable name for the process */ + int return_value; /* The value returned by the process when it ended */ +} t_proc_info, * p_proc_info; + +/* + * Initialize the process management system + */ +extern void proc_init(); + +/* + * Terminate the current process with a return value + * + * Inputs: + * return_value = the value to return from the process + */ +extern void proc_terminate(int return_value); + +/* + * Terminate a process with no return value. + */ +extern void proc_kill(short pid); + +/* + * Mark the process as running and make it the current process + * + * Mark the process that was current as IDLE + */ +extern void proc_running(short pid); + +#endif \ No newline at end of file diff --git a/src/syscalls_m68k.asm b/src/syscalls_m68k.asm deleted file mode 100644 index ac7077d..0000000 --- a/src/syscalls_m68k.asm +++ /dev/null @@ -1,21 +0,0 @@ - idnt "syscalls_m68k.c" - opt o+,ol+,op+,oc+,ot+,oj+,ob+,om+ - section "CODE",code - public _bconout - cnop 0,4 -_bconout - movem.l l3,-(a7) - move.b (7+l5,a7),d2 - move.b d2,d0 - ext.w d0 - ext.l d0 - move.l d0,-(a7) - move.l #1,-(a7) - jsr _bios - addq.w #8,a7 -l1 -l3 reg d2 - movem.l (a7)+,d2 -l5 equ 4 - rts - public _bios diff --git a/vbcc/config/m68k-foenix b/vbcc/config/m68k-foenix index 5c569b4..6722d26 100644 --- a/vbcc/config/m68k-foenix +++ b/vbcc/config/m68k-foenix @@ -4,9 +4,9 @@ -asv=vasmm68k_mot -Fvobj -nowarn=62 %s -o %s -rm=del %s -rmv=del %s --ld=vlink -bsrec28 -x -Cvbcc startup_m68k.o %s %s -L..\vbcc\targets\m68k-foenix\lib -T..\vbcc\targets\m68k-foenix\vlink.cmd -lvc -o %s -Mmapfile +-ld=vlink -bsrec28 -x -Cvbcc m68k\startup_m68k.o %s %s -L..\vbcc\targets\m68k-foenix\lib -T..\vbcc\targets\m68k-foenix\vlink.cmd -lvc -o %s -Mmapfile -l2=vlink -bsrec28 -x -Cvbcc %s %s -L..\vbcc\targets\m68k-foenix\lib -T..\vbcc\targets\m68k-foenix\vlink.cmd -o %s -Mmapfile --ldv=vlink -bsrec28 -t -x -Cvbcc src\m68k\startup.o %s %s -L..\vbcc\targets\m68k-foenix\lib -T..\vbcc\targets\m68k-foenix\vlink.cmd -lvc -o %s -Mmapfile +-ldv=vlink -bsrec28 -t -x -Cvbcc m68k\startup.o %s %s -L..\vbcc\targets\m68k-foenix\lib -T..\vbcc\targets\m68k-foenix\vlink.cmd -lvc -o %s -Mmapfile -l2v=vlink -bsrec28 -t -x -Cvbcc %s %s -L..\vbcc\targets\m68k-foenix\lib -T..\vbcc\targets\m68k-foenix\vlink.cmd -o %s -Mmapfile -ul=-l%s -cf=-F%s