More system calls
Added some more system calls. Made a slight change to the TRAP convention. Now using TRAP #15 for system calls, and moved everything down one register: D0 = function, D1 = param 1, etc.
This commit is contained in:
parent
7498b83349
commit
cb75f46b2e
|
@ -10,6 +10,7 @@
|
|||
#include "dev/channel.h"
|
||||
#include "dev/console.h"
|
||||
#include "dev/ps2.h"
|
||||
#include "dev/kbd_mo.h"
|
||||
#include "dev/text_screen_iii.h"
|
||||
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "log.h"
|
||||
#include "syscalls.h"
|
||||
#include "fsys.h"
|
||||
#include "fatfs/ff.h"
|
||||
#include "dev/channel.h"
|
||||
|
@ -448,6 +450,34 @@ short fchan_ioctrl(t_channel * chan, short command, unsigned char * buffer, shor
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mount, or remount the block device
|
||||
*
|
||||
* For the hard drive, this need be called only once, but for removable
|
||||
* devices, this should be called whenever the media has changed.
|
||||
*
|
||||
* Inputs:
|
||||
* bdev = the number of the block device to mount or re-mount
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success, any other number is an error
|
||||
*/
|
||||
short fsys_mount(short bdev) {
|
||||
FRESULT fres;
|
||||
char drive[3];
|
||||
drive[0] = '0' + (char)bdev;
|
||||
drive[1] = ':';
|
||||
drive[2] = 0;
|
||||
|
||||
fres = f_mount(&g_drive[bdev], drive, 0);
|
||||
if (fres != FR_OK) {
|
||||
DEBUG("Unable to mount drive:");
|
||||
DEBUG(drive);
|
||||
return fres;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the file system
|
||||
|
@ -468,7 +498,14 @@ short fsys_init() {
|
|||
g_fil_state[i] = 0;
|
||||
}
|
||||
|
||||
/* TODO: Mount all logical drives that are present */
|
||||
/* Mount all logical drives that are present */
|
||||
|
||||
for (i = 0; i < MAX_DRIVES; i++) {
|
||||
short res = sys_bdev_status((short)i);
|
||||
if (res >= 0) {
|
||||
fsys_mount(i);
|
||||
}
|
||||
}
|
||||
|
||||
/* Register the channel driver for files. */
|
||||
|
||||
|
@ -486,4 +523,6 @@ short fsys_init() {
|
|||
g_file_dev.flush = fchan_flush;
|
||||
|
||||
cdev_register(&g_file_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ typedef struct s_file_info {
|
|||
* Returns:
|
||||
* 0 on success, negative number on failure.
|
||||
*/
|
||||
short fsys_init();
|
||||
extern short fsys_init();
|
||||
|
||||
/**
|
||||
* Attempt to open a file given the path to the file and the mode.
|
||||
|
|
66
src/dev/wip/midi.c
Normal file
66
src/dev/wip/midi.c
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Definitions for the MIDI ports
|
||||
*/
|
||||
|
||||
#include "midi_reg.h"
|
||||
#include "dev/midi.h"
|
||||
|
||||
/*
|
||||
* Initilialize the MIDI port
|
||||
*/
|
||||
short midi_init() {
|
||||
*MIDI_CMD = 0xff; /* Send the command to reset the MIDI port */
|
||||
|
||||
// while ((*MIDI_STAT & MIDI_STAT_RX_EMPTY) == 0) {
|
||||
// /* While there is data, throw it out */
|
||||
// unsigned char dummy = *MIDI_DATA;
|
||||
// }
|
||||
|
||||
*MIDI_CMD = 0x3F; /* Switch the MIDI port into UART mode */
|
||||
|
||||
// while ((*MIDI_STAT & MIDI_STAT_RX_EMPTY) == 0) {
|
||||
// /* While there is data, throw it out */
|
||||
// unsigned char dummy = *MIDI_DATA;
|
||||
// }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a byte to the MIDI port
|
||||
*
|
||||
* Inputs:
|
||||
* b = the byte to send
|
||||
*/
|
||||
short midi_put(unsigned char b) {
|
||||
while ((*MIDI_STAT & MIDI_STAT_TX_BUSY) != 0) {
|
||||
/* Wait until the MIDI transmitter is not busy */
|
||||
;
|
||||
}
|
||||
|
||||
/* Send the byte */
|
||||
*MIDI_DATA = b;
|
||||
|
||||
while ((*MIDI_STAT & MIDI_STAT_TX_BUSY) != 0) {
|
||||
/* Wait until the MIDI transmitter is not busy */
|
||||
;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a byte from the MIDI port
|
||||
*
|
||||
* Returns:
|
||||
* b = the byte to send
|
||||
*/
|
||||
short midi_get_poll() {
|
||||
if (*MIDI_STAT & MIDI_STAT_RX_EMPTY) {
|
||||
/* There's no data... return 0 */
|
||||
return 0;
|
||||
} else {
|
||||
/* Get and return the byte */
|
||||
return (short)*MIDI_DATA;
|
||||
}
|
||||
}
|
29
src/dev/wip/midi.h
Normal file
29
src/dev/wip/midi.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Declarations for the MIDI ports
|
||||
*/
|
||||
|
||||
#ifndef __MIDI_H
|
||||
#define __MIDI_H
|
||||
|
||||
/*
|
||||
* Initilialize the MIDI port
|
||||
*/
|
||||
extern short midi_init();
|
||||
|
||||
/*
|
||||
* Send a byte to the MIDI port
|
||||
*
|
||||
* Inputs:
|
||||
* b = the byte to send
|
||||
*/
|
||||
extern short midi_put(unsigned char b);
|
||||
|
||||
/*
|
||||
* Get a byte from the MIDI port
|
||||
*
|
||||
* Returns:
|
||||
* b = the byte to send
|
||||
*/
|
||||
extern short midi_get_poll();
|
||||
|
||||
#endif
|
|
@ -14,14 +14,14 @@
|
|||
#include "dev/text_screen_iii.h"
|
||||
#include "dev/pata.h"
|
||||
#include "dev/ps2.h"
|
||||
// #include "dev/kbd_mo.h"
|
||||
#include "dev/kbd_mo.h"
|
||||
#include "dev/sdc.h"
|
||||
#include "dev/uart.h"
|
||||
#include "snd/codec.h"
|
||||
#include "snd/psg.h"
|
||||
#include "snd/sid.h"
|
||||
#include "fatfs/ff.h"
|
||||
// #include "cli/cli.h"
|
||||
#include "cli/cli.h"
|
||||
#include "log.h"
|
||||
|
||||
const char* VolumeStr[FF_VOLUMES] = { "@S", "@F", "@H" };
|
||||
|
@ -190,22 +190,23 @@ void initialize() {
|
|||
DEBUG("PS/2 keyboard initialized.");
|
||||
}
|
||||
|
||||
// if (res = kbdmo_init()) {
|
||||
// print_error(0, "FAILED: A2560K built-in keyboard initialization", res);
|
||||
// } else {
|
||||
// DEBUG("A2560K built-in keyboard initialized.");
|
||||
// }
|
||||
if (res = kbdmo_init()) {
|
||||
print_error(0, "FAILED: A2560K built-in keyboard initialization", res);
|
||||
} else {
|
||||
DEBUG("A2560K built-in keyboard initialized.");
|
||||
}
|
||||
|
||||
// if (res = cli_init()) {
|
||||
// print_error(0, "FAILED: CLI initialization", res);
|
||||
// } else {
|
||||
// DEBUG("CLI initialized.");
|
||||
// }
|
||||
if (res = cli_init()) {
|
||||
print_error(0, "FAILED: CLI initialization", res);
|
||||
} else {
|
||||
DEBUG("CLI initialized.");
|
||||
}
|
||||
|
||||
print(0, "MASK_GRP1: ");
|
||||
unsigned short grp1 = *MASK_GRP1;
|
||||
print_hex_16(0, grp1);
|
||||
print(0, "\n");
|
||||
if (res = fsys_init()) {
|
||||
print_error(0, "FAILED: file system initialization", res);
|
||||
} else {
|
||||
DEBUG("File system initialized.");
|
||||
}
|
||||
|
||||
/* Enable all interrupts */
|
||||
// int_enable_all();
|
||||
|
@ -421,7 +422,16 @@ int main(int argc, char * argv[]) {
|
|||
// try_mo_scancodes(0);
|
||||
// try_bdev_getput(0, BDEV_SDC);
|
||||
|
||||
cli_repl(1);
|
||||
// print(0, "Watching for MIDI signals:\n");
|
||||
// while (1) {
|
||||
// midi_byte = midi_get_poll();
|
||||
// if (midi_byte && (midi_byte != 0xFE) && (midi_byte != 0xF8)) {
|
||||
// print_hex(0, midi_byte);
|
||||
// print(0, "\n");
|
||||
// }
|
||||
// }
|
||||
|
||||
cli_repl(0);
|
||||
|
||||
DEBUG("Stopping.");
|
||||
|
||||
|
|
2913
src/foenixmcp.s68
2913
src/foenixmcp.s68
File diff suppressed because it is too large
Load diff
15
src/include/midi_reg.h
Normal file
15
src/include/midi_reg.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Definitions for the SuperIO MIDI ports
|
||||
*/
|
||||
|
||||
#ifndef __MIDI_REG_H
|
||||
#define __MIDI_REG_H
|
||||
|
||||
#define MIDI_DATA ((volatile unsigned char *)0x00C02330)
|
||||
#define MIDI_STAT ((volatile unsigned char *)0x00C02331)
|
||||
#define MIDI_CMD ((volatile unsigned char *)0x00C02331)
|
||||
|
||||
#define MIDI_STAT_TX_BUSY 0x80
|
||||
#define MIDI_STAT_RX_EMPTY 0x40
|
||||
|
||||
#endif
|
|
@ -7,10 +7,14 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef __SYSCALLS_M68K_H
|
||||
#define __SYSCALLS_M68K_H
|
||||
#ifndef __SYSCALLS_H
|
||||
#define __SYSCALLS_H
|
||||
|
||||
#include "types.h"
|
||||
#include "interrupt.h"
|
||||
#include "dev/channel.h"
|
||||
#include "dev/block.h"
|
||||
#include "dev/fsys.h"
|
||||
|
||||
/*
|
||||
* Syscall function numbers
|
||||
|
@ -20,8 +24,13 @@
|
|||
|
||||
#define KFN_EXIT 0x00 /* Quick the current program and return to the command line */
|
||||
#define KFN_WARMBOOT 0x01 /* Do a soft re-initialization */
|
||||
#define KFN_SETHANDLER 0x02 /* Set a handler for an exception / interrupt */
|
||||
#define KFN_SETINTERRUPT 0x03 /* Enable / Disable an interrupt */
|
||||
#define KFN_INT_REGISTER 0x02 /* Set a handler for an exception / interrupt */
|
||||
#define KFN_INT_ENABLE 0x03 /* Enable an interrupt */
|
||||
#define KFN_INT_DISABLE 0x04 /* Disable an interrupt */
|
||||
#define KFN_INT_ENABLE_ALL 0x05 /* Enable all interrupts */
|
||||
#define KFN_INT_DISABLE_ALL 0x06 /* Disable all interrupts */
|
||||
#define KFN_INT_CLEAR 0x05 /* Clear (acknowledge) an interrupt */
|
||||
#define KFN_INT_PENDING 0x06 /* Return true if the interrupt is pending */
|
||||
|
||||
/* Channel system calls */
|
||||
|
||||
|
@ -60,25 +69,91 @@
|
|||
#define KFN_MKDIR 0x39 /* Create a directory */
|
||||
#define KFN_LOAD 0x3A /* Load a file into memory */
|
||||
#define KFN_SAVE 0x3B /* Save a block of memory to a file */
|
||||
|
||||
/* Process system calls */
|
||||
|
||||
#define KFN_RUN 0x40 /* Load an execute a binary file */
|
||||
#define KFN_LOAD_REGISTER 0x41 /* Register a file type handler for executable binaries */
|
||||
#define KFN_RUN 0x3C /* Load an execute a binary file */
|
||||
#define KFN_LOAD_REGISTER 0x3D /* Register a file type handler for executable binaries */
|
||||
|
||||
/* Timer calls */
|
||||
|
||||
#define KFN_DELAY 0x50 /* Block for a certain amount of time */
|
||||
#define KFN_SET_ALARM 0x51 /* Set an alarm for a certain amount of time */
|
||||
#define KFN_GET_TIMECODE 0x52 /* Gets the current time code (increments since boot) */
|
||||
#define KFN_SET_DATETIME 0x53 /* Set the real time clock date-time */
|
||||
#define KFN_GET_DATETIME 0x54 /* Get the real time clock date-time */
|
||||
#define KFN_DELAY 0x40 /* Block for a certain amount of time */
|
||||
#define KFN_SET_ALARM 0x41 /* Set an alarm for a certain amount of time */
|
||||
#define KFN_GET_TIMECODE 0x42 /* Gets the current time code (increments since boot) */
|
||||
#define KFN_SET_DATETIME 0x43 /* Set the real time clock date-time */
|
||||
#define KFN_GET_DATETIME 0x44 /* Get the real time clock date-time */
|
||||
|
||||
/*
|
||||
* Call into the kernel (provided by assembly)
|
||||
*/
|
||||
extern int32_t syscall(int32_t function, ...);
|
||||
|
||||
/***
|
||||
*** Core system calls
|
||||
***/
|
||||
|
||||
/*
|
||||
* Enable all interrupts
|
||||
*
|
||||
* NOTE: this is actually provided in the low level assembly
|
||||
*/
|
||||
extern void sys_int_enable_all();
|
||||
|
||||
/*
|
||||
* Disable all interrupts
|
||||
*
|
||||
* NOTE: this is actually provided in the low level assembly
|
||||
*/
|
||||
extern void sys_int_disable_all();
|
||||
|
||||
/*
|
||||
* Disable an interrupt by masking it
|
||||
*
|
||||
* Inputs:
|
||||
* n = the number of the interrupt: n[7..4] = group number, n[3..0] = individual number.
|
||||
*/
|
||||
extern void sys_int_disable(unsigned short n);
|
||||
|
||||
/*
|
||||
* Enable an interrupt
|
||||
*
|
||||
* Inputs:
|
||||
* n = the number of the interrupt
|
||||
*/
|
||||
extern void sys_int_enable(unsigned short n);
|
||||
|
||||
/*
|
||||
* Register a handler for a given interrupt.
|
||||
*
|
||||
* Inputs:
|
||||
* n = the number of the interrupt
|
||||
* handler = pointer to the interrupt handler to register
|
||||
*
|
||||
* Returns:
|
||||
* the pointer to the previous interrupt handler
|
||||
*/
|
||||
extern p_int_handler sys_int_register(unsigned short n, p_int_handler handler);
|
||||
|
||||
/*
|
||||
* Return true (non-zero) if an interrupt is pending for the given interrupt
|
||||
*
|
||||
* Inputs:
|
||||
* n = the number of the interrupt: n[7..4] = group number, n[3..0] = individual number.
|
||||
*
|
||||
* Returns:
|
||||
* non-zero if interrupt n is pending, 0 if not
|
||||
*/
|
||||
extern short sys_int_pending(unsigned short n);
|
||||
|
||||
/*
|
||||
* Acknowledge an interrupt (clear out its pending flag)
|
||||
*
|
||||
* Inputs:
|
||||
* n = the number of the interrupt: n[7..4] = group number, n[3..0] = individual number.
|
||||
*/
|
||||
extern void sys_int_clear(unsigned short n);
|
||||
|
||||
/***
|
||||
*** Channel system calls
|
||||
***/
|
||||
|
||||
/*
|
||||
* Read a single byte from the channel
|
||||
*
|
||||
|
@ -116,16 +191,16 @@ extern short sys_chan_read(short channel, unsigned char * buffer, short size);
|
|||
*/
|
||||
extern short sys_chan_readline(short channel, unsigned char * buffer, short size);
|
||||
|
||||
/*
|
||||
* Write a single byte to the device
|
||||
*
|
||||
* Inputs:
|
||||
* channel = the number of the channel
|
||||
* b = the byte to write
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success, a negative value on error
|
||||
*/
|
||||
/*
|
||||
* Write a single byte to the device
|
||||
*
|
||||
* Inputs:
|
||||
* channel = the number of the channel
|
||||
* b = the byte to write
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success, a negative value on error
|
||||
*/
|
||||
extern short sys_chan_write_b(short channel, unsigned char b);
|
||||
|
||||
/*
|
||||
|
@ -140,5 +215,126 @@ extern short sys_chan_write_b(short channel, unsigned char b);
|
|||
*/
|
||||
extern short sys_chan_write(short channel, unsigned char * buffer, short size);
|
||||
|
||||
/*
|
||||
* Return the status of the channel device
|
||||
*
|
||||
* Inputs:
|
||||
* channel = the number of the channel
|
||||
*
|
||||
* Returns:
|
||||
* the status of the device
|
||||
*/
|
||||
extern short sys_chan_status(short channel);
|
||||
|
||||
/*
|
||||
* Ensure that any pending writes to teh device have been completed
|
||||
*
|
||||
* Inputs:
|
||||
* channel = the number of the channel
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success, any negative number is an error code
|
||||
*/
|
||||
extern short sys_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.
|
||||
*/
|
||||
extern short sys_chan_seek(short channel, long position, short base);
|
||||
|
||||
/*
|
||||
* Issue a control command to the device
|
||||
*
|
||||
* Inputs:
|
||||
* channel = the number of the channel
|
||||
* command = the number of the command to send
|
||||
* buffer = pointer to bytes of additional data for the command
|
||||
* size = the size of the buffer
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success, any negative number is an error code
|
||||
*/
|
||||
extern short sys_chan_ioctrl(short channel, short command, uint8_t * buffer, short size);
|
||||
|
||||
/***
|
||||
*** Block device system calls
|
||||
***/
|
||||
|
||||
//
|
||||
// Register a block device driver
|
||||
//
|
||||
extern short sys_bdev_register(p_dev_block device);
|
||||
|
||||
//
|
||||
// Read a block from the device
|
||||
//
|
||||
// Inputs:
|
||||
// dev = the number of the device
|
||||
// lba = the logical block address of the block to read
|
||||
// buffer = the buffer into which to copy the block data
|
||||
// size = the size of the buffer.
|
||||
//
|
||||
// Returns:
|
||||
// number of bytes read, any negative number is an error code
|
||||
//
|
||||
extern short sys_bdev_read(short dev, long lba, unsigned char * buffer, short size);
|
||||
|
||||
//
|
||||
// Write a block from the device
|
||||
//
|
||||
// Inputs:
|
||||
// dev = the number of the device
|
||||
// lba = the logical block address of the block to write
|
||||
// buffer = the buffer containing the data to write
|
||||
// size = the size of the buffer.
|
||||
//
|
||||
// Returns:
|
||||
// number of bytes written, any negative number is an error code
|
||||
//
|
||||
extern short sys_bdev_write(short dev, long lba, const unsigned char * buffer, short size);
|
||||
|
||||
//
|
||||
// Return the status of the block device
|
||||
//
|
||||
// Inputs:
|
||||
// dev = the number of the device
|
||||
//
|
||||
// Returns:
|
||||
// the status of the device
|
||||
//
|
||||
extern short sys_bdev_status(short dev);
|
||||
|
||||
//
|
||||
// Ensure that any pending writes to teh device have been completed
|
||||
//
|
||||
// Inputs:
|
||||
// dev = the number of the device
|
||||
//
|
||||
// Returns:
|
||||
// 0 on success, any negative number is an error code
|
||||
//
|
||||
extern short sys_bdev_flush(short dev);
|
||||
|
||||
//
|
||||
// Issue a control command to the device
|
||||
//
|
||||
// Inputs:
|
||||
// dev = the number of the device
|
||||
// command = the number of the command to send
|
||||
// buffer = pointer to bytes of additional data for the command
|
||||
// size = the size of the buffer
|
||||
//
|
||||
// Returns:
|
||||
// 0 on success, any negative number is an error code
|
||||
//
|
||||
extern short sys_bdev_ioctrl(short dev, short command, unsigned char * buffer, short size);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -6,16 +6,10 @@ for the Motorola 68000 series processors.
|
|||
## System Call Convention
|
||||
|
||||
System calls will be made through the ``TRAP`` instruction.
|
||||
The caller will be expected to push parameters onto the stack using the
|
||||
VBCC ABI, and then issuing a ``TRAP`` instruction.
|
||||
|
||||
* Stack pointer is A7
|
||||
* All arguments are passed on the stack
|
||||
* Registers D0, D1, A0, and A1 will be used as scratch.
|
||||
* Registers D2 - D7, and A2 - A6 will be preserved by the kernel.
|
||||
* Registers D1 - D7, and A0 - A6 will be preserved by the kernel.
|
||||
* First parameter is in D1, second in D2, and so on.
|
||||
* The caller places the function number in D0.
|
||||
* All BIOS calls are issued through a ``TRAP #15`` instruction.
|
||||
* Results are returned in D0.
|
||||
|
||||
## BIOS
|
||||
|
||||
All BIOS calls are issued through a ``TRAP #13`` instruction. Register D0 contains the number of the system call to make.
|
||||
|
||||
|
|
|
@ -4,34 +4,164 @@
|
|||
* NOTE: these routines are not called directly but are instead called through TRAP#13
|
||||
*/
|
||||
|
||||
#include "log.h"
|
||||
#include "types.h"
|
||||
#include "syscalls.h"
|
||||
#include "log.h"
|
||||
#include "interrupt.h"
|
||||
#include "dev/channel.h"
|
||||
#include "dev/block.h"
|
||||
#include "dev/fsys.h"
|
||||
|
||||
/*
|
||||
* Determine the correct system function implementation and call it.
|
||||
*/
|
||||
int32_t syscall_dispatch(int32_t function, int32_t param0, int32_t param1, int32_t param2, int32_t param3, int32_t param4, int32_t param5) {
|
||||
switch (function) {
|
||||
case KFN_CHAN_WRITE_B:
|
||||
return chan_write_b((short)param0, (uint8_t)param1);
|
||||
switch (function & 0x00f0) {
|
||||
case 0x00:
|
||||
/* Core System Calls */
|
||||
switch (function) {
|
||||
case KFN_EXIT:
|
||||
break;
|
||||
|
||||
case KFN_CHAN_WRITE:
|
||||
return chan_write((short)param0, (const uint8_t *)param1, (short)param2);
|
||||
case KFN_WARMBOOT:
|
||||
break;
|
||||
|
||||
case KFN_CHAN_READ_B:
|
||||
return chan_read_b((short)param0);
|
||||
case KFN_INT_REGISTER:
|
||||
return (int32_t)int_register((unsigned short)param0, (p_int_handler)param1);
|
||||
|
||||
case KFN_CHAN_READ:
|
||||
return chan_read((short)param0, (const uint8_t *)param1, (short)param2);
|
||||
case KFN_INT_ENABLE:
|
||||
int_enable((unsigned short)param0);
|
||||
return;
|
||||
|
||||
case KFN_CHAN_READ_LINE:
|
||||
return chan_readline((short)param0, (const uint8_t *)param1, (short)param2);
|
||||
case KFN_INT_DISABLE:
|
||||
int_disable((unsigned short)param0);
|
||||
return;
|
||||
|
||||
case KFN_INT_ENABLE_ALL:
|
||||
int_enable_all();
|
||||
return;
|
||||
|
||||
case KFN_INT_DISABLE_ALL:
|
||||
int_disable_all();
|
||||
return;
|
||||
|
||||
case KFN_INT_CLEAR:
|
||||
int_clear((unsigned short)param0);
|
||||
return;
|
||||
|
||||
case KFN_INT_PENDING:
|
||||
return int_pending((unsigned short)param0);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x10:
|
||||
/* Channel system calls */
|
||||
switch (function) {
|
||||
case KFN_CHAN_WRITE_B:
|
||||
return chan_write_b((short)param0, (uint8_t)param1);
|
||||
|
||||
case KFN_CHAN_WRITE:
|
||||
return chan_write((short)param0, (const uint8_t *)param1, (short)param2);
|
||||
|
||||
case KFN_CHAN_READ_B:
|
||||
return chan_read_b((short)param0);
|
||||
|
||||
case KFN_CHAN_READ:
|
||||
return chan_read((short)param0, (const uint8_t *)param1, (short)param2);
|
||||
|
||||
case KFN_CHAN_READ_LINE:
|
||||
return chan_readline((short)param0, (const uint8_t *)param1, (short)param2);
|
||||
|
||||
case KFN_CHAN_STATUS:
|
||||
return chan_status((short)param0);
|
||||
|
||||
case KFN_CHAN_FLUSH:
|
||||
return chan_flush((short)param0);
|
||||
|
||||
case KFN_CHAN_SEEK:
|
||||
return chan_seek((short)param0, (long)param1, (short)param2);
|
||||
|
||||
case KFN_CHAN_IOCTRL:
|
||||
return chan_ioctrl((short)param0, (short)param1, (unsigned char *)param2, (short)param3);
|
||||
|
||||
case KFN_CHAN_REGISTER:
|
||||
return cdev_register((p_dev_chan)param0);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x20:
|
||||
/* Block device system calls */
|
||||
switch (function) {
|
||||
case KFN_BDEV_GETBLOCK:
|
||||
return bdev_read((short)param0, (long)param1, (unsigned char *)param2, (short)param3);
|
||||
|
||||
case KFN_BDEV_PUTBLOCK:
|
||||
return bdev_write((short)param0, (long)param1, (unsigned char *)param2, (short)param3);
|
||||
|
||||
case KFN_BDEV_FLUSH:
|
||||
return bdev_flush((short)param0);
|
||||
|
||||
case KFN_BDEV_STATUS:
|
||||
return bdev_status((short)param0);
|
||||
|
||||
case KFN_BDEV_IOCTRL:
|
||||
return bdev_ioctrl((short)param0, (short)param1, (unsigned char *)param2, (short)param3);
|
||||
|
||||
case KFN_BDEV_REGISTER:
|
||||
return bdev_register((p_dev_block)param0);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x30:
|
||||
/* File System Calls */
|
||||
switch (function) {
|
||||
case KFN_OPEN:
|
||||
return fsys_open((const char *)param0, (short)param1);
|
||||
|
||||
case KFN_CLOSE:
|
||||
return fsys_close((short)param0);
|
||||
|
||||
case KFN_OPENDIR:
|
||||
return fsys_opendir((const char *)param0);
|
||||
|
||||
case KFN_CLOSEDIR:
|
||||
return fsys_closedir((short)param0);
|
||||
|
||||
case KFN_READDIR:
|
||||
return fsys_readdir((short)param0, (p_file_info)param1);
|
||||
|
||||
case KFN_FINDFIRST:
|
||||
return fsys_findfirst((const char *)param0, (const char *)param1, (p_file_info)param2);
|
||||
|
||||
case KFN_FINDNEXT:
|
||||
return fsys_findnext((short)param0, (p_file_info)param1);
|
||||
|
||||
case KFN_DELETE:
|
||||
return fsys_delete((const char *)param0);
|
||||
|
||||
case KFN_RENAME:
|
||||
return fsys_rename((const char *)param0, (const char *)param1);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG("syscall unknown function\n");
|
||||
do {} while (1);
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
DEBUG("syscall unknown function\n");
|
||||
do {} while (1);
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -51,9 +51,9 @@
|
|||
dc.l not_impl ; 42 - TRAP #10
|
||||
dc.l not_impl ; 43 - TRAP #11
|
||||
dc.l not_impl ; 44 - TRAP #12
|
||||
dc.l h_trap_13 ; 45 - TRAP #13
|
||||
dc.l not_impl ; 45 - TRAP #13
|
||||
dc.l not_impl ; 46 - TRAP #14
|
||||
dc.l not_impl ; 47 - TRAP #15
|
||||
dc.l h_trap_15 ; 47 - TRAP #15
|
||||
dc.l not_impl ; 48 - Reserved
|
||||
dc.l not_impl ; 49 - Reserved
|
||||
dc.l not_impl ; 50 - Reserved
|
||||
|
@ -120,7 +120,7 @@ clrloop: clr.l (a0)+
|
|||
bne clrloop
|
||||
|
||||
; Set TRAP #13 vector handler
|
||||
lea h_trap_13,a0 ; Address of the handler
|
||||
lea h_trap_15,a0 ; Address of the handler
|
||||
move.l #(13+32)<<2,a1 ; TRAP#13 vector address
|
||||
move.l a0,(a1) ; Set the vector
|
||||
|
||||
|
@ -214,31 +214,31 @@ _int_disable_all: ori.w #$0700,SR
|
|||
;
|
||||
_syscall:
|
||||
movem.l d1-d7,-(sp) ; Save caller's registers
|
||||
move.l (56,sp),d7 ; Parameter 5 to D7
|
||||
move.l (52,sp),d6 ; Parameter 4 to D6
|
||||
move.l (48,sp),d5 ; Parameter 3 to D5
|
||||
move.l (44,sp),d4 ; Parameter 2 to D4
|
||||
move.l (40,sp),d3 ; Parameter 1 to D3
|
||||
move.l (36,sp),d2 ; Parameter 0 to D2
|
||||
move.l (32,sp),d1 ; Function number to D1
|
||||
move.l (56,sp),d6 ; Parameter 5 to D6
|
||||
move.l (52,sp),d5 ; Parameter 4 to D5
|
||||
move.l (48,sp),d4 ; Parameter 3 to D4
|
||||
move.l (44,sp),d3 ; Parameter 2 to D3
|
||||
move.l (40,sp),d2 ; Parameter 1 to D2
|
||||
move.l (36,sp),d1 ; Parameter 0 to D1
|
||||
move.l (32,sp),d0 ; Function number to D0
|
||||
|
||||
TRAP #13 ; Call into the kernel
|
||||
TRAP #15 ; Call into the kernel
|
||||
|
||||
movem.l (sp)+,d1-d7 ; Restore caller's registers
|
||||
rts
|
||||
|
||||
|
||||
;
|
||||
; TRAP#13 handler... transfer control to the C dispatcher
|
||||
; TRAP#15 handler... transfer control to the C dispatcher
|
||||
;
|
||||
h_trap_13:
|
||||
move.l d7,-(sp) ; Push the parameters to the stack for the C call
|
||||
move.l d6,-(sp)
|
||||
h_trap_15:
|
||||
move.l d6,-(sp) ; Push the parameters to the stack for the C call
|
||||
move.l d5,-(sp)
|
||||
move.l d4,-(sp)
|
||||
move.l d3,-(sp)
|
||||
move.l d2,-(sp)
|
||||
move.l d1,-(sp)
|
||||
move.l d0,-(sp)
|
||||
|
||||
jsr _syscall_dispatch ; Call the C routine to do the dispatch
|
||||
; Note: the C routine depends upon the register push order
|
||||
|
|
7165
src/mapfile
7165
src/mapfile
File diff suppressed because it is too large
Load diff
248
src/syscalls.c
248
src/syscalls.c
|
@ -1,4 +1,90 @@
|
|||
#include "syscalls.h"
|
||||
#include "interrupt.h"
|
||||
#include "dev/channel.h"
|
||||
#include "dev/block.h"
|
||||
|
||||
/***
|
||||
*** Core system calls
|
||||
***/
|
||||
|
||||
/*
|
||||
* Enable all interrupts
|
||||
*
|
||||
* NOTE: this is actually provided in the low level assembly
|
||||
*/
|
||||
void sys_int_enable_all() {
|
||||
syscall(KFN_INT_ENABLE_ALL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable all interrupts
|
||||
*
|
||||
* NOTE: this is actually provided in the low level assembly
|
||||
*/
|
||||
void sys_int_disable_all() {
|
||||
syscall(KFN_INT_DISABLE_ALL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable an interrupt by masking it
|
||||
*
|
||||
* Inputs:
|
||||
* n = the number of the interrupt: n[7..4] = group number, n[3..0] = individual number.
|
||||
*/
|
||||
void sys_int_disable(unsigned short n) {
|
||||
syscall(KFN_INT_DISABLE, n);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable an interrupt
|
||||
*
|
||||
* Inputs:
|
||||
* n = the number of the interrupt
|
||||
*/
|
||||
void sys_int_enable(unsigned short n) {
|
||||
syscall(KFN_INT_ENABLE, n);
|
||||
}
|
||||
|
||||
/*
|
||||
* Register a handler for a given interrupt.
|
||||
*
|
||||
* Inputs:
|
||||
* n = the number of the interrupt
|
||||
* handler = pointer to the interrupt handler to register
|
||||
*
|
||||
* Returns:
|
||||
* the pointer to the previous interrupt handler
|
||||
*/
|
||||
p_int_handler sys_int_register(unsigned short n, p_int_handler handler) {
|
||||
return (p_int_handler)syscall(KFN_INT_REGISTER, n, handler);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true (non-zero) if an interrupt is pending for the given interrupt
|
||||
*
|
||||
* Inputs:
|
||||
* n = the number of the interrupt: n[7..4] = group number, n[3..0] = individual number.
|
||||
*
|
||||
* Returns:
|
||||
* non-zero if interrupt n is pending, 0 if not
|
||||
*/
|
||||
short sys_int_pending(unsigned short n) {
|
||||
return syscall(KFN_INT_PENDING, n);
|
||||
}
|
||||
|
||||
/*
|
||||
* Acknowledge an interrupt (clear out its pending flag)
|
||||
*
|
||||
* Inputs:
|
||||
* n = the number of the interrupt: n[7..4] = group number, n[3..0] = individual number.
|
||||
*/
|
||||
void sys_int_clear(unsigned short n) {
|
||||
syscall(KFN_INT_CLEAR, n);
|
||||
}
|
||||
|
||||
/***
|
||||
*** Channel system calls
|
||||
***/
|
||||
|
||||
/*
|
||||
* Read a single byte from the channel
|
||||
|
@ -44,16 +130,16 @@ short sys_chan_readline(short channel, unsigned char * buffer, short size) {
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write a single byte to the device
|
||||
*
|
||||
* Inputs:
|
||||
* channel = the number of the channel
|
||||
* b = the byte to write
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success, a negative value on error
|
||||
*/
|
||||
/*
|
||||
* Write a single byte to the device
|
||||
*
|
||||
* Inputs:
|
||||
* channel = the number of the channel
|
||||
* b = the byte to write
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success, a negative value on error
|
||||
*/
|
||||
short sys_chan_write_b(short channel, unsigned char b) {
|
||||
return syscall(KFN_CHAN_WRITE_B, channel);
|
||||
}
|
||||
|
@ -71,3 +157,145 @@ short sys_chan_write_b(short channel, unsigned char b) {
|
|||
short sys_chan_write(short channel, unsigned char * buffer, short size) {
|
||||
return syscall(KFN_CHAN_WRITE, channel, buffer, size);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the status of the channel device
|
||||
*
|
||||
* Inputs:
|
||||
* channel = the number of the channel
|
||||
*
|
||||
* Returns:
|
||||
* the status of the device
|
||||
*/
|
||||
short sys_chan_status(short channel) {
|
||||
return syscall(KFN_CHAN_STATUS, channel);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure that any pending writes to teh device have been completed
|
||||
*
|
||||
* Inputs:
|
||||
* channel = the number of the channel
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success, any negative number is an error code
|
||||
*/
|
||||
short sys_chan_flush(short channel) {
|
||||
return syscall(KFN_CHAN_FLUSH, 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.
|
||||
*/
|
||||
short sys_chan_seek(short channel, long position, short base) {
|
||||
return syscall(KFN_CHAN_SEEK, channel, position, base);
|
||||
}
|
||||
|
||||
/*
|
||||
* Issue a control command to the device
|
||||
*
|
||||
* Inputs:
|
||||
* channel = the number of the channel
|
||||
* command = the number of the command to send
|
||||
* buffer = pointer to bytes of additional data for the command
|
||||
* size = the size of the buffer
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success, any negative number is an error code
|
||||
*/
|
||||
short sys_chan_ioctrl(short channel, short command, uint8_t * buffer, short size) {
|
||||
return syscall(KFN_CHAN_IOCTRL, channel, command, buffer, size);
|
||||
}
|
||||
|
||||
/***
|
||||
*** Block device system calls
|
||||
***/
|
||||
|
||||
//
|
||||
// Register a block device driver
|
||||
//
|
||||
short sys_bdev_register(p_dev_block device) {
|
||||
return syscall(KFN_BDEV_REGISTER, device);
|
||||
}
|
||||
|
||||
//
|
||||
// Read a block from the device
|
||||
//
|
||||
// Inputs:
|
||||
// dev = the number of the device
|
||||
// lba = the logical block address of the block to read
|
||||
// buffer = the buffer into which to copy the block data
|
||||
// size = the size of the buffer.
|
||||
//
|
||||
// Returns:
|
||||
// number of bytes read, any negative number is an error code
|
||||
//
|
||||
short sys_bdev_read(short dev, long lba, unsigned char * buffer, short size) {
|
||||
return syscall(KFN_BDEV_GETBLOCK, dev, lba, buffer, size);
|
||||
}
|
||||
|
||||
//
|
||||
// Write a block from the device
|
||||
//
|
||||
// Inputs:
|
||||
// dev = the number of the device
|
||||
// lba = the logical block address of the block to write
|
||||
// buffer = the buffer containing the data to write
|
||||
// size = the size of the buffer.
|
||||
//
|
||||
// Returns:
|
||||
// number of bytes written, any negative number is an error code
|
||||
//
|
||||
short sys_bdev_write(short dev, long lba, const unsigned char * buffer, short size) {
|
||||
return syscall(KFN_BDEV_PUTBLOCK, dev, lba, buffer, size);
|
||||
}
|
||||
|
||||
//
|
||||
// Return the status of the block device
|
||||
//
|
||||
// Inputs:
|
||||
// dev = the number of the device
|
||||
//
|
||||
// Returns:
|
||||
// the status of the device
|
||||
//
|
||||
short sys_bdev_status(short dev) {
|
||||
return syscall(KFN_BDEV_STATUS, dev);
|
||||
}
|
||||
|
||||
//
|
||||
// Ensure that any pending writes to teh device have been completed
|
||||
//
|
||||
// Inputs:
|
||||
// dev = the number of the device
|
||||
//
|
||||
// Returns:
|
||||
// 0 on success, any negative number is an error code
|
||||
//
|
||||
short sys_bdev_flush(short dev) {
|
||||
return syscall(KFN_BDEV_FLUSH, dev);
|
||||
}
|
||||
|
||||
//
|
||||
// Issue a control command to the device
|
||||
//
|
||||
// Inputs:
|
||||
// dev = the number of the device
|
||||
// command = the number of the command to send
|
||||
// buffer = pointer to bytes of additional data for the command
|
||||
// size = the size of the buffer
|
||||
//
|
||||
// Returns:
|
||||
// 0 on success, any negative number is an error code
|
||||
//
|
||||
short sys_bdev_ioctrl(short dev, short command, unsigned char * buffer, short size) {
|
||||
return syscall(KFN_BDEV_IOCTRL, dev, command, buffer, size);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue