Merge branch 'main' into a2560k
This commit is contained in:
commit
6b8e2204f6
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,6 +1,9 @@
|
||||||
# Prerequisites
|
# Prerequisites
|
||||||
*.d
|
*.d
|
||||||
|
|
||||||
|
# Python cache
|
||||||
|
C256Mgr/__pycache__/
|
||||||
|
|
||||||
# Object files
|
# Object files
|
||||||
*.o
|
*.o
|
||||||
*.ko
|
*.ko
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
1. [ ] Memory management
|
1. [ ] Memory management
|
||||||
1. [x] PGX file loader
|
1. [x] PGX file loader
|
||||||
1. [x] PGZ file loader
|
1. [x] PGZ file loader
|
||||||
1. [ ] ELF file loader
|
1. [x] ELF file loader
|
||||||
1. [x] Command Line Interface
|
1. [x] Command Line Interface
|
||||||
1. [ ] Mouse driver
|
1. [ ] Mouse driver
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
1. [ ] Auto-run/configuration file
|
1. [ ] Auto-run/configuration file
|
||||||
1. Built-in commands:
|
1. Built-in commands:
|
||||||
1. [x] DIR [path]
|
1. [x] DIR [path]
|
||||||
1. [ ] COPY [path] TO [path]
|
1. [x] COPY [path] TO [path]
|
||||||
1. [ ] RENAME [path] TO [path]
|
1. [ ] RENAME [path] TO [path]
|
||||||
1. [x] DELETE [path]
|
1. [x] DELETE [path]
|
||||||
1. [x] CD [path]
|
1. [x] CD [path]
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -31,7 +31,8 @@ ifeq ($(OS),Windows_NT)
|
||||||
# export CFLAGS = +$(VBCC)/config/a2560u_flash -I. -I$(CURDIR)/include -I$(CURDIR)
|
# export CFLAGS = +$(VBCC)/config/a2560u_flash -I. -I$(CURDIR)/include -I$(CURDIR)
|
||||||
export RM = cmd /C del /Q /F
|
export RM = cmd /C del /Q /F
|
||||||
else
|
else
|
||||||
export CFLAGS = +$(VBCC)/config/m68k-foenix-linux -I. -I$(CURDIR)/include -I$(CURDIR)
|
#export CFLAGS = +$(VBCC)/config/m68k-foenix-linux -I. -I$(CURDIR)/include -I$(CURDIR)
|
||||||
|
export CFLAGS = +$(VBCC)/config/a2560u_flash-linux -I. -I$(CURDIR)/include -I$(CURDIR)
|
||||||
export RM = rm -f
|
export RM = rm -f
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,8 @@ const t_cli_command g_cli_commands[] = {
|
||||||
{ "HELP", "HELP : print this helpful message", cmd_help },
|
{ "HELP", "HELP : print this helpful message", cmd_help },
|
||||||
{ "CD", "CD <path> : sets the current directory", cmd_cd },
|
{ "CD", "CD <path> : sets the current directory", cmd_cd },
|
||||||
{ "CLS", "CLS : clear the screen", cmd_cls },
|
{ "CLS", "CLS : clear the screen", cmd_cls },
|
||||||
|
{ "COPY", "COPY <src path> <dst path> : Copies files to destination", cmd_copy },
|
||||||
|
{ "DASM", "DASM <addr> [<count>] : print a memory disassembly", mem_cmd_dasm },
|
||||||
{ "DEL", "DEL <path> : delete a file or directory", cmd_del },
|
{ "DEL", "DEL <path> : delete a file or directory", cmd_del },
|
||||||
{ "DIR", "DIR <path> : print directory listing", cmd_dir },
|
{ "DIR", "DIR <path> : print directory listing", cmd_dir },
|
||||||
{ "DISKFILL", "DISKFILL <drive #> <sector #> <byte value>", cmd_diskfill },
|
{ "DISKFILL", "DISKFILL <drive #> <sector #> <byte value>", cmd_diskfill },
|
||||||
|
@ -258,6 +260,7 @@ short cli_rerepl() {
|
||||||
//
|
//
|
||||||
short cli_repl(short channel) {
|
short cli_repl(short channel) {
|
||||||
char command_line[MAX_COMMAND_SIZE];
|
char command_line[MAX_COMMAND_SIZE];
|
||||||
|
char cwd_buffer[MAX_PATH_LEN];
|
||||||
char * arg;
|
char * arg;
|
||||||
char * token_save;
|
char * token_save;
|
||||||
char * delim = " ";
|
char * delim = " ";
|
||||||
|
@ -267,7 +270,11 @@ short cli_repl(short channel) {
|
||||||
g_current_channel = channel;
|
g_current_channel = channel;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
sys_chan_write(channel, "\n> ", 3); // Print our prompt
|
sys_chan_write(channel, "\n", 1);
|
||||||
|
if(sys_fsys_get_cwd(cwd_buffer, MAX_PATH_LEN) == 0) {
|
||||||
|
sys_chan_write(channel, cwd_buffer, strlen(cwd_buffer));
|
||||||
|
}
|
||||||
|
sys_chan_write(channel, "> ", 2); // Print our prompt
|
||||||
sys_chan_readline(channel, command_line, MAX_COMMAND_SIZE); // Attempt to read line
|
sys_chan_readline(channel, command_line, MAX_COMMAND_SIZE); // Attempt to read line
|
||||||
sys_chan_write(channel, "\n", 1);
|
sys_chan_write(channel, "\n", 1);
|
||||||
|
|
||||||
|
|
1104
src/cli/dis68k.c
Normal file
1104
src/cli/dis68k.c
Normal file
File diff suppressed because it is too large
Load diff
6
src/cli/dis68k.h
Normal file
6
src/cli/dis68k.h
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#ifndef __MCP_DIS68K_H
|
||||||
|
#define __MCP_DIS68K_H
|
||||||
|
|
||||||
|
void disasm(unsigned long int start, unsigned long int end);
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,5 +1,6 @@
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "syscalls.h"
|
#include "syscalls.h"
|
||||||
|
@ -142,6 +143,88 @@ short cmd_del(short screen, int argc, char * argv[]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
short cmd_copy(short screen, int argc, char * argv[]) {
|
||||||
|
FRESULT find_result;
|
||||||
|
FRESULT result;
|
||||||
|
DIR dir; /* Directory object */
|
||||||
|
FILINFO src_info; /* File information */
|
||||||
|
FILINFO dst_info;
|
||||||
|
FIL src_file;
|
||||||
|
FIL dst_file;
|
||||||
|
|
||||||
|
BYTE buffer[4096]; /* File copy buffer */
|
||||||
|
UINT br, bw; /* File read/write count */
|
||||||
|
|
||||||
|
char path[MAX_PATH_LEN];
|
||||||
|
|
||||||
|
bool is_directory = false;
|
||||||
|
bool is_append_file = false;
|
||||||
|
|
||||||
|
TRACE("cmd_copy");
|
||||||
|
|
||||||
|
if (argc > 2) {
|
||||||
|
strcpy(path, argv[2]);
|
||||||
|
|
||||||
|
result = f_stat(argv[2], &dst_info);
|
||||||
|
if (result == FR_OK) {
|
||||||
|
is_directory = dst_info.fattrib & AM_DIR;
|
||||||
|
} else if (result == FR_NO_FILE) {
|
||||||
|
is_directory = false;
|
||||||
|
} else {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
find_result = f_findfirst(&dir, &src_info, "", argv[1]);
|
||||||
|
|
||||||
|
while (find_result == FR_OK && src_info.fname[0]) {
|
||||||
|
if (strcmp(src_info.fname, path) == 0) goto skip; // Skip copying file to self.
|
||||||
|
|
||||||
|
result = f_open(&src_file, src_info.fname, FA_READ);
|
||||||
|
if (result != FR_OK) goto error;
|
||||||
|
|
||||||
|
if (is_directory) {
|
||||||
|
sprintf(path, "%s/%s", dst_info.fname, src_info.fname);
|
||||||
|
result = f_open(&dst_file, path, FA_WRITE | FA_CREATE_ALWAYS);
|
||||||
|
} else if (is_append_file) {
|
||||||
|
result = f_open(&dst_file, path, FA_WRITE | FA_OPEN_APPEND);
|
||||||
|
} else {
|
||||||
|
result = f_open(&dst_file, path, FA_WRITE | FA_CREATE_ALWAYS);
|
||||||
|
}
|
||||||
|
if (result != FR_OK) goto error;
|
||||||
|
|
||||||
|
print(screen, (is_append_file) ? "Appending " : "Copying ");
|
||||||
|
print(screen, src_info.fname);
|
||||||
|
print(screen, " to ");
|
||||||
|
print(screen, path);
|
||||||
|
print(screen, "\n");
|
||||||
|
|
||||||
|
/* Copy source to destination */
|
||||||
|
for (;;) {
|
||||||
|
result = f_read(&src_file, buffer, sizeof buffer, &br); /* Read a chunk of data from the source file */
|
||||||
|
if (br == 0) break; /* error or eof */
|
||||||
|
result = f_write(&dst_file, buffer, br, &bw); /* Write it to the destination file */
|
||||||
|
if (bw < br) break; /* error or disk full */
|
||||||
|
}
|
||||||
|
|
||||||
|
f_close(&src_file);
|
||||||
|
f_close(&dst_file);
|
||||||
|
|
||||||
|
skip:
|
||||||
|
find_result = f_findnext(&dir, &src_info);
|
||||||
|
is_append_file = true; // If copying more than one file to a file, then open for append.
|
||||||
|
}
|
||||||
|
f_closedir(&dir);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
err_print(screen, "Unable to copy file(s)", result);
|
||||||
|
f_close(&src_file);
|
||||||
|
f_close(&dst_file);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Change the directory
|
* Change the directory
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -25,6 +25,11 @@ extern short cmd_mkdir(short screen, int argc, char * argv[]);
|
||||||
*/
|
*/
|
||||||
extern short cmd_del(short screen, int argc, char * argv[]);
|
extern short cmd_del(short screen, int argc, char * argv[]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copies file(s) to destination
|
||||||
|
*/
|
||||||
|
extern short cmd_copy(short screen, int argc, char * argv[]);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the current working directory
|
* Set the current working directory
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -38,6 +38,36 @@ short mem_cmd_dump(short channel, int argc, char * argv[]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
short mem_cmd_dasm(short channel, int argc, char * argv[]) {
|
||||||
|
unsigned long address = 0;
|
||||||
|
long count = 1000;
|
||||||
|
long i;
|
||||||
|
|
||||||
|
TRACE("mem_cmd_dasm");
|
||||||
|
|
||||||
|
#if defined(__m68k__) || defined(__M68K__)
|
||||||
|
if (argc >= 2) {
|
||||||
|
address = cli_eval_number(argv[1]);
|
||||||
|
|
||||||
|
if (argc > 2) {
|
||||||
|
count = cli_eval_number(argv[2]);
|
||||||
|
}
|
||||||
|
print(0, "=================\n");
|
||||||
|
disasm(address, address + count);
|
||||||
|
print(0, "=================\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
log(LOG_ERROR, "USAGE: DASM <address> <count>");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
log(LOG_ERROR, "DASM only available on m68k machines");
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write an 8-bit byte to memory
|
* Write an 8-bit byte to memory
|
||||||
*
|
*
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#ifndef __MEM_CMDS_H
|
#ifndef __MEM_CMDS_H
|
||||||
#define __MEM_CMDS_H
|
#define __MEM_CMDS_H
|
||||||
|
|
||||||
|
#include "dis68k.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print out the contents of a block of memory
|
* Print out the contents of a block of memory
|
||||||
*
|
*
|
||||||
|
@ -12,6 +14,13 @@
|
||||||
*/
|
*/
|
||||||
extern short mem_cmd_dump(short channel, int argc, char * argv[]);
|
extern short mem_cmd_dump(short channel, int argc, char * argv[]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print out the dissassembly of a block of memory
|
||||||
|
*
|
||||||
|
* DASM <address> [<count>]
|
||||||
|
*/
|
||||||
|
extern short mem_cmd_dasm(short channel, int argc, char * argv[]);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write an 8-bit byte to memory
|
* Write an 8-bit byte to memory
|
||||||
*
|
*
|
||||||
|
|
|
@ -417,17 +417,18 @@ short chan_flush(short channel) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
/*
|
||||||
// Attempt to set the position of the channel cursor (if supported)
|
* Attempt to set the position of the channel cursor (if supported)
|
||||||
//
|
*
|
||||||
// Inputs:
|
* Inputs:
|
||||||
// channel = the number of the channel
|
* channel = the number of the channel
|
||||||
// position = the position of the cursor
|
* position = the position of the cursor
|
||||||
// base = whether the position is absolute or relative to the current position
|
* base = whether the position is from the beginning of the channel, relative to the current position,
|
||||||
//
|
* or relative to the end of the channel
|
||||||
// Returns:
|
*
|
||||||
// 0 = success, a negative number is an error.
|
* Returns:
|
||||||
//
|
* 0 = success, a negative number is an error.
|
||||||
|
*/
|
||||||
short chan_seek(short channel, long position, short base) {
|
short chan_seek(short channel, long position, short base) {
|
||||||
p_channel chan;
|
p_channel chan;
|
||||||
p_dev_chan cdev;
|
p_dev_chan cdev;
|
||||||
|
|
|
@ -36,8 +36,9 @@
|
||||||
#define CDEV_STAT_READABLE 0x04 // The channel has data to read (read will not block)
|
#define CDEV_STAT_READABLE 0x04 // The channel has data to read (read will not block)
|
||||||
#define CDEV_STAT_WRITABLE 0x08 // The channel can accept data (write will not block)
|
#define CDEV_STAT_WRITABLE 0x08 // The channel can accept data (write will not block)
|
||||||
|
|
||||||
#define CDEV_SEEK_ABSOLUTE 0
|
#define CDEV_SEEK_START 0 /* Seek from the start of the file */
|
||||||
#define CDEV_SEEK_RELATIVE 1
|
#define CDEV_SEEK_RELATIVE 1 /* Seek from the current position */
|
||||||
|
#define CDEV_SEEK_END 2 /* Seek from teh end of the file */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Structure defining a channel
|
* Structure defining a channel
|
||||||
|
@ -242,7 +243,8 @@ extern short chan_flush(short channel);
|
||||||
* Inputs:
|
* Inputs:
|
||||||
* channel = the number of the channel
|
* channel = the number of the channel
|
||||||
* position = the position of the cursor
|
* position = the position of the cursor
|
||||||
* base = whether the position is absolute or relative to the current position
|
* base = whether the position is from the beginning of the channel, relative to the current position,
|
||||||
|
* or relative to the end of the channel
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
* 0 = success, a negative number is an error.
|
* 0 = success, a negative number is an error.
|
||||||
|
|
86
src/dev/elf.h
Normal file
86
src/dev/elf.h
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
#ifndef _ELF_H
|
||||||
|
#define _ELF_H
|
||||||
|
|
||||||
|
#define ET_NONE 0 // No file type
|
||||||
|
#define ET_REL 1 // Relocatable file
|
||||||
|
#define ET_EXEC 2 // Executable file
|
||||||
|
#define ET_DYN 3 // Shared object file
|
||||||
|
#define ET_CORE 4 // Core file
|
||||||
|
#define ET_NUM 5 // Number of defined types
|
||||||
|
#define EM_NONE 0 // No machine
|
||||||
|
#define EM_386 3 // Intel 80386
|
||||||
|
#define EM_68K 4 // Motorola m68k family
|
||||||
|
#define EM_MIPS 8 // MIPS R3000 big-endian
|
||||||
|
#define EM_MIPS_LE 10 // MIPS R3000 little-endian
|
||||||
|
#define EM_PPC 20 // PowerPC
|
||||||
|
#define EM_PPC64 21 // PowerPC 64-bit
|
||||||
|
#define EM_ARM 40 // ARM
|
||||||
|
|
||||||
|
#if defined(__powerpc__)
|
||||||
|
#define CPU_ARCH EM_PPC
|
||||||
|
#elif defined(__powerpc64__)
|
||||||
|
#define CPU_ARCH EM_PPC64
|
||||||
|
#elif defined(__arm__)
|
||||||
|
#define CPU_ARCH EM_ARM
|
||||||
|
#elif defined(__m68k__) || defined(__M68K__)
|
||||||
|
#define CPU_ARCH EM_68K
|
||||||
|
#else
|
||||||
|
#define CPU_ARCH EM_NONE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PT_NULL = 0,
|
||||||
|
PT_LOAD,
|
||||||
|
PT_DYNAMIC,
|
||||||
|
PT_INTERP,
|
||||||
|
PT_NOTE,
|
||||||
|
PT_SHLIB,
|
||||||
|
PT_PHDR,
|
||||||
|
PT_TLS
|
||||||
|
} progtype_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
HDATA_NONE = 0,
|
||||||
|
HDATA_LITTLE,
|
||||||
|
HDATA_BIG
|
||||||
|
} endianness_t;
|
||||||
|
|
||||||
|
struct ident_t {
|
||||||
|
unsigned char magic[4];
|
||||||
|
unsigned char class;
|
||||||
|
unsigned char data;
|
||||||
|
unsigned char version;
|
||||||
|
unsigned char osabi;
|
||||||
|
unsigned char abiversion;
|
||||||
|
unsigned char padding[7];
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct ident_t ident;
|
||||||
|
unsigned short type;
|
||||||
|
unsigned short machine;
|
||||||
|
unsigned long version;
|
||||||
|
unsigned long entry;
|
||||||
|
unsigned long progOffset;
|
||||||
|
unsigned long shoff;
|
||||||
|
unsigned long flags;
|
||||||
|
unsigned short ehsize;
|
||||||
|
unsigned short progSize;
|
||||||
|
unsigned short progNum;
|
||||||
|
unsigned short shentsize;
|
||||||
|
unsigned short shnum;
|
||||||
|
unsigned short shtrndx;
|
||||||
|
} elf32_header;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned long type;
|
||||||
|
unsigned long offset;
|
||||||
|
unsigned long virtAddr;
|
||||||
|
unsigned long physAddr;
|
||||||
|
unsigned long fileSize;
|
||||||
|
unsigned long memSize;
|
||||||
|
unsigned long flags;
|
||||||
|
unsigned long align;
|
||||||
|
} elf32_program_header;
|
||||||
|
|
||||||
|
#endif
|
|
@ -16,6 +16,7 @@
|
||||||
#include "dev/channel.h"
|
#include "dev/channel.h"
|
||||||
#include "simpleio.h"
|
#include "simpleio.h"
|
||||||
#include "errors.h"
|
#include "errors.h"
|
||||||
|
#include "elf.h"
|
||||||
|
|
||||||
#define MAX_DRIVES 8 /* Maximum number of drives */
|
#define MAX_DRIVES 8 /* Maximum number of drives */
|
||||||
#define MAX_DIRECTORIES 8 /* Maximum number of open directories */
|
#define MAX_DIRECTORIES 8 /* Maximum number of open directories */
|
||||||
|
@ -23,6 +24,14 @@
|
||||||
#define MAX_LOADERS 10 /* Maximum number of file loaders */
|
#define MAX_LOADERS 10 /* Maximum number of file loaders */
|
||||||
#define MAX_EXT 4
|
#define MAX_EXT 4
|
||||||
|
|
||||||
|
static const char *const elf_cpu_desc[] = {
|
||||||
|
"NONE","M32","SPARC","386","68K","88K","IAMCU","860","MIPS","S370",
|
||||||
|
"MIPS_RS3_LE","UNKNOWN","UNKNOWN","UNKNOWN","UNKNOWN","PARISC","UNKNOWN",
|
||||||
|
"VPP500","SPARC32PLUS","960","PPC","PPC64","S390","SPU","UNKNOWN",
|
||||||
|
"UNKNOWN","UNKNOWN","UNKNOWN","UNKNOWN","UNKNOWN","UNKNOWN","UNKNOWN",
|
||||||
|
"UNKNOWN","UNKNOWN","UNKNOWN","UNKNOWN","V800","FR20","RH32","RCE","ARM"
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Types
|
* Types
|
||||||
*/
|
*/
|
||||||
|
@ -340,7 +349,7 @@ short fsys_findnext(short dir, p_file_info file) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return ERR_BAD_HANDLE;
|
return ERR_BAD_HANDLE;
|
||||||
|
@ -447,8 +456,7 @@ short fsys_set_cwd(const char * path) {
|
||||||
short fsys_get_cwd(char * path, short size) {
|
short fsys_get_cwd(char * path, short size) {
|
||||||
FRESULT result;
|
FRESULT result;
|
||||||
|
|
||||||
f_chdrive("");
|
result = f_getcwd(path, size);
|
||||||
result = f_getcwd(path);
|
|
||||||
if (result == FR_OK) {
|
if (result == FR_OK) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -644,13 +652,21 @@ short fchan_seek(t_channel * chan, long position, short base) {
|
||||||
|
|
||||||
file = fchan_to_file(chan);
|
file = fchan_to_file(chan);
|
||||||
if (file) {
|
if (file) {
|
||||||
if (base == CDEV_SEEK_ABSOLUTE) {
|
if (base == CDEV_SEEK_START) {
|
||||||
|
/* Position relative to the start of the file */
|
||||||
result = f_lseek(file, position);
|
result = f_lseek(file, position);
|
||||||
return fatfs_to_foenix(result);
|
return fatfs_to_foenix(result);
|
||||||
|
|
||||||
} else if (base == CDEV_SEEK_RELATIVE) {
|
} else if (base == CDEV_SEEK_RELATIVE) {
|
||||||
|
/* Position relative to the current position */
|
||||||
long current = f_tell(file);
|
long current = f_tell(file);
|
||||||
result = f_lseek(file, current + position);
|
result = f_lseek(file, current + position);
|
||||||
return fatfs_to_foenix(result);
|
return fatfs_to_foenix(result);
|
||||||
|
|
||||||
|
} else if (base == CDEV_SEEK_END) {
|
||||||
|
/* Position relative to the end of the file */
|
||||||
|
result = f_lseek(file, f_size(file) + position);
|
||||||
|
return fatfs_to_foenix(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -970,6 +986,77 @@ short fsys_pgz_loader(short chan, long destination, long * start) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
short fsys_elf_loader(short chan, long destination, long * start) {
|
||||||
|
char log_buffer[100];
|
||||||
|
size_t numBytes, highMem = 0, progIndex = 0, lowMem = ~0;
|
||||||
|
elf32_header header;
|
||||||
|
elf32_program_header progHeader;
|
||||||
|
|
||||||
|
chan_seek(chan, 0, 0);
|
||||||
|
numBytes = chan_read(chan, &header, sizeof(header));
|
||||||
|
|
||||||
|
if (header.ident.magic[0] != 0x7F ||
|
||||||
|
header.ident.magic[1] != 'E' ||
|
||||||
|
header.ident.magic[2] != 'L' ||
|
||||||
|
header.ident.magic[3] != 'F') {
|
||||||
|
DEBUG("[!] Not an ELF file");
|
||||||
|
return ERR_BAD_BINARY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (header.machine != CPU_ARCH) {
|
||||||
|
sprintf(&log_buffer, "[!] Incompatible CPU arch: expected %s, but found %s\n", elf_cpu_desc[CPU_ARCH], elf_cpu_desc[header.machine]);
|
||||||
|
DEBUG(log_buffer);
|
||||||
|
return ERR_BAD_BINARY;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (header.type) {
|
||||||
|
case ET_REL:
|
||||||
|
// ELF type: relocatable"
|
||||||
|
break;
|
||||||
|
case ET_EXEC:
|
||||||
|
// ELF type: executable"
|
||||||
|
break;
|
||||||
|
case ET_DYN:
|
||||||
|
DEBUG("[!] Cannot load ELF: loading shared objects is not supported");
|
||||||
|
return ERR_NOT_EXECUTABLE;
|
||||||
|
default:
|
||||||
|
DEBUG("[!] Cannot load ELF: invalid type flag (file probably corrupted)");
|
||||||
|
return ERR_NOT_EXECUTABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (progIndex < header.progNum) {
|
||||||
|
chan_seek(chan, progIndex * header.progSize + header.progOffset, 0);
|
||||||
|
numBytes = chan_read(chan, &progHeader, sizeof(progHeader));
|
||||||
|
switch (progHeader.type) {
|
||||||
|
case PT_NULL:
|
||||||
|
case PT_PHDR:
|
||||||
|
case PT_NOTE:
|
||||||
|
break;
|
||||||
|
case PT_DYNAMIC:
|
||||||
|
case PT_SHLIB:
|
||||||
|
DEBUG("[!] Dynamically linked ELFs not supported");
|
||||||
|
return ERR_NOT_EXECUTABLE;
|
||||||
|
case PT_LOAD:
|
||||||
|
chan_seek(chan, progHeader.offset, 0);
|
||||||
|
uint8_t * write_buffer = (uint8_t *) progHeader.physAddr;
|
||||||
|
numBytes = chan_read(chan, write_buffer, progHeader.fileSize);
|
||||||
|
if (progHeader.fileSize < progHeader.memSize)
|
||||||
|
memset((uint8_t*)progHeader.physAddr + progHeader.fileSize, 0, progHeader.memSize - progHeader.fileSize);
|
||||||
|
if (progHeader.physAddr + progHeader.fileSize > highMem) highMem = progHeader.physAddr + progHeader.fileSize;
|
||||||
|
if (progHeader.physAddr < lowMem) lowMem = progHeader.physAddr + progHeader.align;
|
||||||
|
break;
|
||||||
|
case PT_INTERP:
|
||||||
|
DEBUG("[!] Interpreted ELFs are not supported");
|
||||||
|
return ERR_NOT_EXECUTABLE;
|
||||||
|
}
|
||||||
|
progIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*start = header.entry;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Loader for the PGX binary file format
|
* Loader for the PGX binary file format
|
||||||
*
|
*
|
||||||
|
@ -1239,6 +1326,7 @@ short fsys_init() {
|
||||||
/* Register the built-in binary file loaders */
|
/* Register the built-in binary file loaders */
|
||||||
fsys_register_loader("PGZ", fsys_pgz_loader);
|
fsys_register_loader("PGZ", fsys_pgz_loader);
|
||||||
fsys_register_loader("PGX", fsys_pgx_loader);
|
fsys_register_loader("PGX", fsys_pgx_loader);
|
||||||
|
fsys_register_loader("ELF", fsys_elf_loader);
|
||||||
|
|
||||||
/* Register the channel driver for files. */
|
/* Register the channel driver for files. */
|
||||||
|
|
||||||
|
|
3323
src/foenixmcp.s68
Normal file
3323
src/foenixmcp.s68
Normal file
File diff suppressed because it is too large
Load diff
|
@ -15,6 +15,7 @@
|
||||||
#include "dev/channel.h"
|
#include "dev/channel.h"
|
||||||
#include "dev/block.h"
|
#include "dev/block.h"
|
||||||
#include "dev/fsys.h"
|
#include "dev/fsys.h"
|
||||||
|
#include "dev/rtc.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Syscall function numbers
|
* Syscall function numbers
|
||||||
|
@ -571,7 +572,7 @@ extern short sys_fsys_rename(const char * old_path, const char * new_path);
|
||||||
* Returns:
|
* Returns:
|
||||||
* 0 on success, negative number on failure.
|
* 0 on success, negative number on failure.
|
||||||
*/
|
*/
|
||||||
extern short sys_fsys_setcwd(const char * path);
|
extern short sys_fsys_set_cwd(const char * path);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current working drive and directory
|
* Get the current working drive and directory
|
||||||
|
@ -583,7 +584,7 @@ extern short sys_fsys_setcwd(const char * path);
|
||||||
* Returns:
|
* Returns:
|
||||||
* 0 on success, negative number on failure.
|
* 0 on success, negative number on failure.
|
||||||
*/
|
*/
|
||||||
extern short sys_fsys_getcwd(char * path, short size);
|
extern short sys_fsys_get_cwd(char * path, short size);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Load a file into memory at the designated destination address.
|
* Load a file into memory at the designated destination address.
|
||||||
|
|
|
@ -21,7 +21,7 @@ PENDING_GRP0 = $00C00100
|
||||||
PENDING_GRP1 = $00C00102
|
PENDING_GRP1 = $00C00102
|
||||||
PENDING_GRP2 = $00C00104
|
PENDING_GRP2 = $00C00104
|
||||||
|
|
||||||
section "vectors",code
|
section "VECTORS",code
|
||||||
|
|
||||||
dc.l ___STACK ; 00 - Initial stack pointer
|
dc.l ___STACK ; 00 - Initial stack pointer
|
||||||
dc.l coldboot ; 01 - Initial PC
|
dc.l coldboot ; 01 - Initial PC
|
||||||
|
@ -385,7 +385,7 @@ _call_user:
|
||||||
move.l (8,a7),a1 ; Get the pointer to the process's stack
|
move.l (8,a7),a1 ; Get the pointer to the process's stack
|
||||||
move.l (12,a7),d0 ; Get the number of parameters passed
|
move.l (12,a7),d0 ; Get the number of parameters passed
|
||||||
move.l (16,a7),a2 ; Get the pointer to the parameters
|
move.l (16,a7),a2 ; Get the pointer to the parameters
|
||||||
andi #$dfff,sr ; Drop into user mode
|
; andi #$dfff,sr ; Drop into user mode
|
||||||
movea.l a1,a7 ; Set the stack
|
movea.l a1,a7 ; Set the stack
|
||||||
|
|
||||||
move.l a2,-(a7) ; Push the parameters list
|
move.l a2,-(a7) ; Push the parameters list
|
||||||
|
|
13416
src/mapfile
13416
src/mapfile
File diff suppressed because it is too large
Load diff
|
@ -42,8 +42,9 @@ void codec_set_volume(unsigned char vol) {
|
||||||
volume = vol;
|
volume = vol;
|
||||||
|
|
||||||
*CODEC = 0x0A00 | (0xFF - (vol & 0xFF));
|
*CODEC = 0x0A00 | (0xFF - (vol & 0xFF));
|
||||||
*CODEC = 0x0400 | ((vol >> 1) & 0xff);
|
codec_wait();
|
||||||
|
|
||||||
|
*CODEC = 0x0400 | ((vol >> 1) & 0xff);
|
||||||
codec_wait();
|
codec_wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
13
vbcc/config/a2560u_flash-linux
Normal file
13
vbcc/config/a2560u_flash-linux
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
-cc=vbccm68k -quiet %s -o= %s %s -O=%ld -I$VBCC/targets/m68k-foenix/include
|
||||||
|
-ccv=vbccm68k %s -o= %s %s -O=%ld -I$VBCC/targets/m68k-foenix/include
|
||||||
|
-as=vasmm68k_mot -quiet -Fvobj -nowarn=62 %s -o %s
|
||||||
|
-asv=vasmm68k_mot -Fvobj -nowarn=62 %s -o %s
|
||||||
|
-rm=rm %s
|
||||||
|
-rmv=rm %s
|
||||||
|
-ld=vlink -brawbin1 -x -Cvbcc m68k/startup_m68k.o %s %s -L$VBCC/targets/m68k-foenix/lib -T$VBCC/targets/m68k-foenix/vlink_flash_a2560u.cmd -lvc -o %s -Mmapfile
|
||||||
|
-l2=vlink -brawbin1 -x -Cvbcc %s %s -L$VBCC/targets/m68k-foenix/lib -T$VBCC/targets/m68k-foenix/vlink_flash_a2560u.cmd -o %s -Mmapfile
|
||||||
|
-ldv=vlink -brawbin1 -t -x -Cvbcc m68k/startup.o %s %s -L$VBCC/targets/m68k-foenix/lib -T$VBCC/targets/m68k-foenix/vlink_flash_a2560u.cmd -lvc -o %s -Mmapfile
|
||||||
|
-l2v=vlink -brawbin1 -t -x -Cvbcc %s %s -L$VBCC/targets/m68k-foenix/lib -T$VBCC/targets/m68k-foenix/vlink_flash_a2560u.cmd -o %s -Mmapfile
|
||||||
|
-ul=-l%s
|
||||||
|
-cf=-F%s
|
||||||
|
-ml=1000
|
Loading…
Reference in a new issue