LPT and MIDI Tests
Added tests for the parallel and MIDI ports on SuperIO machines
This commit is contained in:
parent
4d2f3e37a0
commit
95856b80dc
Binary file not shown.
|
@ -6,6 +6,7 @@
|
|||
#include "sound_cmds.h"
|
||||
#include "sound_reg.h"
|
||||
#include "snd/psg.h"
|
||||
#include "dev/midi.h"
|
||||
|
||||
/*
|
||||
* Play a sound on the PSG
|
||||
|
@ -124,3 +125,80 @@ short opl3_test(short channel, int argc, char * argv[]) {
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a receive test on the MIDI ports
|
||||
*/
|
||||
short midi_rx_test(short channel, int argc, char * argv[]) {
|
||||
char message[80];
|
||||
unsigned short scancode = 0;
|
||||
int i;
|
||||
|
||||
midi_init();
|
||||
|
||||
sprintf(message, "Press '1' to start, and 'ESC' to exit test.\n");
|
||||
sys_chan_write(channel, message, strlen(message));
|
||||
|
||||
while (sys_kbd_scancode() != 0x02) ;
|
||||
|
||||
i = 0;
|
||||
while (scancode != 0x01) {
|
||||
unsigned char input = midi_get_poll();
|
||||
if ((input != 0xf8) && (input != 0xfe)) {
|
||||
if ((i % 16) == 0) {
|
||||
sprintf(message, "\n%02X", input);
|
||||
sys_chan_write(channel, message, strlen(message));
|
||||
} else {
|
||||
sprintf(message, " %02X", input);
|
||||
sys_chan_write(channel, message, strlen(message));
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
scancode = sys_kbd_scancode();
|
||||
}
|
||||
|
||||
sys_chan_write(channel, "\n", 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Perform a loopback test on the MIDI ports
|
||||
*/
|
||||
short midi_loop_test(short channel, int argc, char * argv[]) {
|
||||
char message[80];
|
||||
unsigned short scancode = 0;
|
||||
unsigned char output;
|
||||
|
||||
midi_init();
|
||||
|
||||
sprintf(message, "Plug a MIDI loopback cable between MIDI IN and MIDI OUT.\nThen press '1' to start.\n");
|
||||
sys_chan_write(channel, message, strlen(message));
|
||||
|
||||
sprintf(message, "Press ESC to exit test.\n");
|
||||
sys_chan_write(channel, message, strlen(message));
|
||||
|
||||
while (sys_kbd_scancode() != 0x02) ;
|
||||
|
||||
output = 0xF8;
|
||||
while (scancode != 0x01) {
|
||||
sprintf(message, "Sending: ");
|
||||
sys_chan_write(channel, message, strlen(message));
|
||||
midi_put(output);
|
||||
sprintf(message, "%02X --> ", output);
|
||||
sys_chan_write(channel, message, strlen(message));
|
||||
|
||||
unsigned char input = midi_get_poll();
|
||||
sprintf(message, "%02X\n", input);
|
||||
sys_chan_write(channel, message, strlen(message));
|
||||
|
||||
scancode = sys_kbd_scancode();
|
||||
}
|
||||
|
||||
sys_chan_write(channel, "\n", 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -15,4 +15,14 @@ extern short psg_test(short channel, int argc, char * argv[]);
|
|||
*/
|
||||
extern short opl3_test(short channel, int argc, char * argv[]);
|
||||
|
||||
/*
|
||||
* Perform a receive test on the MIDI ports
|
||||
*/
|
||||
extern short midi_rx_test(short channel, int argc, char * argv[]);
|
||||
|
||||
/*
|
||||
* Perform a loopback test on the MIDI ports
|
||||
*/
|
||||
extern short midi_loop_test(short channel, int argc, char * argv[]);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,9 +7,11 @@
|
|||
|
||||
#include "cli.h"
|
||||
#include "cli/test_cmds.h"
|
||||
#include "cli/sound_cmds.h"
|
||||
#include "dev/block.h"
|
||||
#include "dev/channel.h"
|
||||
#include "dev/fsys.h"
|
||||
#include "dev/lpt.h"
|
||||
#include "dev/rtc.h"
|
||||
#include "dev/uart.h"
|
||||
#include "fatfs/ff.h"
|
||||
|
@ -20,6 +22,29 @@
|
|||
#include "sys_general.h"
|
||||
#include "uart_reg.h"
|
||||
|
||||
#define LPT_DATA_PORT ((volatile unsigned char *)0x00C02378)
|
||||
|
||||
#define LPT_STAT_PORT ((volatile unsigned char *)0x00C02379)
|
||||
#define LPT_STAT_BUSY 0x80
|
||||
#define LPT_STAT_ACK 0x40
|
||||
#define LPT_STAT_PO 0x20
|
||||
#define LPT_STAT_SELECT 0x10
|
||||
#define LPT_STAT_ERROR 0x08
|
||||
#define LPT_STAT_IRQ 0x04
|
||||
|
||||
#define LPT_CTRL_PORT ((volatile unsigned char *)0x00C0237A)
|
||||
#define LPT_CTRL_STROBE 0x01
|
||||
#define LPT_CTRL_AL 0x02
|
||||
#define LPT_CTRL_INIT 0x04
|
||||
#define LPT_CTRL_SELECT 0x08
|
||||
#define LPT_CTRL_IRQE 0x10
|
||||
#define LPT_CTRL_BI 0x20
|
||||
|
||||
#define LPT_INIT_ON 0x08 /* Start the printer initialization process */
|
||||
#define LPT_INIT_OFF 0x0C /* Stop the printer initialization process */
|
||||
#define LPT_STROBE_ON 0x0F /* Strobe the printer */
|
||||
#define LPT_STROBE_OFF 0x0E /* Drop the strobe to the printer */
|
||||
|
||||
typedef struct s_cli_test_feature {
|
||||
const char * name;
|
||||
const char * help;
|
||||
|
@ -201,12 +226,95 @@ short cli_test_create(short screen, int argc, char * argv[]) {
|
|||
}
|
||||
}
|
||||
|
||||
short cli_test_lpt(short screen, int argc, char * argv[]) {
|
||||
char message[80];
|
||||
unsigned char scancode;
|
||||
|
||||
sprintf(message, "Test parallel port:\nF1: DATA=00 F2: DATA=FF F3: STRB=1 F4: STRB=0\n");
|
||||
sys_chan_write(screen, message, strlen(message));
|
||||
sprintf(message, "F5: INIT=1 F6: INIT=0 F7: SEL=1 F8: SEL=0\nESC: Quit");
|
||||
sys_chan_write(screen, message, strlen(message));
|
||||
|
||||
while (1) {
|
||||
scancode = sys_kbd_scancode();
|
||||
switch (scancode) {
|
||||
case 0x3B: /* F1 */
|
||||
*LPT_DATA_PORT = 0;
|
||||
break;
|
||||
|
||||
case 0x3C: /* F2 */
|
||||
*LPT_DATA_PORT = 0xff;
|
||||
break;
|
||||
|
||||
case 0x3D: /* F3 */
|
||||
*LPT_CTRL_PORT = LPT_CTRL_STROBE;
|
||||
break;
|
||||
|
||||
case 0x3E: /* F4 */
|
||||
*LPT_CTRL_PORT = 0;
|
||||
break;
|
||||
|
||||
case 0x3F: /* F5 */
|
||||
*LPT_CTRL_PORT = 0;
|
||||
break;
|
||||
|
||||
case 0x40: /* F6 */
|
||||
*LPT_CTRL_PORT = LPT_CTRL_INIT;
|
||||
break;
|
||||
|
||||
case 0x41: /* F7 */
|
||||
*LPT_CTRL_PORT = LPT_CTRL_SELECT;
|
||||
break;
|
||||
|
||||
case 0x42: /* F8 */
|
||||
*LPT_CTRL_PORT = 0;
|
||||
break;
|
||||
|
||||
case 0x1B: /* ESC */
|
||||
return 0;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
short cmd_test_print(short screen, int argc, char * argv[]) {
|
||||
const char * test_pattern = "0123456789ABCDEFGHIJKLMNOPQRTSUVWZXYZ\r\n";
|
||||
|
||||
char message[80];
|
||||
unsigned short scancode = 0;
|
||||
|
||||
sprintf(message, "Initializing printer...\n");
|
||||
sys_chan_write(screen, message, strlen(message));
|
||||
|
||||
lpt_initialize();
|
||||
|
||||
sprintf(message, "Sending test patterns to printer (ESC to quit)...\n");
|
||||
sys_chan_write(screen, message, strlen(message));
|
||||
|
||||
while (scancode != 0x01) {
|
||||
scancode = sys_kbd_scancode();
|
||||
lpt_write(0, test_pattern, strlen(test_pattern));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static t_cli_test_feature cli_test_features[] = {
|
||||
{"CREATE", "CREATE <path>: test creating a file", cli_test_create},
|
||||
{"IDE", "IDE: test reading the MBR of the IDE drive", cli_test_ide},
|
||||
{"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},
|
||||
{"MEM", "MEM: test reading and writing memory", cli_mem_test},
|
||||
{"MIDILOOP", "MIDILOOP: perform a loopback test on the MIDI ports", midi_loop_test},
|
||||
{"MIDIRX", "MIDIRX: perform a receive test on the MIDI ports", midi_rx_test},
|
||||
{"OPL3", "OPL3: test the OPL3 sound chip", opl3_test},
|
||||
{"PSG", "PSG: test the PSG sound chip", psg_test},
|
||||
{"PRINT", "PRINT: sent text to the printer", cmd_test_print},
|
||||
{"UART", "UART: test the serial port", cli_test_uart},
|
||||
{0, 0}
|
||||
};
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#define MAX_ANSI_ARGS 10
|
||||
|
||||
#define CON_CTRL_ANSI 0x80 /* Set to enable ANSI escape processing */
|
||||
#define CON_IOCTRL_ANSI_ON 0x01 /* IOCTRL Command: turn on ANSI terminal codes */
|
||||
#define CON_IOCTRL_ANSI_OFF 0x02 /* IOCTRL Command: turn off ANSI terminal codes */
|
||||
|
||||
typedef void (*ansi_handler)(p_channel, short, short[]);
|
||||
|
||||
|
@ -39,6 +41,7 @@ typedef struct s_console_data {
|
|||
unsigned char control; /* Control flags for the console: e.g. process ANSI codes */
|
||||
unsigned char ansi_buffer_count; /* Number of characters in the ANSI BUFFER */
|
||||
char ansi_buffer[ANSI_BUFFER_SIZE]; /* Used to keep track of characters in the ANSI escape sequences */
|
||||
char key_buffer; /* Used to peek at keyboard input */
|
||||
} t_console_data, *p_console_data;
|
||||
|
||||
/*
|
||||
|
@ -425,6 +428,7 @@ short con_open(p_channel chan, uint8_t * path, short mode) {
|
|||
for (i = 0; i < ANSI_BUFFER_SIZE; i++) {
|
||||
con_data->ansi_buffer[i] = 0;
|
||||
}
|
||||
con_data->key_buffer = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -485,8 +489,18 @@ short con_write_b(p_channel chan, uint8_t b) {
|
|||
* Attempt to read from the keyboard.
|
||||
*/
|
||||
short con_read_b(p_channel chan) {
|
||||
p_console_data con_data;
|
||||
|
||||
/* Check to see if we need to process ANSI codes */
|
||||
con_data = &(chan->data);
|
||||
|
||||
char c;
|
||||
do {
|
||||
if (con_data->key_buffer != 0) {
|
||||
c = con_data->key_buffer;
|
||||
con_data->key_buffer = 0;
|
||||
|
||||
} else {
|
||||
|
||||
#if MODEL == MODEL_FOENIX_A2560K
|
||||
#ifdef KBD_POLLED
|
||||
|
@ -502,6 +516,7 @@ short con_read_b(p_channel chan) {
|
|||
c = kbd_getc();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
} while (c == 0);
|
||||
|
||||
|
@ -605,13 +620,58 @@ short con_write(p_channel chan, const uint8_t * buffer, short size) {
|
|||
return i;
|
||||
}
|
||||
|
||||
short con_has_input(p_channel chan) {
|
||||
p_console_data con_data;
|
||||
char c;
|
||||
|
||||
/* Check to see if we need to process ANSI codes */
|
||||
con_data = &(chan->data);
|
||||
|
||||
if (con_data->key_buffer != 0) {
|
||||
/* If we already peeked and have a character... return true */
|
||||
return 1;
|
||||
|
||||
} else {
|
||||
/* Otherwise, peek at the keyboard to see if there is a valid key */
|
||||
|
||||
#if MODEL == MODEL_FOENIX_A2560K
|
||||
#ifdef KBD_POLLED
|
||||
ps2_mouse_get_packet();
|
||||
c = kbdmo_getc_poll();
|
||||
#else
|
||||
c = kbdmo_getc();
|
||||
#endif
|
||||
#else
|
||||
#ifdef KBD_POLLED
|
||||
c = kbd_getc_poll();
|
||||
#else
|
||||
c = kbd_getc();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (c == 0) {
|
||||
/* No: return false */
|
||||
return 0;
|
||||
|
||||
} else {
|
||||
/* Yes: save the key we got and return true */
|
||||
con_data->key_buffer = c;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Return the status of the console
|
||||
//
|
||||
short con_status(p_channel chan) {
|
||||
// TODO: make CDEV_STAT_READABLE conditional
|
||||
short status = CDEV_STAT_WRITABLE; /* The console is always writable */
|
||||
if (con_has_input(chan)) {
|
||||
/* If there is data available, flag that it's readable */
|
||||
status |= CDEV_STAT_READABLE;
|
||||
}
|
||||
|
||||
return CDEV_STAT_READABLE | CDEV_STAT_WRITABLE;
|
||||
return status;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -622,6 +682,25 @@ short con_seek(p_channel chan, long position, short base) {
|
|||
}
|
||||
|
||||
short con_ioctrl(p_channel chan, short command, uint8_t * buffer, short size) {
|
||||
p_console_data con_data;
|
||||
|
||||
/* Check to see if we need to process ANSI codes */
|
||||
con_data = &(chan->data);
|
||||
|
||||
switch (command) {
|
||||
case CON_IOCTRL_ANSI_ON:
|
||||
/* Turn on ANSI interpreting */
|
||||
con_data->control |= CON_CTRL_ANSI;
|
||||
return 0;
|
||||
|
||||
case CON_IOCTRL_ANSI_OFF:
|
||||
/* Turn on ANSI interpreting */
|
||||
con_data->control &= ~CON_CTRL_ANSI;
|
||||
return 0;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,11 +32,9 @@
|
|||
short lpt_delay() {
|
||||
int i;
|
||||
short x;
|
||||
for (i = 0, x = 0; i < 65535; i++) {
|
||||
for (i = 0, x = 0; i < 10; i++) {
|
||||
x++;
|
||||
}
|
||||
|
||||
DEBUG(".");
|
||||
return x;
|
||||
}
|
||||
|
77
src/dev/midi.c
Normal file
77
src/dev/midi.c
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Definitions for the MIDI ports
|
||||
*/
|
||||
|
||||
#include "midi_reg.h"
|
||||
#include "dev/midi.h"
|
||||
#include "simpleio.h"
|
||||
|
||||
/*
|
||||
* Return true if there is data waiting to be read
|
||||
*/
|
||||
short midi_input_not_ready() {
|
||||
return (*MIDI_STAT & MIDI_STAT_RX_EMPTY);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if there is data waiting to be read
|
||||
*/
|
||||
short midi_output_busy() {
|
||||
return (*MIDI_STAT & MIDI_STAT_RX_EMPTY);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initilialize the MIDI port
|
||||
*/
|
||||
short midi_init() {
|
||||
unsigned char dummy;
|
||||
|
||||
while (midi_output_busy()) ;
|
||||
|
||||
*MIDI_CMD = 0xFF; /* Reset the MIDI port */
|
||||
|
||||
/* Wait for the ACK */
|
||||
for (dummy = 0; dummy != 0xFE; ) {
|
||||
while (midi_input_not_ready()) ;
|
||||
dummy = *MIDI_DATA;
|
||||
}
|
||||
|
||||
while (midi_output_busy()) ;
|
||||
|
||||
*MIDI_CMD = 0x3F; /* Switch the MIDI port into UART mode */
|
||||
|
||||
/* Wait for the ACK */
|
||||
for (dummy = 0; dummy != 0xFE; ) {
|
||||
while (midi_input_not_ready()) ;
|
||||
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_output_busy()) ;
|
||||
|
||||
/* Send the byte */
|
||||
*MIDI_DATA = b;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a byte from the MIDI port
|
||||
*
|
||||
* Returns:
|
||||
* b = the byte to send
|
||||
*/
|
||||
unsigned char midi_get_poll() {
|
||||
while (midi_input_not_ready()) ;
|
||||
return *MIDI_DATA;
|
||||
}
|
|
@ -24,6 +24,6 @@ extern short midi_put(unsigned char b);
|
|||
* Returns:
|
||||
* b = the byte to send
|
||||
*/
|
||||
extern short midi_get_poll();
|
||||
extern unsigned char midi_get_poll();
|
||||
|
||||
#endif
|
|
@ -118,7 +118,7 @@ int text_init() {
|
|||
|
||||
/* Initialize everything... only do a screen if it's present */
|
||||
|
||||
need_hires = ((*VKY3_DIP_REG & VKY3_DIP_HIRES) == VKY3_DIP_HIRES) ? 1 : 0;
|
||||
// need_hires = ((*VKY3_DIP_REG & VKY3_DIP_HIRES) == VKY3_DIP_HIRES) ? 1 : 0;
|
||||
|
||||
chan_a->master_control = MasterControlReg_A;
|
||||
chan_a->text_cells = ScreenText_A;
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
5035
src/foenixmcp.s68
5035
src/foenixmcp.s68
File diff suppressed because it is too large
Load diff
|
@ -353,6 +353,11 @@ extern short sys_bdev_flush(short dev);
|
|||
//
|
||||
extern short sys_bdev_ioctrl(short dev, short command, unsigned char * buffer, short size);
|
||||
|
||||
/*
|
||||
* Return the next scan code from the keyboard... 0 if nothing pending
|
||||
*/
|
||||
extern unsigned short sys_kbd_scancode();
|
||||
|
||||
/*
|
||||
* Miscellaneous
|
||||
*/
|
||||
|
|
|
@ -13,6 +13,13 @@
|
|||
#include "dev/block.h"
|
||||
#include "dev/fsys.h"
|
||||
#include "dev/rtc.h"
|
||||
#include "sys_general.h"
|
||||
|
||||
#if MODEL == MODEL_FOENIX_A2560K
|
||||
#include "dev/kbd_mo.h"
|
||||
#else
|
||||
#include "dev/ps2.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Determine the correct system function implementation and call it.
|
||||
|
@ -188,6 +195,13 @@ unsigned long syscall_dispatch(int32_t function, int32_t param0, int32_t param1,
|
|||
rtc_get_time((p_time)param0);
|
||||
return 0;
|
||||
|
||||
case KFN_KBD_SCANCODE:
|
||||
#if MODEL == MODEL_FOENIX_A2560K
|
||||
return kbdmo_get_scancode();
|
||||
#else
|
||||
return kbd_get_scancode();
|
||||
#endif
|
||||
|
||||
case KFN_ERR_MESSAGE:
|
||||
return (unsigned long)err_message((short)param0);
|
||||
|
||||
|
|
11012
src/mapfile
11012
src/mapfile
File diff suppressed because it is too large
Load diff
|
@ -314,6 +314,13 @@ short sys_bdev_ioctrl(short dev, short command, unsigned char * buffer, short si
|
|||
* Miscellaneous
|
||||
*/
|
||||
|
||||
/*
|
||||
* Return the next scan code from the keyboard... 0 if nothing pending
|
||||
*/
|
||||
unsigned short sys_kbd_scancode() {
|
||||
return syscall(KFN_KBD_SCANCODE);
|
||||
}
|
||||
|
||||
const char * sys_err_message(short err_number) {
|
||||
return (const char *)syscall(KFN_ERR_MESSAGE, (short)err_number);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue