Restructured directories
Switched to a more hierarchical structure, preparing for adding more code to flesh out the real kernel code.
This commit is contained in:
parent
642e17b084
commit
ddc9c962ef
16
README.md
16
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
|
For the 65816 and 68000 computers, the project will be built using the VBCC
|
||||||
compiler.
|
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
|
## License
|
||||||
|
|
||||||
Most of the source code for this kernel is made available under the open source
|
Most of the source code for this kernel is made available under the open source
|
||||||
|
|
32
src/Makefile
32
src/Makefile
|
@ -1,18 +1,30 @@
|
||||||
AS=vasmm68k_mot
|
export AS = vasmm68k_mot
|
||||||
CC=vc
|
export ASFLAGS = -quiet -Fvobj -nowarn=62
|
||||||
CFLAGS=+../vbcc/config/m68k-foenix -I. -Iinclude -k
|
export CC = vc
|
||||||
DEPS=syscalls_m68k.h
|
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
|
cpu = m68k
|
||||||
$(CC) $(CFLAGS) -o foenixmcp.s68 foenixmcp.o bios_m68k.o syscalls_m68k.o
|
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
|
.PHONY: all $(cpu)
|
||||||
$(AS) -Fvobj -o $@ $<
|
|
||||||
|
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)
|
%.o: %.c $(DEPS)
|
||||||
$(CC) -S -c -o $@ $< $(CFLAGS)
|
$(CC) -S -c -o $@ $< $(CFLAGS)
|
||||||
|
|
||||||
PHONEY: clean
|
.PHONEY: clean
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
del *.o
|
$(RM) *.s68 *.o
|
||||||
|
$(MAKE) --directory=$(cpu) clean
|
||||||
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -2,7 +2,7 @@
|
||||||
* Startup file for the Foenix/MCP
|
* Startup file for the Foenix/MCP
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "syscalls_m68k.h"
|
#include "m68k/syscalls_m68k.h"
|
||||||
|
|
||||||
int main(int argc, char * argv[]) {
|
int main(int argc, char * argv[]) {
|
||||||
bconout('A');
|
bconout('A');
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
S0100000666F656E69786D63702E73363817
|
|
||||||
S2240100004FF90002000041F9000101C4203C0000000467104298598066FA41FA0038327C85
|
|
||||||
S22401002000B422884EB9000100E860FE48E77F002E2F00122C2F00162A2F001A282F001E98
|
|
||||||
S224010040262F002C242F0030222F002A4E4D4CDF00FE4E752F022F014EB900010168508FE3
|
|
||||||
S2240100604E73000048E7203047F9000101AA203C000101AA672674014AAB0004670C528204
|
|
||||||
S2240100802002E5884AB3080066F45382670E2002E588247308004E92538266F22F2F001079
|
|
||||||
S2240100A04EB90001002A584F4CDF0C044E754E7148E700304AB9000101BC66262679000158
|
|
||||||
S2240100C001C4700123C0000101BC200B670C246B00044E922653200B66F42F2F000C6184E5
|
|
||||||
S2240100E0584F4CDF0C004E7548E7003047F9000101B6203C000101B2670C4A936708245BB4
|
|
||||||
S2240101004E924A9366F82F2F00102F2F00104EB9000101242F0061984FEF000C4CDF0C000C
|
|
||||||
S2240101204E750000487800414EB90001018C487800424EB90001018C487800434EB90001BE
|
|
||||||
S224010140018C4FEF000C60FE70004E75122F00072039000101C052B9000101C0307C400015
|
|
||||||
S2240101601181080070004E7548E73000262F0010242F000C20025380670260082F0361CC64
|
|
||||||
S224010180584F600270FF4CDF000C4E752F02142F000B1002488048C02F00487800014EB98F
|
|
||||||
S20E0101A00001002C504F241F4E757D
|
|
||||||
S20C0101AA000000000000000047
|
|
||||||
S20C0101B200000000000000003F
|
|
||||||
S20C0101BC000000000000000035
|
|
||||||
S804010000FA
|
|
|
@ -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
|
|
19
src/include/types.h
Normal file
19
src/include/types.h
Normal file
|
@ -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
|
|
@ -1,10 +1,20 @@
|
||||||
AS=vasmm68k_mot
|
override CFLAGS = +../../vbcc/config/m68k-foenix -I. -I../include
|
||||||
CC=vc
|
|
||||||
CFLAGS=+../../vbcc/config/m68k-foenix -I. -I../include
|
|
||||||
DEPS=syscalls_m68k.h
|
|
||||||
|
|
||||||
startup.o: startup.s
|
asources = startup_m68k.s
|
||||||
$(AS) -o $@ $<
|
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)
|
$(CC) -c -o $@ $< $(CFLAGS)
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) $(aobjects) $(cobjects)
|
||||||
|
|
|
@ -4,13 +4,15 @@
|
||||||
* NOTE: these routines are not called directly but are instead called through TRAP#13
|
* NOTE: these routines are not called directly but are instead called through TRAP#13
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
#define TEXT_MATRIX_0 ((volatile char *)0x00004000)
|
#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;
|
TEXT_MATRIX_0[text_cursor_0++] = c;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -18,20 +20,20 @@ int impl_bconout(char c) {
|
||||||
// /*
|
// /*
|
||||||
// * Set an exception handler
|
// * 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:
|
// * Inputs:
|
||||||
// * number = the number of the 68000 exception vector (2 - 255)
|
// * 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:
|
// * Return:
|
||||||
// * the previous value
|
// * the previous value
|
||||||
// */
|
// */
|
||||||
// long impl_setexc(unsigned short number, void (* handler)()) {
|
// long impl_setexc(unsigned short number, void (* handler)()) {
|
||||||
// interrupt_handler * address = 0;
|
// int32_terrupt_handler * address = 0;
|
||||||
// long result = 0;
|
// long result = 0;
|
||||||
// if ((number > 1) && (number < 256)) {
|
// if ((number > 1) && (number < 256)) {
|
||||||
// address = (interrupt_handler *)(number * 2);
|
// address = (int32_terrupt_handler *)(number * 2);
|
||||||
// result = (long)(*address);
|
// result = (long)(*address);
|
||||||
// if (handler != 0) {
|
// if (handler != 0) {
|
||||||
// *address = handler;
|
// *address = handler;
|
||||||
|
@ -44,7 +46,7 @@ int impl_bconout(char c) {
|
||||||
/*
|
/*
|
||||||
* Determine the correct BIOS function implementation to call and call it.
|
* 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) {
|
switch (function) {
|
||||||
case 1:
|
case 1:
|
||||||
return impl_bconout(param0);
|
return impl_bconout(param0);
|
|
@ -1,5 +1,6 @@
|
||||||
xref ___exit
|
|
||||||
xref ___main
|
xref ___main
|
||||||
|
xdef _bios
|
||||||
|
xdef ___exit
|
||||||
|
|
||||||
code
|
code
|
||||||
|
|
||||||
|
@ -25,10 +26,10 @@ ___exit:
|
||||||
|
|
||||||
;
|
;
|
||||||
; Function to make a BIOS system call based on the number of the BIOS function:
|
; 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 (18,sp),d7 ; Parameter 5 to D7
|
||||||
move.l (22,sp),d6 ; Parameter 4 to D6
|
move.l (22,sp),d6 ; Parameter 4 to D6
|
||||||
move.l (26,sp),d5 ; Parameter 3 to D5
|
move.l (26,sp),d5 ; Parameter 3 to D5
|
||||||
|
@ -55,4 +56,3 @@ h_trap_13:
|
||||||
addq.l #8,a7
|
addq.l #8,a7
|
||||||
|
|
||||||
rte ; Return to the caller
|
rte ; Return to the caller
|
||||||
|
|
|
@ -2,12 +2,13 @@
|
||||||
* Definitions for calling into the Foenix/MCP BIOS on the 68000 series
|
* Definitions for calling into the Foenix/MCP BIOS on the 68000 series
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
#include "syscalls_m68k.h"
|
#include "syscalls_m68k.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Call into the BIOS by issuing a TRAP #13
|
* 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
|
// * Set an exception handler
|
||||||
|
@ -31,6 +32,6 @@ extern int bios(int function, ...);
|
||||||
* Inputs:
|
* Inputs:
|
||||||
* c = character to print
|
* c = character to print
|
||||||
*/
|
*/
|
||||||
int bconout(char c) {
|
int32_t bconout(char c) {
|
||||||
return bios(1, c);
|
return bios(1, c);
|
||||||
}
|
}
|
|
@ -10,6 +10,8 @@
|
||||||
#ifndef __SYSCALLS_M68K_H
|
#ifndef __SYSCALLS_M68K_H
|
||||||
#define __SYSCALLS_M68K_H
|
#define __SYSCALLS_M68K_H
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
// /*
|
// /*
|
||||||
// * Set an exception handler
|
// * Set an exception handler
|
||||||
// *
|
// *
|
||||||
|
@ -25,6 +27,6 @@
|
||||||
* Inputs:
|
* Inputs:
|
||||||
* c = character to print
|
* c = character to print
|
||||||
*/
|
*/
|
||||||
extern int bconout(char c);
|
extern int32_t bconout(char c);
|
||||||
|
|
||||||
#endif
|
#endif
|
103
src/mapfile
103
src/mapfile
|
@ -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
|
|
256
src/memory.c
Normal file
256
src/memory.c
Normal file
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
84
src/memory.h
Normal file
84
src/memory.h
Normal file
|
@ -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
|
45
src/proc.h
Normal file
45
src/proc.h
Normal file
|
@ -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
|
|
@ -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
|
|
|
@ -4,9 +4,9 @@
|
||||||
-asv=vasmm68k_mot -Fvobj -nowarn=62 %s -o %s
|
-asv=vasmm68k_mot -Fvobj -nowarn=62 %s -o %s
|
||||||
-rm=del %s
|
-rm=del %s
|
||||||
-rmv=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
|
-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
|
-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
|
-ul=-l%s
|
||||||
-cf=-F%s
|
-cf=-F%s
|
||||||
|
|
Loading…
Reference in a new issue