Interrupts and Jiffies

Fixed some interrupt issues on the U and converted the TICKS millisecond timer to be a jiffy (1/60s) timer based on the SOF interrupt. There are still some issue managing the RTC periodic interrupt.
This commit is contained in:
Peter Weingartner 2021-11-08 15:39:32 -05:00
parent c8c8aca1c6
commit 002b7decf0
27 changed files with 9541 additions and 9509 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -111,7 +111,7 @@ short cmd_getjiffies(short channel, int argc, char * argv[]) {
short cmd_get_ticks(short channel, int argc, char * argv[]) { short cmd_get_ticks(short channel, int argc, char * argv[]) {
char buffer[80]; char buffer[80];
sprintf(buffer, "%d\n", rtc_get_ticks()); sprintf(buffer, "%d\n", rtc_get_jiffies());
sys_chan_write(channel, buffer, strlen(buffer)); sys_chan_write(channel, buffer, strlen(buffer));
return 0; return 0;
} }

View file

@ -273,13 +273,13 @@ short cli_rtc_set(short channel, const char * value) {
char message[80]; char message[80];
if (strcmp(value, "1") == 0) { if (strcmp(value, "1") == 0) {
unsigned char flags = *RTC_FLAGS; rtc_enable_ticks();
*RTC_ENABLES = RTC_PIE;
int_enable(INT_RTC);
sprintf(message, "RTC interrupt enabled.\n"); sprintf(message, "RTC interrupt enabled.\n");
} else if (strcmp(value, "0") == 0) { } else if (strcmp(value, "0") == 0) {
int_disable(INT_RTC); int_disable(INT_RTC);
sprintf(message, "RTC interrupt disabled.\n"); sprintf(message, "RTC interrupt disabled.\n");
} else { } else {
sprintf(message, "USAGE: SET RTC 0|1\n"); sprintf(message, "USAGE: SET RTC 0|1\n");
} }
@ -471,8 +471,8 @@ void cli_set_init() {
cli_last_setting = 0; cli_last_setting = 0;
cli_set_register("DATE", "DATE yyyy-mm-dd -- set the date in the realtime clock", cli_date_set, cli_date_get); cli_set_register("DATE", "DATE yyyy-mm-dd -- set the date in the realtime clock", cli_date_set, cli_date_get);
cli_set_register("RTC", "RTC 1|0 -- Enable or disable the realtime clock interrupt", cli_rtc_set, cli_rtc_get); // cli_set_register("RTC", "RTC 1|0 -- Enable or disable the realtime clock interrupt", cli_rtc_set, cli_rtc_get);
cli_set_register("SOF", "SOF 1|0 -- Enable or disable the Start of Frame interrupt", cli_sof_set, cli_sof_get); // cli_set_register("SOF", "SOF 1|0 -- Enable or disable the Start of Frame interrupt", cli_sof_set, cli_sof_get);
cli_set_register("TIME", "TIME HH:MM:SS -- set the time in the realtime clock", cli_time_set, cli_time_get); cli_set_register("TIME", "TIME HH:MM:SS -- set the time in the realtime clock", cli_time_set, cli_time_get);
cli_set_register("FONT", "FONT <path> -- set a font for the display", cli_font_set, cli_font_get); cli_set_register("FONT", "FONT <path> -- set a font for the display", cli_font_set, cli_font_get);
cli_set_register("VOLUME", "VOLUME <0 - 255> -- set the master volume", cli_volume_set, cli_volume_get); cli_set_register("VOLUME", "VOLUME <0 - 255> -- set the master volume", cli_volume_set, cli_volume_get);

View file

@ -19,20 +19,20 @@ short psg_test(short channel, int argc, char * argv[]) {
psg_tone(0, 34923); psg_tone(0, 34923);
psg_attenuation(0, 0); psg_attenuation(0, 0);
target_time = rtc_get_ticks() + 300; target_time = sys_time_jiffies() + 6;
while (target_time > rtc_get_ticks()) ; while (target_time > sys_time_jiffies()) ;
psg_tone(1, 44000); psg_tone(1, 44000);
psg_attenuation(1, 0); psg_attenuation(1, 0);
target_time = rtc_get_ticks() + 300; target_time = sys_time_jiffies() + 6;
while (target_time > rtc_get_ticks()) ; while (target_time > sys_time_jiffies()) ;
psg_tone(2, 52325); psg_tone(2, 52325);
psg_attenuation(2, 0); psg_attenuation(2, 0);
target_time = rtc_get_ticks() + 1000; target_time = sys_time_jiffies() + 60;
while (target_time > rtc_get_ticks()) ; while (target_time > sys_time_jiffies()) ;
psg_attenuation(0, 15); psg_attenuation(0, 15);
psg_tone(0, 0); psg_tone(0, 0);
@ -110,8 +110,8 @@ short opl3_test(short channel, int argc, char * argv[]) {
} }
} }
target_time = rtc_get_ticks() + 1000; target_time = sys_time_jiffies() + 60;
while (target_time > rtc_get_ticks()) ; while (target_time > sys_time_jiffies()) ;
i = 0; i = 0;
while (1) { while (1) {
@ -492,8 +492,8 @@ short opl2_test(short channel, int argc, char * argv[]) {
OPN2_INT_BASE[OPN2_28_KEY_ON_OFF] = i; OPN2_INT_BASE[OPN2_28_KEY_ON_OFF] = i;
} }
long target_ticks = rtc_get_ticks(); long target_ticks = sys_time_jiffies();
while (target_ticks > rtc_get_ticks() + 300) ; while (target_ticks > sys_time_jiffies() + 300) ;
for (i = 0x00; i < 0x07; i++) { for (i = 0x00; i < 0x07; i++) {
OPN2_INT_BASE[OPN2_28_KEY_ON_OFF] = i; OPN2_INT_BASE[OPN2_28_KEY_ON_OFF] = i;

View file

@ -121,19 +121,19 @@ short cli_test_rtc(short channel, int argc, char * argv[]) {
*RTC_ENABLES = RTC_PIE; /* Turn on the periodic interrupt */ *RTC_ENABLES = RTC_PIE; /* Turn on the periodic interrupt */
int_enable(INT_RTC); int_enable(INT_RTC);
ticks = rtc_get_ticks(); ticks = sys_time_jiffies();
sprintf(buffer, "Waiting for updated ticks starting from %d\n", ticks); sprintf(buffer, "Waiting for updated ticks starting from %d\n", ticks);
sys_chan_write(channel, buffer, strlen(buffer)); sys_chan_write(channel, buffer, strlen(buffer));
while (1) { while (1) {
if (ticks < rtc_get_ticks()) { if (ticks < sys_time_jiffies()) {
/* We got the periodic interrupt */ /* We got the periodic interrupt */
sprintf(buffer, "Tick! %d\n", ticks); sprintf(buffer, "Tick! %d\n", ticks);
sys_chan_write(channel, buffer, strlen(buffer)); sys_chan_write(channel, buffer, strlen(buffer));
ticks = rtc_get_ticks(); ticks = sys_time_jiffies();
} }
} }
} }
@ -333,7 +333,6 @@ static t_cli_test_feature cli_test_features[] = {
{"CREATE", "CREATE <path>: test creating a file", cli_test_create}, {"CREATE", "CREATE <path>: test creating a file", cli_test_create},
{"IDE", "IDE: test reading the MBR of the IDE drive", cli_test_ide}, {"IDE", "IDE: test reading the MBR of the IDE drive", cli_test_ide},
{"PANIC", "PANIC: test the kernel panic mechanism", cli_test_panic}, {"PANIC", "PANIC: test the kernel panic mechanism", cli_test_panic},
{"RTC", "RTC: test the real time clock periodic interrupt", cli_test_rtc},
{"LPT", "LPT: test the parallel port", cli_test_lpt}, {"LPT", "LPT: test the parallel port", cli_test_lpt},
{"MEM", "MEM: test reading and writing memory", cli_mem_test}, {"MEM", "MEM: test reading and writing memory", cli_mem_test},
{"MIDILOOP", "MIDILOOP: perform a loopback test on the MIDI ports", midi_loop_test}, {"MIDILOOP", "MIDILOOP: perform a loopback test on the MIDI ports", midi_loop_test},

View file

@ -17,8 +17,8 @@
// Constants // Constants
// //
#define PATA_TIMEOUT_MS 300 #define PATA_TIMEOUT_JF 20 /* Timeout in jiffies: 1/60th second */
#define PATA_WAIT_MS 100 #define PATA_WAIT_JF 10 /* Delay in jiffies: 1/60th second */
// //
// Variables // Variables
@ -44,10 +44,10 @@ short pata_wait_not_busy() {
TRACE("pata_wait_not_busy"); TRACE("pata_wait_not_busy");
target_ticks = rtc_get_ticks() + PATA_TIMEOUT_MS; target_ticks = rtc_get_jiffies() + PATA_TIMEOUT_JF;
do { do {
status = *PATA_CMD_STAT; status = *PATA_CMD_STAT;
ticks = rtc_get_ticks(); ticks = rtc_get_jiffies();
} while ((status & PATA_STAT_BSY) && (target_ticks > ticks)); } while ((status & PATA_STAT_BSY) && (target_ticks > ticks));
if (target_ticks <= ticks) { if (target_ticks <= ticks) {
@ -73,10 +73,10 @@ short pata_wait_ready() {
TRACE("pata_wait_ready"); TRACE("pata_wait_ready");
target_ticks = rtc_get_ticks() + PATA_TIMEOUT_MS; target_ticks = rtc_get_jiffies() + PATA_TIMEOUT_JF;
do { do {
status = *PATA_CMD_STAT; status = *PATA_CMD_STAT;
ticks = rtc_get_ticks(); ticks = rtc_get_jiffies();
} while (((status & PATA_STAT_DRDY) == 0) && (target_ticks > ticks)); } while (((status & PATA_STAT_DRDY) == 0) && (target_ticks > ticks));
if (target_ticks <= ticks) { if (target_ticks <= ticks) {
@ -104,10 +104,10 @@ short pata_wait_ready_not_busy() {
// status = *PATA_CMD_STAT; // status = *PATA_CMD_STAT;
// } while (((status & (PATA_STAT_DRDY | PATA_STAT_BSY)) != PATA_STAT_DRDY) && (count-- > 0)); // } while (((status & (PATA_STAT_DRDY | PATA_STAT_BSY)) != PATA_STAT_DRDY) && (count-- > 0));
target_ticks = rtc_get_ticks() + PATA_TIMEOUT_MS; target_ticks = rtc_get_jiffies() + PATA_TIMEOUT_JF;
do { do {
while (((*PATA_CMD_STAT & PATA_STAT_DRDY) != PATA_STAT_DRDY) && (target_ticks > ticks)) { while (((*PATA_CMD_STAT & PATA_STAT_DRDY) != PATA_STAT_DRDY) && (target_ticks > ticks)) {
ticks = rtc_get_ticks(); ticks = rtc_get_jiffies();
} }
} while (((*PATA_CMD_STAT & PATA_STAT_BSY) == PATA_STAT_BSY) && (target_ticks > ticks)); } while (((*PATA_CMD_STAT & PATA_STAT_BSY) == PATA_STAT_BSY) && (target_ticks > ticks));
@ -134,10 +134,10 @@ short pata_wait_data_request() {
TRACE("pata_wait_data_request"); TRACE("pata_wait_data_request");
target_ticks = rtc_get_ticks() + PATA_TIMEOUT_MS; target_ticks = rtc_get_jiffies() + PATA_TIMEOUT_JF;
do { do {
status = *PATA_CMD_STAT; status = *PATA_CMD_STAT;
ticks = rtc_get_ticks(); ticks = rtc_get_jiffies();
} while (((status & PATA_STAT_DRQ) != PATA_STAT_DRQ) && (target_ticks > ticks)); } while (((status & PATA_STAT_DRQ) != PATA_STAT_DRQ) && (target_ticks > ticks));
if (target_ticks <= ticks) { if (target_ticks <= ticks) {
@ -345,8 +345,8 @@ short pata_flush_cache() {
*PATA_CMD_STAT = 0xE7; // PATA_CMD_FLUSH_CACHE; *PATA_CMD_STAT = 0xE7; // PATA_CMD_FLUSH_CACHE;
// Give the controller some time (100ms?)... // Give the controller some time (100ms?)...
target_ticks = rtc_get_ticks() + PATA_WAIT_MS; target_ticks = rtc_get_jiffies() + PATA_WAIT_JF;
while (target_ticks > rtc_get_ticks()) ; while (target_ticks > rtc_get_jiffies()) ;
if (pata_wait_ready_not_busy()) { if (pata_wait_ready_not_busy()) {
return DEV_TIMEOUT; return DEV_TIMEOUT;
@ -411,8 +411,8 @@ short pata_write(long lba, const unsigned char * buffer, short size) {
*PATA_CMD_STAT = PATA_CMD_WRITE_SECTOR; // Issue the WRITE command *PATA_CMD_STAT = PATA_CMD_WRITE_SECTOR; // Issue the WRITE command
// Give the controller some time (100ms?)... // Give the controller some time (100ms?)...
target_ticks = rtc_get_ticks() + PATA_WAIT_MS; target_ticks = rtc_get_jiffies() + PATA_WAIT_JF;
while (target_ticks > rtc_get_ticks()) ; while (target_ticks > rtc_get_jiffies()) ;
if (pata_wait_ready_not_busy()) { if (pata_wait_ready_not_busy()) {
/* Turn off the HDD LED */ /* Turn off the HDD LED */

View file

@ -12,7 +12,7 @@
#include "dev/text_screen_iii.h" #include "dev/text_screen_iii.h"
#include "rsrc/bitmaps/mouse_pointer.h" #include "rsrc/bitmaps/mouse_pointer.h"
#define PS2_TIMEOUT_MS 400 #define PS2_TIMEOUT_JF 10 /* Timeout in jiffies: 1/60 second units */
#define PS2_RESEND_MAX 50 /* Number of times we'll repeat a command on receiving a 0xFE reply */ #define PS2_RESEND_MAX 50 /* Number of times we'll repeat a command on receiving a 0xFE reply */
/* /*
@ -257,9 +257,9 @@ short ps2_wait_out() {
log(LOG_TRACE, "ps2_wait_out"); log(LOG_TRACE, "ps2_wait_out");
target_ticks = rtc_get_ticks() + PS2_TIMEOUT_MS; target_ticks = rtc_get_jiffies() + PS2_TIMEOUT_JF;
while ((*PS2_STATUS & PS2_STAT_OBF) == 0) { while ((*PS2_STATUS & PS2_STAT_OBF) == 0) {
if (rtc_get_ticks() > target_ticks) { if (rtc_get_jiffies() > target_ticks) {
return -1; return -1;
} }
} }
@ -278,9 +278,9 @@ short ps2_wait_in() {
log(LOG_TRACE, "ps2_wait_in"); log(LOG_TRACE, "ps2_wait_in");
target_ticks = rtc_get_ticks() + PS2_TIMEOUT_MS; target_ticks = rtc_get_jiffies() + PS2_TIMEOUT_JF;
while ((*PS2_STATUS & PS2_STAT_IBF) != 0) { while ((*PS2_STATUS & PS2_STAT_IBF) != 0) {
if (rtc_get_ticks() > target_ticks) { if (rtc_get_jiffies() > target_ticks) {
return -1; return -1;
} }
} }

View file

@ -7,6 +7,7 @@
#include "gabe_reg.h" #include "gabe_reg.h"
#include "rtc.h" #include "rtc.h"
#include "rtc_reg.h" #include "rtc_reg.h"
#include "timers.h"
static long rtc_ticks; static long rtc_ticks;
@ -16,11 +17,8 @@ static long rtc_ticks;
void rtc_handle_int() { void rtc_handle_int() {
unsigned char flags; unsigned char flags;
flags = *RTC_FLAGS; /* Periodic interrupt: increment the ticks counter */
/* Peridic interrupt: increment the ticks counter */
rtc_ticks++; rtc_ticks++;
int_clear(INT_RTC);
} }
/* /*
@ -35,27 +33,38 @@ void rtc_init() {
int_disable(INT_RTC); int_disable(INT_RTC);
/* Set the periodic interrupt to 976 microsecs */
*RTC_RATES = RTC_RATE_976us;
/* Make sure the RTC is on */ /* Make sure the RTC is on */
*RTC_CTRL = RTC_STOP; *RTC_CTRL = RTC_STOP;
int_register(INT_RTC, rtc_handle_int); /*
* For the moment: Every so often, the RTC interrupt gets acknowledged
* without clearing the flags. Until I can sort out why, I will use
* the SOF A interrupt as a surrogate for the RTC jiffie timer
*/
// /* Set the periodic interrupt to 15 millisecs */
// *RTC_RATES = RTC_RATE_15ms;
// int_register(INT_RTC, rtc_handle_int);
/* Enable the periodic interrupt */ /* Enable the periodic interrupt */
flags = *RTC_FLAGS; // flags = *RTC_FLAGS;
*RTC_ENABLES = RTC_PIE; // *RTC_ENABLES = RTC_PIE;
int_enable(INT_RTC); // int_enable(INT_RTC);
} }
/* /*
* Make sure the RTC tick counter is enabled * Make sure the RTC tick counter is enabled
*/ */
void rtc_enable_ticks() { void rtc_enable_ticks() {
/* Set the periodic interrupt to 15 millisecs */
*RTC_RATES = RTC_RATE_15ms;
unsigned char flags = *RTC_FLAGS; unsigned char flags = *RTC_FLAGS;
*RTC_ENABLES = RTC_PIE; *RTC_ENABLES = RTC_PIE;
int_enable(INT_RTC); int_enable(INT_RTC);
} }
@ -213,16 +222,15 @@ void rtc_get_time(p_time time) {
} }
/* /*
* Get the number of ticks since the system last booted. * Get the number of jiffies since the system last booted.
* *
* NOTE: a tick is almost, but not quite, 1ms. The RTC periodic interrupt * NOTE: a jiffie is 1/60 of a second. This timer will not be
* period does not line up with a 1ms timer, but it comes close. * 100% precise, so it should be used for timeout purposes
* Therefore, a tick will be 976.5625 microseconds... a little faster * where precision is not critical.
* than 1ms.
* *
* Returns: * Returns:
* the number of ticks since the last reset * the number of jiffies since the last reset
*/ */
long rtc_get_ticks() { long rtc_get_jiffies() {
return rtc_ticks; return timers_jiffies();
} }

View file

@ -43,16 +43,15 @@ extern void rtc_set_time(p_time time);
extern void rtc_get_time(p_time time); extern void rtc_get_time(p_time time);
/* /*
* Get the number of ticks since the system last booted. * Get the number of jiffies since the system last booted.
* *
* NOTE: a tick is almost, but not quite, 1ms. The RTC periodic interrupt * NOTE: a jiffie is 1/60 of a second. This timer will not be
* period does not line up with a 1ms timer, but it comes close. * 100% precise, so it should be used for timeout purposes
* Therefore, a tick will be 976.5625 microseconds... a little faster * where precision is not critical.
* than 1ms.
* *
* Returns: * Returns:
* the number of ticks since the last reset * the number of jiffies since the last reset
*/ */
extern long rtc_get_ticks(); extern long rtc_get_jiffies();
#endif #endif

View file

@ -17,7 +17,7 @@
// Constants // Constants
// //
#define SDC_TIMEOUT_MS 300 #define SDC_TIMEOUT_JF 20 /* Timeout in jiffies (1/60 second) */
unsigned char g_sdc_status = SDC_STAT_NOINIT; unsigned char g_sdc_status = SDC_STAT_NOINIT;
unsigned char g_sdc_error = 0; unsigned char g_sdc_error = 0;
@ -77,9 +77,9 @@ short sdc_wait_busy() {
int retry_count = MAX_TRIES_BUSY; int retry_count = MAX_TRIES_BUSY;
unsigned char status; unsigned char status;
timer_ticks = rtc_get_ticks() + SDC_TIMEOUT_MS; timer_ticks = rtc_get_jiffies() + SDC_TIMEOUT_JF;
do { do {
if (rtc_get_ticks() > timer_ticks) { if (rtc_get_jiffies() > timer_ticks) {
// If we have run out of tries, return a TIMEOUT error // If we have run out of tries, return a TIMEOUT error
return DEV_TIMEOUT; return DEV_TIMEOUT;
} }

View file

@ -135,11 +135,12 @@ void load_splashscreen() {
/* Display the splashscreen: 640x480 */ /* Display the splashscreen: 640x480 */
*MasterControlReg_A = VKY3_MCR_GRAPH_EN | VKY3_MCR_BITMAP_EN; *MasterControlReg_A = VKY3_MCR_GRAPH_EN | VKY3_MCR_BITMAP_EN;
target_ticks = rtc_get_jiffies() + 300;
/* Play the SID test bong on the Gideon SID implementation */ /* Play the SID test bong on the Gideon SID implementation */
sid_test_internal(); sid_test_internal();
target_ticks = rtc_get_ticks() + 10000; while (target_ticks > rtc_get_jiffies()) ;
while (target_ticks > rtc_get_ticks()) ;
/* Initialize the text channels */ /* Initialize the text channels */
text_init(); text_init();
@ -201,15 +202,15 @@ void initialize() {
log(LOG_INFO, "Console installed."); log(LOG_INFO, "Console installed.");
} }
/* Initialize the timers the MCP uses */
timers_init();
/* Initialize the real time clock */ /* Initialize the real time clock */
rtc_init(); rtc_init();
/* Enable all interrupts */ /* Enable all interrupts */
int_enable_all(); int_enable_all();
/* Make sure the RTC tick counter is going */
rtc_enable_ticks();
/* Display the splash screen */ /* Display the splash screen */
load_splashscreen(); load_splashscreen();
@ -252,8 +253,6 @@ void initialize() {
} else { } else {
log(LOG_INFO, "File system initialized."); log(LOG_INFO, "File system initialized.");
} }
int_disable(INT_RTC);
} }
int main(int argc, char * argv[]) { int main(int argc, char * argv[]) {

File diff suppressed because it is too large Load diff

Binary file not shown.

View file

@ -53,6 +53,9 @@
#define RTC_RATES_WD 0xf0 #define RTC_RATES_WD 0xf0
#define RTC_RATES_RS 0x0f #define RTC_RATES_RS 0x0f
#define RTC_RATE_976us 0x06 #define RTC_RATE_976us 0x06
#define RTC_RATE_4ms 0x04
#define RTC_RATE_15ms 0x0A
/* Enable bits */ /* Enable bits */
#define RTC_AIE 0x08 #define RTC_AIE 0x08

View file

@ -80,7 +80,7 @@
/* Misc calls */ /* Misc calls */
#define KFN_TIME_TICKS 0x50 /* Gets the current time code (increments since boot) */ #define KFN_TIME_JIFFIES 0x50 /* Gets the current time code (increments since boot) */
#define KFN_TIME_SETRTC 0x51 /* Set the real time clock date-time */ #define KFN_TIME_SETRTC 0x51 /* Set the real time clock date-time */
#define KFN_TIME_GETRTC 0x52 /* Get the real time clock date-time */ #define KFN_TIME_GETRTC 0x52 /* Get the real time clock date-time */
#define KFN_KBD_SCANCODE 0x53 /* Get the next scan code from the keyboard */ #define KFN_KBD_SCANCODE 0x53 /* Get the next scan code from the keyboard */
@ -578,17 +578,16 @@ extern short sys_fsys_register_loader(const char * extension, p_file_loader load
*/ */
/* /*
* Get the number of ticks since the system last booted. * Get the number of jiffies since the system last booted.
* *
* NOTE: a tick is almost, but not quite, 1ms. The RTC periodic interrupt * NOTE: a jiffie is 1/60 of a second. This timer will not be
* period does not line up with a 1ms timer, but it comes close. * 100% precise, so it should be used for timeout purposes
* Therefore, a tick will be 976.5625 microseconds... a little faster * where precision is not critical.
* than 1ms.
* *
* Returns: * Returns:
* the number of ticks since the last reset * the number of jiffies since the last reset
*/ */
extern long sys_rtc_get_ticks(); extern long sys_time_jiffies();
/* /*
* Set the time on the RTC * Set the time on the RTC

View file

@ -157,16 +157,18 @@ void int_vicky_channel_a() {
unsigned short mask = 1; unsigned short mask = 1;
unsigned short pending = *PENDING_GRP0 & 0xff; unsigned short pending = *PENDING_GRP0 & 0xff;
/* Acknowledge all the pending interrupts:
* NOTE: we have to do this, even if there is no handler for the interrupt */
*PENDING_GRP0 = 0x00ff;
if (pending != 0) { if (pending != 0) {
for (n = 0; n < 8; n++) { for (n = 0; n < 8; n++) {
if (pending & mask) { if (pending & mask) {
p_int_handler handler = g_int_handler[n]; p_int_handler handler = g_int_handler[n];
if (handler) { if (handler) {
/* If we got a handler, call it */ /* If we got a handler, call it */
handler(); handler();
/* And acknowledge the interrupt */
int_clear(n);
} }
} }
@ -184,6 +186,10 @@ void int_vicky_channel_b() {
unsigned short mask = 1; unsigned short mask = 1;
unsigned short pending = (*PENDING_GRP0 >> 8) & 0xff; unsigned short pending = (*PENDING_GRP0 >> 8) & 0xff;
/* Acknowledge all the pending interrupts:
* NOTE: we have to do this, even if there is no handler for the interrupt */
*PENDING_GRP0 = 0xff00;
if (pending != 0) { if (pending != 0) {
for (n = 8; n < 16; n++) { for (n = 8; n < 16; n++) {
if (pending & mask) { if (pending & mask) {
@ -191,9 +197,6 @@ void int_vicky_channel_b() {
if (handler) { if (handler) {
/* If we got a handler, call it */ /* If we got a handler, call it */
handler(); handler();
/* And acknowledge the interrupt */
int_clear(n);
} }
} }

View file

@ -193,8 +193,8 @@ unsigned long syscall_dispatch(int32_t function, int32_t param0, int32_t param1,
case 0x50: case 0x50:
/* Misc functions */ /* Misc functions */
switch (function) { switch (function) {
case KFN_TIME_TICKS: case KFN_TIME_JIFFIES:
return rtc_get_ticks(); return rtc_get_jiffies();
case KFN_TIME_SETRTC: case KFN_TIME_SETRTC:
rtc_set_time((p_time)param0); rtc_set_time((p_time)param0);

View file

@ -10,6 +10,13 @@
xdef _call_user xdef _call_user
xdef _restart_cli xdef _restart_cli
;
; Interrupt registers for A2560U and U+
;
PENDING_GRP0 = $00B00100
PENDING_GRP1 = $00B00102
PENDING_GRP2 = $00B00104
section "vectors",code section "vectors",code
dc.l ___STACK ; 00 - Initial stack pointer dc.l ___STACK ; 00 - Initial stack pointer
@ -37,12 +44,12 @@
dc.l not_impl ; 22 - Reserved dc.l not_impl ; 22 - Reserved
dc.l not_impl ; 23 - Reserved dc.l not_impl ; 23 - Reserved
dc.l _handle_spurious ; 24 - Spurious Interrupt dc.l _handle_spurious ; 24 - Spurious Interrupt
dc.l autovec1 ; 25 - Level 1 Interrupt Autovector dc.l not_impl ; 25 - Level 1 Interrupt Autovector
dc.l autovec2 ; 26 - Level 2 Interrupt Autovector dc.l not_impl ; 26 - Level 2 Interrupt Autovector
dc.l not_impl ; 27 - Level 3 Interrupt Autovector dc.l not_impl ; 27 - Level 3 Interrupt Autovector
dc.l not_impl ; 28 - Level 4 Interrupt Autovector dc.l not_impl ; 28 - Level 4 Interrupt Autovector
dc.l not_impl ; 29 - Level 5 Interrupt Autovector dc.l not_impl ; 29 - Level 5 Interrupt Autovector
dc.l not_impl ; 30 - Level 6 Interrupt Autovector dc.l autovec2 ; 30 - Level 6 Interrupt Autovector
dc.l not_impl ; 31 - Level 7 Interrupt Autovector dc.l not_impl ; 31 - Level 7 Interrupt Autovector
dc.l not_impl ; 32 - TRAP #0 dc.l not_impl ; 32 - TRAP #0
dc.l not_impl ; 33 - TRAP #1 dc.l not_impl ; 33 - TRAP #1
@ -137,8 +144,7 @@ ___exit:
; ;
; Autovector #1: Used by VICKY III Channel B interrupts ; Autovector #1: Used by VICKY III Channel B interrupts
; ;
autovec1: ori.w #$0700,SR ; Set the level to 7 autovec1: movem.l d0-d7/a0-a6,-(a7)
movem.l d0-d7/a0-a6,-(a7)
jsr _int_vicky_channel_b ; Call the dispatcher for Channel B interrupts jsr _int_vicky_channel_b ; Call the dispatcher for Channel B interrupts
movem.l (a7)+,d0-d7/a0-a6 movem.l (a7)+,d0-d7/a0-a6
rte rte
@ -146,8 +152,7 @@ autovec1: ori.w #$0700,SR ; Set the level to 7
; ;
; Autovector #1: Used by VICKY III Channel A interrupts ; Autovector #1: Used by VICKY III Channel A interrupts
; ;
autovec2: ori.w #$0700,SR ; Set the level to 7 autovec2: movem.l d0-d7/a0-a6,-(a7)
movem.l d0-d7/a0-a6,-(a7)
jsr _int_vicky_channel_a ; Call the dispatcher for Channel A interrupts jsr _int_vicky_channel_a ; Call the dispatcher for Channel A interrupts
movem.l (a7)+,d0-d7/a0-a6 movem.l (a7)+,d0-d7/a0-a6
rte rte
@ -172,16 +177,16 @@ intdis_end: movem.l (a7)+,d0-d7/a0-a6 ; Restore affected registers
; Interrupt Vector 0x10 -- SuperIO Keyboard ; Interrupt Vector 0x10 -- SuperIO Keyboard
; ;
interrupt_x10: interrupt_x10:
ori.w #$0700,SR ; Set the level to 7 move.w #$0001,(PENDING_GRP1) ; Clear the flag for INT 10
movem.l d0-d7/a0-a6,-(a7) ; Save affected registers movem.l d0-d7/a0-a6,-(a7) ; Save affected registers
move.w #($10<<2),d0 ; Get the offset to interrupt 0x11 move.w #($10<<2),d0 ; Get the offset to interrupt 0x11
bra int_dispatch ; And process the interrupt bra int_dispatch
; ;
; Interrupt Vector 0x11 -- A2560K "Mo" keyboard ; Interrupt Vector 0x11 -- A2560K "Mo" keyboard
; ;
interrupt_x11: interrupt_x11:
ori.w #$0700,SR ; Set the level to 7 move.w #$0002,(PENDING_GRP1) ; Clear the flag for INT 11
movem.l d0-d7/a0-a6,-(a7) ; Save affected registers movem.l d0-d7/a0-a6,-(a7) ; Save affected registers
move.w #($11<<2),d0 ; Get the offset to interrupt 0x11 move.w #($11<<2),d0 ; Get the offset to interrupt 0x11
bra int_dispatch ; And process the interrupt bra int_dispatch ; And process the interrupt
@ -190,7 +195,7 @@ interrupt_x11:
; Interrupt Vector 0x12 -- SuperIO Mouse ; Interrupt Vector 0x12 -- SuperIO Mouse
; ;
interrupt_x12: interrupt_x12:
ori.w #$0700,SR ; Set the level to 7 move.w #$0004,(PENDING_GRP1) ; Clear the flag for INT 12
movem.l d0-d7/a0-a6,-(a7) ; Save affected registers movem.l d0-d7/a0-a6,-(a7) ; Save affected registers
move.w #($12<<2),d0 ; Get the offset to interrupt 0x11 move.w #($12<<2),d0 ; Get the offset to interrupt 0x11
bra int_dispatch ; And process the interrupt bra int_dispatch ; And process the interrupt
@ -199,7 +204,7 @@ interrupt_x12:
; Interrupt Vector 0x1F -- RTC ; Interrupt Vector 0x1F -- RTC
; ;
interrupt_x1F: interrupt_x1F:
ori.w #$0700,SR ; Set the level to 7 move.w #$8000,(PENDING_GRP1) ; Clear the flag for INT 1F
movem.l d0-d7/a0-a6,-(a7) ; Save affected registers movem.l d0-d7/a0-a6,-(a7) ; Save affected registers
move.w #($1f<<2),d0 ; Get the offset to interrupt 0x1f move.w #($1f<<2),d0 ; Get the offset to interrupt 0x1f
bra int_dispatch ; And process the interrupt bra int_dispatch ; And process the interrupt
@ -208,7 +213,6 @@ interrupt_x1F:
; Interrupt Vector 0x21 -- SDCard Insert ; Interrupt Vector 0x21 -- SDCard Insert
; ;
interrupt_x21: interrupt_x21:
ori.w #$0700,SR ; Set the level to 7
movem.l d0-d7/a0-a6,-(a7) ; Save affected registers movem.l d0-d7/a0-a6,-(a7) ; Save affected registers
move.w #($21<<2),d0 ; Get the offset to interrupt 0x1f move.w #($21<<2),d0 ; Get the offset to interrupt 0x1f
bra int_dispatch ; And process the interrupt bra int_dispatch ; And process the interrupt

12301
src/mapfile

File diff suppressed because it is too large Load diff

View file

@ -4,6 +4,7 @@
#include "snd/sid.h" #include "snd/sid.h"
#include "sound_reg.h" #include "sound_reg.h"
#include "dev/rtc.h"
/* /*
* Return the base address of the given SID chip * Return the base address of the given SID chip
@ -65,6 +66,7 @@ void sid_init_all() {
void sid_test_internal() { void sid_test_internal() {
unsigned char i; unsigned char i;
unsigned int j; unsigned int j;
long jiffies;
// Attack = 2, Decay = 9 // Attack = 2, Decay = 9
*SID_INT_L_V1_ATCK_DECY = 0x29; *SID_INT_L_V1_ATCK_DECY = 0x29;
@ -95,8 +97,8 @@ void sid_test_internal() {
*SID_INT_L_V1_CTRL = 0x11; *SID_INT_L_V1_CTRL = 0x11;
*SID_INT_R_V1_CTRL = 0x11; *SID_INT_R_V1_CTRL = 0x11;
for (j=0 ; j<65536; j++); jiffies = rtc_get_jiffies() + 3;
while (jiffies > rtc_get_jiffies());
*SID_INT_L_V2_FREQ_LO = 49; *SID_INT_L_V2_FREQ_LO = 49;
*SID_INT_L_V2_FREQ_HI = 8; *SID_INT_L_V2_FREQ_HI = 8;
@ -106,7 +108,8 @@ void sid_test_internal() {
*SID_INT_L_V2_CTRL = 0x11; *SID_INT_L_V2_CTRL = 0x11;
*SID_INT_R_V2_CTRL = 0x11; *SID_INT_R_V2_CTRL = 0x11;
for (j=0 ; j<65536; j++); jiffies = rtc_get_jiffies() + 3;
while (jiffies > rtc_get_jiffies());
*SID_INT_L_V3_FREQ_LO = 135; *SID_INT_L_V3_FREQ_LO = 135;
*SID_INT_L_V3_FREQ_HI = 33; *SID_INT_L_V3_FREQ_HI = 33;
@ -116,7 +119,8 @@ void sid_test_internal() {
*SID_INT_L_V3_CTRL = 0x11; *SID_INT_L_V3_CTRL = 0x11;
*SID_INT_R_V3_CTRL = 0x11; *SID_INT_R_V3_CTRL = 0x11;
for (j=0 ; j<262144; j++); jiffies = rtc_get_jiffies() + 60;
while (jiffies > rtc_get_jiffies());
*SID_INT_L_V1_CTRL = 0x10; *SID_INT_L_V1_CTRL = 0x10;
*SID_INT_R_V1_CTRL = 0x10; *SID_INT_R_V1_CTRL = 0x10;
@ -128,13 +132,17 @@ void sid_test_internal() {
*SID_INT_R_V2_CTRL = 0x10; *SID_INT_R_V2_CTRL = 0x10;
for (j=0 ; j<32768 ; j++); for (j=0 ; j<32768 ; j++);
for (i = 0; i < 16; i++) { // for (i = 0; i < 16; i++) {
//
// jiffies = rtc_get_jiffies() + 1;
// while (jiffies > rtc_get_jiffies());
//
// *SID_INT_L_MODE_VOL = 15 - i;
// *SID_INT_R_MODE_VOL = 15 - i;
// }
for (j=0 ; j<1024 ; j++); *SID_INT_L_MODE_VOL = 0;
*SID_INT_R_MODE_VOL = 0;
*SID_INT_L_MODE_VOL = 15 - i;
*SID_INT_R_MODE_VOL = 15 - i;
}
} }
void sid_text_external() { void sid_text_external() {

View file

@ -542,18 +542,17 @@ short sys_fsys_register_loader(const char * extension, p_file_loader loader) {
*/ */
/* /*
* Get the number of ticks since the system last booted. * Get the number of jiffies since the system last booted.
* *
* NOTE: a tick is almost, but not quite, 1ms. The RTC periodic interrupt * NOTE: a jiffie is 1/60 of a second. This timer will not be
* period does not line up with a 1ms timer, but it comes close. * 100% precise, so it should be used for timeout purposes
* Therefore, a tick will be 976.5625 microseconds... a little faster * where precision is not critical.
* than 1ms.
* *
* Returns: * Returns:
* the number of ticks since the last reset * the number of jiffies since the last reset
*/ */
long sys_rtc_get_ticks() { extern long sys_time_jiffies() {
return syscall(KFN_TIME_TICKS); return syscall(KFN_TIME_JIFFIES);
} }
/* /*

View file

@ -13,13 +13,6 @@ void sof_a_handler() {
long jc_mod; long jc_mod;
jiffy_count++; jiffy_count++;
jc_mod = jiffy_count % 60;
if (jc_mod == 30) {
*GABE_CTRL_REG = *GABE_CTRL_REG | POWER_ON_LED;
} else if (jc_mod == 0) {
*GABE_CTRL_REG = *GABE_CTRL_REG & ~POWER_ON_LED;
}
} }
/* /*
@ -29,7 +22,7 @@ void timers_init() {
jiffy_count = 0; jiffy_count = 0;
int_register(INT_SOF_A, sof_a_handler); int_register(INT_SOF_A, sof_a_handler);
// int_enable(INT_SOF_A); int_enable(INT_SOF_A);
} }
/* /*

13
vbcc/config/a2560u_flash Normal file
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=del %s
-rmv=del %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

View file

@ -1,13 +1,13 @@
-cc=vbccm68k -quiet %s -o= %s %s -O=%ld -ID:\projects\FoenixMCP\vbcc\targets\m68k-foenix\include -cc=vbccm68k -quiet %s -o= %s %s -O=%ld -I%%VBCC%%\targets\m68k-foenix\include
-ccv=vbccm68k %s -o= %s %s -O=%ld -ID:\projects\FoenixMCP\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 -as=vasmm68k_mot -quiet -Fvobj -nowarn=62 %s -o %s
-asv=vasmm68k_mot -Fvobj -nowarn=62 %s -o %s -asv=vasmm68k_mot -Fvobj -nowarn=62 %s -o %s
-rm=del %s -rm=del %s
-rmv=del %s -rmv=del %s
-ld=vlink -bsrec28 -x -Cvbcc m68k\startup_m68k.o %s %s -L..\vbcc\targets\m68k-foenix\lib -T..\vbcc\targets\m68k-foenix\vlink.cmd -lvc -o %s -Mmapfile -ld=vlink -bsrec28 -x -Cvbcc m68k\startup_m68k.o %s %s -L%%VBCC%%\targets\m68k-foenix\lib -T%%VBCC%%\targets\m68k-foenix\vlink.cmd -lvc -o %s -Mmapfile
-l2=vlink -bsrec28 -x -Cvbcc %s %s -L..\vbcc\targets\m68k-foenix\lib -T..\vbcc\targets\m68k-foenix\vlink.cmd -o %s -Mmapfile -l2=vlink -bsrec28 -x -Cvbcc %s %s -L%%VBCC%%\targets\m68k-foenix\lib -T%%VBCC%%\targets\m68k-foenix\vlink.cmd -o %s -Mmapfile
-ldv=vlink -bsrec28 -t -x -Cvbcc m68k\startup.o %s %s -L..\vbcc\targets\m68k-foenix\lib -T..\vbcc\targets\m68k-foenix\vlink.cmd -lvc -o %s -Mmapfile -ldv=vlink -bsrec28 -t -x -Cvbcc m68k\startup.o %s %s -L%%VBCC%%\targets\m68k-foenix\lib -T%%VBCC%%\targets\m68k-foenix\vlink.cmd -lvc -o %s -Mmapfile
-l2v=vlink -bsrec28 -t -x -Cvbcc %s %s -L..\vbcc\targets\m68k-foenix\lib -T..\vbcc\targets\m68k-foenix\vlink.cmd -o %s -Mmapfile -l2v=vlink -bsrec28 -t -x -Cvbcc %s %s -L%%VBCC%%\targets\m68k-foenix\lib -T%%VBCC%%\targets\m68k-foenix\vlink.cmd -o %s -Mmapfile
-ul=-l%s -ul=-l%s
-cf=-F%s -cf=-F%s
-ml=1000 -ml=1000

View file

@ -0,0 +1,36 @@
FLASHSTART = 0x00E10000;
FLASHLEN = 0x00200000;
RAMSTART = 0x00001000;
RAMSIZE = 0x00010000;
STACKLEN = 0x400;
VECTORSIZE = 0x400;
BINFILESTART = 0x00000000;
PAGESIZE = 0x10000;
MEMORY
{
vectors : org = 0x000000, len = VECTORSIZE
ram : org = RAMSTART + VECTORSIZE, len = RAMSIZE - VECTORSIZE
flash: org = FLASHSTART, len = FLASHLEN
binpage0: org = BINFILESTART, len = PAGESIZE
binpages: org = BINFILESTART + PAGESIZE, len = FLASHLEN - PAGESIZE
}
SECTIONS
{
vectors : { *(VECTORS) } >vectors AT>binpage0
text : {*(CODE)} >flash AT>binpages
.dtors : { *(.dtors) } >flash AT>binpages
.ctors : { *(.ctors) } >flash AT>binpages
rodata : {*(RODATA)} >flash AT>binpages
data: {*(DATA)} >ram
bss (NOLOAD): {*(BSS)} >ram
___heap = ADDR(bss) + SIZEOF(bss);
___heapend = RAMSTART + RAMSIZE - STACKLEN;
___BSSSTART = ADDR(bss);
___BSSSIZE = SIZEOF(bss);
___STACK = RAMSTART + RAMSIZE;
}