SYS_EXIT, RUN command
Added ability to RUN a PGX file and the SYS_EXIT call.
This commit is contained in:
parent
ee4d8db4fa
commit
a3dab23bac
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -50,3 +50,6 @@ modules.order
|
||||||
Module.symvers
|
Module.symvers
|
||||||
Mkfile.old
|
Mkfile.old
|
||||||
dkms.conf
|
dkms.conf
|
||||||
|
samples/HelloPGX/hello.pgx
|
||||||
|
samples/HelloPGX/hello.pgx
|
||||||
|
samples/HelloPGX/hello.lst
|
||||||
|
|
|
@ -7,28 +7,32 @@ F00:0006
|
||||||
F00:0007 dc.b "PGX", $02
|
F00:0007 dc.b "PGX", $02
|
||||||
S01:00010000: 50 47 58
|
S01:00010000: 50 47 58
|
||||||
S01:00010003: 02
|
S01:00010003: 02
|
||||||
F00:0008 dc.l _start
|
F00:0008 dc.l start
|
||||||
S01:00010004: 00 01 00 08
|
S01:00010004: 00 01 00 08
|
||||||
F00:0009
|
F00:0009
|
||||||
F00:0010 _start: move.l #_greet_end-_greet+1,d3 ; Length of the message
|
F00:0010 start: move.l #$13,d0 ; sys_chan_write
|
||||||
S01:00010008: 76 0E
|
S01:00010008: 70 13
|
||||||
F00:0011 move.l #_greet,d2 ; Pointer to the message
|
F00:0011 clr.l d1 ; Channel #0
|
||||||
S01:0001000A: 24 3C 00 01 00 18
|
S01:0001000A: 72 00
|
||||||
F00:0012 clr.l d1 ; Write to channel #0 (main screen)
|
F00:0012 move.l #greet,d2 ; Pointer to message
|
||||||
S01:00010010: 72 00
|
S01:0001000C: 24 3C 00 01 00 1C
|
||||||
F00:0013 move.l #$14,d0 ; sys_chan_write_b
|
F00:0013 move.l #greet_end-greet+1,d3 ; Length of message
|
||||||
S01:00010012: 70 14
|
S01:00010012: 76 0E
|
||||||
F00:0014 trap #15 ; Call it
|
F00:0014 trap #15
|
||||||
S01:00010014: 4E 4F
|
S01:00010014: 4E 4F
|
||||||
F00:0015
|
F00:0015
|
||||||
F00:0016 _lock: bra _lock
|
F00:0016 done: clr.l d0 ; sys_exit
|
||||||
S01:00010016: 60 FE
|
S01:00010016: 70 00
|
||||||
F00:0017
|
F00:0017 clr.l d1 ; Return value = 0
|
||||||
F00:0018 _greet: dc.b "Hello, world!"
|
S01:00010018: 72 00
|
||||||
S01:00010018: 48 65 6C 6C 6F 2C 20 77 6F 72 6C 64 21
|
F00:0018 trap #15
|
||||||
F00:0019 _greet_end: dc.b 0
|
S01:0001001A: 4E 4F
|
||||||
S01:00010025: 00
|
F00:0019
|
||||||
F00:0020
|
F00:0020 greet: dc.b "Hello, world!"
|
||||||
|
S01:0001001C: 48 65 6C 6C 6F 2C 20 77 6F 72 6C 64 21
|
||||||
|
F00:0021 greet_end: dc.b 0
|
||||||
|
S01:00010029: 00
|
||||||
|
F00:0022
|
||||||
|
|
||||||
|
|
||||||
Sections:
|
Sections:
|
||||||
|
@ -40,14 +44,14 @@ F00 hello.s
|
||||||
|
|
||||||
|
|
||||||
Symbols:
|
Symbols:
|
||||||
_lock EXPR(65558=0x10016) ABS
|
done EXPR(65558=0x10016) UNUSED ABS
|
||||||
_greet EXPR(65560=0x10018) ABS
|
greet_end EXPR(65577=0x10029) ABS
|
||||||
_greet_end EXPR(65573=0x10025) ABS
|
greet EXPR(65564=0x1001c) ABS
|
||||||
_start EXPR(65544=0x10008) ABS
|
start EXPR(65544=0x10008) ABS
|
||||||
_MOVEMBYTES EXPR(0=0x0) INTERNAL
|
_MOVEMBYTES EXPR(0=0x0) INTERNAL
|
||||||
MOVEMSIZE EXPR(0=0x0) INTERNAL
|
MOVEMSIZE EXPR(0=0x0) INTERNAL
|
||||||
_MOVEMREGS EXPR(0=0x0) INTERNAL
|
_MOVEMREGS EXPR(0=0x0) INTERNAL
|
||||||
__LINE__ EXPR(20=0x14) INTERNAL
|
__LINE__ EXPR(22=0x16) INTERNAL
|
||||||
__FO EXPR(0=0x0) INTERNAL
|
__FO EXPR(0=0x0) INTERNAL
|
||||||
__RS EXPR(0=0x0) INTERNAL
|
__RS EXPR(0=0x0) INTERNAL
|
||||||
REPTN EXPR(-1=0xffffffff) INTERNAL
|
REPTN EXPR(-1=0xffffffff) INTERNAL
|
||||||
|
|
Binary file not shown.
|
@ -5,15 +5,17 @@
|
||||||
org $010000
|
org $010000
|
||||||
|
|
||||||
dc.b "PGX", $02
|
dc.b "PGX", $02
|
||||||
dc.l _start
|
dc.l start
|
||||||
|
|
||||||
_start: move.l #_greet_end-_greet+1,d3 ; Length of the message
|
start: move.l #$13,d0 ; sys_chan_write
|
||||||
move.l #_greet,d2 ; Pointer to the message
|
clr.l d1 ; Channel #0
|
||||||
clr.l d1 ; Write to channel #0 (main screen)
|
move.l #greet,d2 ; Pointer to message
|
||||||
move.l #$14,d0 ; sys_chan_write_b
|
move.l #greet_end-greet+1,d3 ; Length of message
|
||||||
trap #15 ; Call it
|
trap #15
|
||||||
|
|
||||||
_lock: bra _lock
|
done: clr.l d0 ; sys_exit
|
||||||
|
clr.l d1 ; Return value = 0
|
||||||
|
trap #15
|
||||||
|
|
||||||
_greet: dc.b "Hello, world!"
|
greet: dc.b "Hello, world!"
|
||||||
_greet_end: dc.b 0
|
greet_end: dc.b 0
|
||||||
|
|
|
@ -21,7 +21,8 @@ export MODEL=4
|
||||||
export AS = vasmm68k_mot
|
export AS = vasmm68k_mot
|
||||||
export ASFLAGS = -quiet -Fvobj -nowarn=62
|
export ASFLAGS = -quiet -Fvobj -nowarn=62
|
||||||
export CC = vc
|
export CC = vc
|
||||||
export CFLAGS = +../vbcc/config/m68k-foenix -I. -Iinclude -DCPU=$(CPU) -DMODEL=$(MODEL)
|
export DEFINES = -DCPU=$(CPU) -DMODEL=$(MODEL) -DKBD_POLLED=1
|
||||||
|
export CFLAGS = +../vbcc/config/m68k-foenix -I. -Iinclude
|
||||||
export RM = cmd /C del /Q /F
|
export RM = cmd /C del /Q /F
|
||||||
|
|
||||||
cpu = m68k
|
cpu = m68k
|
||||||
|
@ -60,7 +61,7 @@ cli:
|
||||||
$(MAKE) --directory=cli
|
$(MAKE) --directory=cli
|
||||||
|
|
||||||
foenixmcp.s68: $(c_obj) $(cpu) dev fatfs snd cli
|
foenixmcp.s68: $(c_obj) $(cpu) dev fatfs snd cli
|
||||||
$(CC) $(CFLAGS) -o foenixmcp.s68 $(c_obj) $(cpu_c_obj) $(dev_c_obj) $(fat_c_obj) $(snd_c_obj) $(cli_c_obj)
|
$(CC) $(CFLAGS) $(DEFINES) -o foenixmcp.s68 $(c_obj) $(cpu_c_obj) $(dev_c_obj) $(fat_c_obj) $(snd_c_obj) $(cli_c_obj)
|
||||||
|
|
||||||
%.o: %.c $(DEPS)
|
%.o: %.c $(DEPS)
|
||||||
$(CC) -S -c -o $@ $< $(CFLAGS)
|
$(CC) -S -c -o $@ $< $(CFLAGS)
|
||||||
|
|
|
@ -7,7 +7,7 @@ cobjects = $(subst .c,.o,$(csources))
|
||||||
all: $(cobjects)
|
all: $(cobjects)
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(CC) -c -o $@ $< $(CFLAGS)
|
$(CC) -c -o $@ $< $(CFLAGS) $(DEFINES)
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
|
|
||||||
|
|
|
@ -27,27 +27,10 @@ typedef struct s_cli_command {
|
||||||
} t_cli_command, *p_cli_command;
|
} t_cli_command, *p_cli_command;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Commands
|
* Variables
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern const t_cli_command g_cli_commands[];
|
short g_current_channel = 0;
|
||||||
|
|
||||||
//
|
|
||||||
// List all the commands
|
|
||||||
//
|
|
||||||
int cmd_help(short channel, int argc, char * argv[]) {
|
|
||||||
p_cli_command command;
|
|
||||||
|
|
||||||
for (command = g_cli_commands; (command != 0) && (command->name != 0); command++) {
|
|
||||||
sys_chan_write(channel, command->help, strlen(command->help));
|
|
||||||
sys_chan_write(channel, "\n", 2);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// CLI variables
|
|
||||||
//
|
|
||||||
|
|
||||||
const t_cli_command g_cli_commands[] = {
|
const t_cli_command g_cli_commands[] = {
|
||||||
{ "?", "? -- print this helpful message", cmd_help },
|
{ "?", "? -- print this helpful message", cmd_help },
|
||||||
|
@ -61,10 +44,24 @@ const t_cli_command g_cli_commands[] = {
|
||||||
{ "POKE8", "POKE8 <address> <value> -- write the byte value to the address in memory", mem_cmd_poke8},
|
{ "POKE8", "POKE8 <address> <value> -- write the byte value to the address in memory", mem_cmd_poke8},
|
||||||
{ "POKE16", "POKE16 <address> <value> -- write the 16-bit word value to the address in memory", mem_cmd_poke16},
|
{ "POKE16", "POKE16 <address> <value> -- write the 16-bit word value to the address in memory", mem_cmd_poke16},
|
||||||
{ "POKE32", "POKE32 <address> <value> -- write the 32-bit long word value to the address in memory", mem_cmd_poke32},
|
{ "POKE32", "POKE32 <address> <value> -- write the 32-bit long word value to the address in memory", mem_cmd_poke32},
|
||||||
|
{ "RUN", "RUN <path> -- execute a binary file", cmd_run },
|
||||||
{ "TYPE", "TYPE <path> -- print the contents of a text file", cmd_type },
|
{ "TYPE", "TYPE <path> -- print the contents of a text file", cmd_type },
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// List all the commands
|
||||||
|
//
|
||||||
|
int cmd_help(short channel, int argc, char * argv[]) {
|
||||||
|
p_cli_command command;
|
||||||
|
|
||||||
|
for (command = g_cli_commands; (command != 0) && (command->name != 0); command++) {
|
||||||
|
sys_chan_write(channel, command->help, strlen(command->help));
|
||||||
|
sys_chan_write(channel, "\n", 2);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Attempt to execute a command
|
// Attempt to execute a command
|
||||||
//
|
//
|
||||||
|
@ -126,6 +123,12 @@ char * strtok_r(char * source, const char * delimiter, char ** saveptr) {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
short cli_rerepl() {
|
||||||
|
while (1) {
|
||||||
|
cli_repl(g_current_channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Enter the CLI's read-eval-print loop
|
// Enter the CLI's read-eval-print loop
|
||||||
//
|
//
|
||||||
|
@ -137,8 +140,7 @@ short cli_repl(short channel) {
|
||||||
int argc = 0;
|
int argc = 0;
|
||||||
char * argv[MAX_ARGC];
|
char * argv[MAX_ARGC];
|
||||||
|
|
||||||
const char * welcome = "\n\nFoenix/MCP Command Line Utility... online.\nType \"HELP\" or \"?\" for help.\n\n";
|
g_current_channel = channel;
|
||||||
sys_chan_write(channel, welcome, strlen(welcome));
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
sys_chan_write(channel, "\n> ", 3); // Print our prompt
|
sys_chan_write(channel, "\n> ", 3); // Print our prompt
|
||||||
|
|
|
@ -39,4 +39,9 @@ extern short cli_repl(short channel);
|
||||||
*/
|
*/
|
||||||
extern long cli_eval_number(const char * arg);
|
extern long cli_eval_number(const char * arg);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print a help message
|
||||||
|
*/
|
||||||
|
extern int cmd_help(short channel, int argc, char * argv[]);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5,11 +5,24 @@
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "simpleio.h"
|
#include "simpleio.h"
|
||||||
#include "cli.h"
|
#include "cli.h"
|
||||||
|
#include "proc.h"
|
||||||
#include "cli/dos_cmds.h"
|
#include "cli/dos_cmds.h"
|
||||||
#include "dev/block.h"
|
#include "dev/block.h"
|
||||||
#include "dev/fsys.h"
|
#include "dev/fsys.h"
|
||||||
#include "fatfs/ff.h"
|
#include "fatfs/ff.h"
|
||||||
|
|
||||||
|
short cmd_run(short screen, int argc, char * argv[]) {
|
||||||
|
TRACE("cmd_run");
|
||||||
|
|
||||||
|
if (argc > 1) {
|
||||||
|
short result = proc_run(argv[1]);
|
||||||
|
if (result < 0) {
|
||||||
|
log_num(LOG_ERROR, "Unable to run: ", result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
short cmd_dir(short screen, int argc, char * argv[]) {
|
short cmd_dir(short screen, int argc, char * argv[]) {
|
||||||
t_file_info my_file;
|
t_file_info my_file;
|
||||||
char * path = "";
|
char * path = "";
|
||||||
|
|
|
@ -5,6 +5,11 @@
|
||||||
#ifndef __DOS_CMDS_H
|
#ifndef __DOS_CMDS_H
|
||||||
#define __DOS_CMDS_H
|
#define __DOS_CMDS_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Execute a binary file
|
||||||
|
*/
|
||||||
|
extern short cmd_run(short screen, int argc, char * argv[]);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* List the directory at the given path
|
* List the directory at the given path
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -7,7 +7,7 @@ cobjects = $(subst .c,.o,$(csources))
|
||||||
all: $(cobjects)
|
all: $(cobjects)
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(CC) -c -o $@ $< $(CFLAGS)
|
$(CC) -c -o $@ $< $(CFLAGS) $(DEFINES)
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
|
|
||||||
|
|
|
@ -278,6 +278,8 @@ short chan_write_b(short channel, uint8_t b) {
|
||||||
p_dev_chan cdev;
|
p_dev_chan cdev;
|
||||||
short res;
|
short res;
|
||||||
|
|
||||||
|
TRACE("chan_write_b");
|
||||||
|
|
||||||
res = chan_get_records(channel, &chan, &cdev);
|
res = chan_get_records(channel, &chan, &cdev);
|
||||||
if (res == 0) {
|
if (res == 0) {
|
||||||
return cdev->write_b(chan, b);
|
return cdev->write_b(chan, b);
|
||||||
|
|
|
@ -35,7 +35,11 @@ short con_write_b(p_channel chan, uint8_t b) {
|
||||||
short con_read_b(p_channel chan) {
|
short con_read_b(p_channel chan) {
|
||||||
char c;
|
char c;
|
||||||
do {
|
do {
|
||||||
|
#ifdef KBD_POLLED
|
||||||
|
c = kbdmo_getc_poll();
|
||||||
|
#else
|
||||||
c = kbdmo_getc();
|
c = kbdmo_getc();
|
||||||
|
#endif
|
||||||
} while (c == 0);
|
} while (c == 0);
|
||||||
|
|
||||||
// Echo the character to the screen
|
// Echo the character to the screen
|
||||||
|
|
|
@ -221,7 +221,9 @@ short kbdmo_init() {
|
||||||
int_register(INT_KBD_A2560K, kbdmo_handle_irq);
|
int_register(INT_KBD_A2560K, kbdmo_handle_irq);
|
||||||
|
|
||||||
/* Enable the interrupt for the keyboard */
|
/* Enable the interrupt for the keyboard */
|
||||||
|
#ifndef KBD_POLLED
|
||||||
int_enable(INT_KBD_A2560K);
|
int_enable(INT_KBD_A2560K);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ cobjects = $(subst .c,.o,$(csources))
|
||||||
all: $(cobjects)
|
all: $(cobjects)
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(CC) -c -o $@ $< $(CFLAGS)
|
$(CC) -c -o $@ $< $(CFLAGS) $(DEFINES)
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,7 @@ void initialize() {
|
||||||
text_init(); // Initialize the text channels
|
text_init(); // Initialize the text channels
|
||||||
DEBUG("Foenix/MCP starting up...");
|
DEBUG("Foenix/MCP starting up...");
|
||||||
|
|
||||||
log_setlevel(LOG_VERBOSE);
|
log_setlevel(LOG_ERROR);
|
||||||
|
|
||||||
/* Initialize the interrupt system */
|
/* Initialize the interrupt system */
|
||||||
int_init();
|
int_init();
|
||||||
|
@ -174,50 +174,6 @@ void initialize() {
|
||||||
int_enable_all();
|
int_enable_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
// void try_mo_scancodes(short screen) {
|
|
||||||
// // volatile unsigned short * kbd_mo_data = ((volatile unsigned short *)0x00C00040);
|
|
||||||
// // volatile unsigned short * kbd_mo_stat = ((volatile unsigned short *)0x00C00042);
|
|
||||||
//
|
|
||||||
// print(screen, "mo> ");
|
|
||||||
//
|
|
||||||
// do {
|
|
||||||
// // unsigned short status = *kbd_mo_stat;
|
|
||||||
// // if ((status & KBD_MO_STAT_EMPTY) != KBD_MO_STAT_EMPTY) {
|
|
||||||
// // unsigned short data = *kbd_mo_data;
|
|
||||||
// // print(screen, "[");
|
|
||||||
// // print_hex_16(screen, status);
|
|
||||||
// // print(screen, "]: {");
|
|
||||||
// //
|
|
||||||
// // print_hex_16(screen, data);
|
|
||||||
// // print(screen, "}\n ");
|
|
||||||
// // // }
|
|
||||||
// // }
|
|
||||||
//
|
|
||||||
// unsigned short scancode = kbdmo_get_scancode_poll();
|
|
||||||
// if (scancode != 0) {
|
|
||||||
// print(screen, "[");
|
|
||||||
// print_hex_16(screen, scancode);
|
|
||||||
// print(screen, "]\n");
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// } while (1);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// void try_mo_chars(short screen) {
|
|
||||||
// char buffer[2];
|
|
||||||
// buffer[1] = 0;
|
|
||||||
//
|
|
||||||
// print(screen, "mo> ");
|
|
||||||
//
|
|
||||||
// while (1) {
|
|
||||||
// unsigned char c = kbdmo_getc_poll();
|
|
||||||
// if (c) {
|
|
||||||
// // text_put_raw(screen, c);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
void uart_send(short uart, char * message) {
|
void uart_send(short uart, char * message) {
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
|
@ -380,14 +336,6 @@ int main(int argc, char * argv[]) {
|
||||||
print(CDEV_CONSOLE, "Text Channel A\n");
|
print(CDEV_CONSOLE, "Text Channel A\n");
|
||||||
print(CDEV_EVID, "Text Channel B\n");
|
print(CDEV_EVID, "Text Channel B\n");
|
||||||
|
|
||||||
print(CDEV_CONSOLE, "MASK_GRP1: ");
|
|
||||||
print_hex_16(CDEV_CONSOLE, *MASK_GRP1);
|
|
||||||
print(CDEV_CONSOLE, "\n");
|
|
||||||
|
|
||||||
print(CDEV_CONSOLE, "MASK_PEND1: ");
|
|
||||||
print_hex_16(CDEV_CONSOLE, *PENDING_GRP1);
|
|
||||||
print(CDEV_CONSOLE, "\n");
|
|
||||||
|
|
||||||
// uart_test_send(0);
|
// uart_test_send(0);
|
||||||
|
|
||||||
/* Register a handler for the SOF interrupt and enable it */
|
/* Register a handler for the SOF interrupt and enable it */
|
||||||
|
@ -413,6 +361,9 @@ int main(int argc, char * argv[]) {
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
const char * welcome = "\n\nFoenix/MCP Command Line Utility... online.\nType \"HELP\" or \"?\" for help.\n\n";
|
||||||
|
sys_chan_write(0, welcome, strlen(welcome));
|
||||||
cli_repl(0);
|
cli_repl(0);
|
||||||
|
|
||||||
DEBUG("Stopping.");
|
DEBUG("Stopping.");
|
||||||
|
|
3623
src/foenixmcp.s68
3623
src/foenixmcp.s68
File diff suppressed because it is too large
Load diff
|
@ -5,7 +5,7 @@
|
||||||
#ifndef __ERRORS_H
|
#ifndef __ERRORS_H
|
||||||
#define __ERRORS_H
|
#define __ERRORS_H
|
||||||
|
|
||||||
#define MAX_ERROR_NUMBER 15 // Largest (absolute value) of the error number
|
#define MAX_ERROR_NUMBER 16 // Largest (absolute value) of the error number
|
||||||
|
|
||||||
#define ERR_GENERAL -1 // A general error condition
|
#define ERR_GENERAL -1 // A general error condition
|
||||||
#define DEV_ERR_BADDEV -2 // Device number is bad (too big or no device assigned)
|
#define DEV_ERR_BADDEV -2 // Device number is bad (too big or no device assigned)
|
||||||
|
@ -22,5 +22,5 @@
|
||||||
#define ERR_BAD_EXTENSION -13 // The path to load did not have an extension that matched registered loaders
|
#define ERR_BAD_EXTENSION -13 // The path to load did not have an extension that matched registered loaders
|
||||||
#define ERR_OUT_OF_MEMORY -14 // Unable to allocate more memory
|
#define ERR_OUT_OF_MEMORY -14 // Unable to allocate more memory
|
||||||
#define ERR_BAD_BINARY -15 // Bad binary file format... i.e. binary format does not match expectations
|
#define ERR_BAD_BINARY -15 // Bad binary file format... i.e. binary format does not match expectations
|
||||||
|
#define ERR_NOT_EXECUTABLE -16 // Binary file format does not have a starting address
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -53,7 +53,7 @@
|
||||||
//
|
//
|
||||||
// #elif SYSTEM == SYS_FOENIX_A2560K
|
// #elif SYSTEM == SYS_FOENIX_A2560K
|
||||||
#define PS2_STATUS ((unsigned char *)0x00C02064)
|
#define PS2_STATUS ((unsigned char *)0x00C02064)
|
||||||
#define PS2_CMD_BUF ((unsigned char *)0x00C02060)
|
#define PS2_CMD_BUF ((unsigned char *)0x00C02064)
|
||||||
#define PS2_OUT_BUF ((unsigned char *)0x00C02060)
|
#define PS2_OUT_BUF ((unsigned char *)0x00C02060)
|
||||||
#define PS2_INPT_BUF ((unsigned char *)0x00C02060)
|
#define PS2_INPT_BUF ((unsigned char *)0x00C02060)
|
||||||
#define PS2_DATA_BUF ((unsigned char *)0x00C02060)
|
#define PS2_DATA_BUF ((unsigned char *)0x00C02060)
|
||||||
|
|
|
@ -89,6 +89,18 @@ extern int32_t syscall(int32_t function, ...);
|
||||||
*** Core system calls
|
*** Core system calls
|
||||||
***/
|
***/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Quit the current user process
|
||||||
|
*
|
||||||
|
* NOTE: at the moment, this relaunches the CLI. In the future, this
|
||||||
|
* may cause execution to return to the program that started
|
||||||
|
* the user process.
|
||||||
|
*
|
||||||
|
* Inputs:
|
||||||
|
* result = the code to return to the kernel
|
||||||
|
*/
|
||||||
|
extern void sys_exit(int result);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enable all interrupts
|
* Enable all interrupts
|
||||||
*
|
*
|
||||||
|
|
|
@ -85,7 +85,7 @@ void log3(short level, char * message1, char * message2, char * message3) {
|
||||||
void log_num(short level, char * message, int n) {
|
void log_num(short level, char * message, int n) {
|
||||||
if (level <= log_level) {
|
if (level <= log_level) {
|
||||||
print(log_channel, message);
|
print(log_channel, message);
|
||||||
print_hex_16(log_channel, n);
|
print_hex_32(log_channel, n);
|
||||||
print_c(log_channel, '\n');
|
print_c(log_channel, '\n');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ all: $(aobjects) $(cobjects)
|
||||||
$(AS) $(ASFLAGS) -o $@ $<
|
$(AS) $(ASFLAGS) -o $@ $<
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(CC) -c -o $@ $< $(CFLAGS)
|
$(CC) -c -o $@ $< $(CFLAGS) $(DEFINES)
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ int32_t syscall_dispatch(int32_t function, int32_t param0, int32_t param1, int32
|
||||||
/* Core System Calls */
|
/* Core System Calls */
|
||||||
switch (function) {
|
switch (function) {
|
||||||
case KFN_EXIT:
|
case KFN_EXIT:
|
||||||
|
proc_exit((int)param0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KFN_WARMBOOT:
|
case KFN_WARMBOOT:
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
xref ___main
|
xref ___main
|
||||||
|
xref _cli_rerepl
|
||||||
|
|
||||||
xdef _syscall
|
xdef _syscall
|
||||||
xdef ___exit
|
xdef ___exit
|
||||||
xdef _int_enable_all
|
xdef _int_enable_all
|
||||||
xdef _int_disable_all
|
xdef _int_disable_all
|
||||||
|
xdef _call_user
|
||||||
|
xdef _restart_cli
|
||||||
|
|
||||||
section "vectors",code
|
section "vectors",code
|
||||||
|
|
||||||
|
@ -240,3 +244,22 @@ h_trap_15:
|
||||||
add.l #28,sp ; Remove parameters from the stack
|
add.l #28,sp ; Remove parameters from the stack
|
||||||
|
|
||||||
rte ; Return to the caller
|
rte ; Return to the caller
|
||||||
|
|
||||||
|
;
|
||||||
|
; Jump into a user mode code
|
||||||
|
;
|
||||||
|
; Inputs:
|
||||||
|
; a0 = pointer to code to execute
|
||||||
|
; a1 = location to set user stack pointer
|
||||||
|
;
|
||||||
|
_call_user:
|
||||||
|
move.l (4,a7),a0
|
||||||
|
move.l (8,a7),a1
|
||||||
|
andi #$dfff,sr ; Drop into user mode
|
||||||
|
movea.l a1,a7 ; Set the stack
|
||||||
|
jmp (a0)
|
||||||
|
|
||||||
|
_restart_cli:
|
||||||
|
lea ___STACK,sp
|
||||||
|
jsr _cli_rerepl
|
||||||
|
bra _restart_cli
|
||||||
|
|
8682
src/mapfile
8682
src/mapfile
File diff suppressed because it is too large
Load diff
91
src/proc.c
Normal file
91
src/proc.c
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* Routines to support processes
|
||||||
|
*
|
||||||
|
* NOTE: at the moment, FoenixMCP is single tasking only, so there is only
|
||||||
|
* one "process" besides the kernel.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "errors.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "dev/fsys.h"
|
||||||
|
|
||||||
|
static const long k_default_stack = 0x0000ffff; /* For now... we're just going to put the user stack under 0x00010000 */
|
||||||
|
static int g_proc_result;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Assembly routine: reset the supervisor stack pointer and restart the CLI
|
||||||
|
*/
|
||||||
|
extern void restart_cli();
|
||||||
|
|
||||||
|
extern void call_user(long start, long stack);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start a user mode process
|
||||||
|
*
|
||||||
|
* Inputs:
|
||||||
|
* start = the address to start execution
|
||||||
|
* stack = the location to start the user mode stack
|
||||||
|
*/
|
||||||
|
void proc_exec(long start, long stack) {
|
||||||
|
TRACE("proc_exec");
|
||||||
|
|
||||||
|
log_num(LOG_INFO, "proc_exec start: ", start);
|
||||||
|
log_num(LOG_INFO, "proc_exec stack: ", stack);
|
||||||
|
|
||||||
|
g_proc_result = 0;
|
||||||
|
call_user(start, stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Quit the current user process
|
||||||
|
*
|
||||||
|
* NOTE: at the moment, this relaunches the CLI. In the future, this
|
||||||
|
* may cause execution to return to the program that started
|
||||||
|
* the user process.
|
||||||
|
*
|
||||||
|
* Inputs:
|
||||||
|
*/
|
||||||
|
void proc_exit(int result) {
|
||||||
|
g_proc_result = result;
|
||||||
|
restart_cli();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the result code of the previously running user process
|
||||||
|
*/
|
||||||
|
int proc_get_result() {
|
||||||
|
return g_proc_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find an executable binary matching the path, load it, and execute it
|
||||||
|
*
|
||||||
|
* Inputs:
|
||||||
|
* path = the path to try to load
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* returns an error code on failure, will not return on success
|
||||||
|
*/
|
||||||
|
short proc_run(const char * path) {
|
||||||
|
|
||||||
|
TRACE("proc_run");
|
||||||
|
|
||||||
|
/* TODO: allow for commands without extensions */
|
||||||
|
/* TODO: allow for a search PATH */
|
||||||
|
/* TODO: allocate stack more dynamically */
|
||||||
|
|
||||||
|
long start = 0;
|
||||||
|
short result = fsys_load(path, 0, &start);
|
||||||
|
if (result == 0) {
|
||||||
|
if (start != 0) {
|
||||||
|
proc_exec(start, k_default_stack);
|
||||||
|
} else {
|
||||||
|
log_num(LOG_ERROR, "Couldn't execute file: ", result);
|
||||||
|
return ERR_NOT_EXECUTABLE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log_num(LOG_ERROR, "Couldn't load file: ", result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
48
src/proc.h
Normal file
48
src/proc.h
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Routines to support processes
|
||||||
|
*
|
||||||
|
* NOTE: at the moment, FoenixMCP is single tasking only, so there is only
|
||||||
|
* one "process" besides the kernel.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PROC_H
|
||||||
|
#define __PROC_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start a user mode process
|
||||||
|
*
|
||||||
|
* Inputs:
|
||||||
|
* start = the address to start execution
|
||||||
|
* stack = the location to start the user mode stack
|
||||||
|
*/
|
||||||
|
extern void proc_exec(long start, long stack);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Quit the current user process
|
||||||
|
*
|
||||||
|
* NOTE: at the moment, this relaunches the CLI. In the future, this
|
||||||
|
* may cause execution to return to the program that started
|
||||||
|
* the user process.
|
||||||
|
*
|
||||||
|
* Inputs:
|
||||||
|
*/
|
||||||
|
extern void proc_exit(int result);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the result code of the previously running user process
|
||||||
|
*/
|
||||||
|
extern int proc_get_result();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find an executable binary matching the path, load it, and execute it
|
||||||
|
*
|
||||||
|
* Inputs:
|
||||||
|
* path = the path to try to load
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* returns an error code on failure, will not return on success
|
||||||
|
*/
|
||||||
|
extern short proc_run(const char * path);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue