Merge branch 'main' into a2560k

This commit is contained in:
Peter Weingartner 2021-11-22 21:00:47 -05:00
commit 6b8e2204f6
23 changed files with 11162 additions and 7071 deletions

3
.gitignore vendored
View file

@ -1,6 +1,9 @@
# Prerequisites
*.d
# Python cache
C256Mgr/__pycache__/
# Object files
*.o
*.ko

View file

@ -18,7 +18,7 @@
1. [ ] Memory management
1. [x] PGX file loader
1. [x] PGZ file loader
1. [ ] ELF file loader
1. [x] ELF file loader
1. [x] Command Line Interface
1. [ ] Mouse driver
@ -28,7 +28,7 @@
1. [ ] Auto-run/configuration file
1. Built-in commands:
1. [x] DIR [path]
1. [ ] COPY [path] TO [path]
1. [x] COPY [path] TO [path]
1. [ ] RENAME [path] TO [path]
1. [x] DELETE [path]
1. [x] CD [path]

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -31,7 +31,8 @@ ifeq ($(OS),Windows_NT)
# export CFLAGS = +$(VBCC)/config/a2560u_flash -I. -I$(CURDIR)/include -I$(CURDIR)
export RM = cmd /C del /Q /F
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
endif

View file

@ -56,6 +56,8 @@ const t_cli_command g_cli_commands[] = {
{ "HELP", "HELP : print this helpful message", cmd_help },
{ "CD", "CD <path> : sets the current directory", cmd_cd },
{ "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 },
{ "DIR", "DIR <path> : print directory listing", cmd_dir },
{ "DISKFILL", "DISKFILL <drive #> <sector #> <byte value>", cmd_diskfill },
@ -258,6 +260,7 @@ short cli_rerepl() {
//
short cli_repl(short channel) {
char command_line[MAX_COMMAND_SIZE];
char cwd_buffer[MAX_PATH_LEN];
char * arg;
char * token_save;
char * delim = " ";
@ -267,7 +270,11 @@ short cli_repl(short channel) {
g_current_channel = channel;
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_write(channel, "\n", 1);

1104
src/cli/dis68k.c Normal file

File diff suppressed because it is too large Load diff

6
src/cli/dis68k.h Normal file
View file

@ -0,0 +1,6 @@
#ifndef __MCP_DIS68K_H
#define __MCP_DIS68K_H
void disasm(unsigned long int start, unsigned long int end);
#endif

View file

@ -1,5 +1,6 @@
#include <ctype.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.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
*/

View file

@ -25,6 +25,11 @@ extern short cmd_mkdir(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
*/

View file

@ -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
*

View file

@ -5,6 +5,8 @@
#ifndef __MEM_CMDS_H
#define __MEM_CMDS_H
#include "dis68k.h"
/*
* Print out the contents of a block of memory
*
@ -12,6 +14,13 @@
*/
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
*

View file

@ -417,17 +417,18 @@ short chan_flush(short channel) {
}
}
//
// Attempt to set the position of the channel cursor (if supported)
//
// Inputs:
// channel = the number of the channel
// position = the position of the cursor
// base = whether the position is absolute or relative to the current position
//
// Returns:
// 0 = success, a negative number is an error.
//
/*
* Attempt to set the position of the channel cursor (if supported)
*
* Inputs:
* channel = the number of the channel
* position = the position of the cursor
* 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.
*/
short chan_seek(short channel, long position, short base) {
p_channel chan;
p_dev_chan cdev;

View file

@ -36,8 +36,9 @@
#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_SEEK_ABSOLUTE 0
#define CDEV_SEEK_RELATIVE 1
#define CDEV_SEEK_START 0 /* Seek from the start of the file */
#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
@ -242,7 +243,8 @@ extern short chan_flush(short channel);
* Inputs:
* channel = the number of the channel
* 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.

86
src/dev/elf.h Normal file
View 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

View file

@ -16,6 +16,7 @@
#include "dev/channel.h"
#include "simpleio.h"
#include "errors.h"
#include "elf.h"
#define MAX_DRIVES 8 /* Maximum number of drives */
#define MAX_DIRECTORIES 8 /* Maximum number of open directories */
@ -23,6 +24,14 @@
#define MAX_LOADERS 10 /* Maximum number of file loaders */
#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
*/
@ -340,7 +349,7 @@ short fsys_findnext(short dir, p_file_info file) {
}
}
return 0
return 0;
}
} else {
return ERR_BAD_HANDLE;
@ -447,8 +456,7 @@ short fsys_set_cwd(const char * path) {
short fsys_get_cwd(char * path, short size) {
FRESULT result;
f_chdrive("");
result = f_getcwd(path);
result = f_getcwd(path, size);
if (result == FR_OK) {
return 0;
} else {
@ -644,13 +652,21 @@ short fchan_seek(t_channel * chan, long position, short base) {
file = fchan_to_file(chan);
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);
return fatfs_to_foenix(result);
} else if (base == CDEV_SEEK_RELATIVE) {
/* Position relative to the current position */
long current = f_tell(file);
result = f_lseek(file, current + position);
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;
}
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
*
@ -1239,6 +1326,7 @@ short fsys_init() {
/* Register the built-in binary file loaders */
fsys_register_loader("PGZ", fsys_pgz_loader);
fsys_register_loader("PGX", fsys_pgx_loader);
fsys_register_loader("ELF", fsys_elf_loader);
/* Register the channel driver for files. */

3323
src/foenixmcp.s68 Normal file

File diff suppressed because it is too large Load diff

View file

@ -15,6 +15,7 @@
#include "dev/channel.h"
#include "dev/block.h"
#include "dev/fsys.h"
#include "dev/rtc.h"
/*
* Syscall function numbers
@ -571,7 +572,7 @@ extern short sys_fsys_rename(const char * old_path, const char * new_path);
* Returns:
* 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
@ -583,7 +584,7 @@ extern short sys_fsys_setcwd(const char * path);
* Returns:
* 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.

View file

@ -21,7 +21,7 @@ PENDING_GRP0 = $00C00100
PENDING_GRP1 = $00C00102
PENDING_GRP2 = $00C00104
section "vectors",code
section "VECTORS",code
dc.l ___STACK ; 00 - Initial stack pointer
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 (12,a7),d0 ; Get the number of parameters passed
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
move.l a2,-(a7) ; Push the parameters list

13416
src/mapfile

File diff suppressed because it is too large Load diff

View file

@ -42,8 +42,9 @@ void codec_set_volume(unsigned char vol) {
volume = vol;
*CODEC = 0x0A00 | (0xFF - (vol & 0xFF));
*CODEC = 0x0400 | ((vol >> 1) & 0xff);
codec_wait();
*CODEC = 0x0400 | ((vol >> 1) & 0xff);
codec_wait();
}

View 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