Channel Redirection
Added basic support for redirecting channel IDs to other channels (sys_chan_swap and sys_chan_dev). Current flash version is not quite working... panics on running an external file.
This commit is contained in:
parent
660d8c5b3f
commit
b315be98b7
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -4,7 +4,7 @@
|
|||
# and where the MCP will run (ram or flash)
|
||||
#
|
||||
UNIT := a2560k
|
||||
MEMORY := ram
|
||||
MEMORY := flash
|
||||
|
||||
# CPU_WDC65816 0x16 /* CPU code for the Western Design Center 65816 */
|
||||
# CPU_M68000 0x20 /* CPU code for the Motorola 68000 */
|
||||
|
|
|
@ -88,6 +88,8 @@ extern short cmd_credits(short channel, int argc, const char * argv[]);
|
|||
/** The channel to use for interactions */
|
||||
short g_current_channel = 0;
|
||||
|
||||
short g_channels_swapped = 1;
|
||||
|
||||
/** Flag to indicate that the current working directory has changed */
|
||||
short g_cwd_changed = 0;
|
||||
|
||||
|
@ -136,21 +138,24 @@ const t_cli_command g_cli_commands[] = {
|
|||
};
|
||||
|
||||
/**
|
||||
* Set the number of the channel to use for interactions
|
||||
* Set the number of the screen to use for interactions
|
||||
*
|
||||
* @param channel the number of the text device to use
|
||||
* @param screen the number of the text device to use
|
||||
*/
|
||||
void cli_channel_set(short channel) {
|
||||
g_current_channel = channel;
|
||||
void cli_txt_screen_set(short screen) {
|
||||
if (sys_chan_device(0) != screen) {
|
||||
sys_chan_swap(0, 1);
|
||||
g_channels_swapped = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of the channel to use for interactions
|
||||
* Get the number of the screen used for interactions
|
||||
*
|
||||
* @return channel the number of the text device to use
|
||||
* @return the number of the text device to use
|
||||
*/
|
||||
short cli_channel_get() {
|
||||
return g_current_channel;
|
||||
short cli_txt_screen_get() {
|
||||
return sys_chan_device(0);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -730,24 +735,26 @@ void cli_draw_window(short channel, const char * status, short is_active) {
|
|||
t_rect region, old_region, full_region;
|
||||
short i = 0, j;
|
||||
|
||||
short dev = sys_chan_device(channel);
|
||||
|
||||
// Save the current region and cursor location
|
||||
sys_txt_get_xy(channel, &cursor);
|
||||
sys_txt_get_region(channel, &old_region);
|
||||
sys_txt_get_color(channel, &foreground, &background);
|
||||
sys_txt_get_xy(dev, &cursor);
|
||||
sys_txt_get_region(dev, &old_region);
|
||||
sys_txt_get_color(dev, &foreground, &background);
|
||||
|
||||
// Return to the full region and get its dimensions
|
||||
region.origin.x = 0;
|
||||
region.origin.y = 0;
|
||||
region.size.width = 0;
|
||||
region.size.height = 0;
|
||||
sys_txt_set_region(channel, ®ion);
|
||||
sys_txt_get_region(channel, &full_region);
|
||||
sys_txt_set_region(dev, ®ion);
|
||||
sys_txt_get_region(dev, &full_region);
|
||||
|
||||
// Display the titlebar
|
||||
i = 0;
|
||||
sys_txt_set_xy(channel, 0, 0);
|
||||
if (is_active) {
|
||||
sys_txt_set_color(channel, background, foreground);
|
||||
sys_txt_set_xy(dev, 0, 0);
|
||||
if (channel == 0) {
|
||||
sys_txt_set_color(dev, background, foreground);
|
||||
}
|
||||
for (j = 0; j < strlen(title_header); j++) {
|
||||
buffer[i++] = title_header[j];
|
||||
|
@ -766,16 +773,13 @@ void cli_draw_window(short channel, const char * status, short is_active) {
|
|||
print(channel, buffer);
|
||||
|
||||
// Restore the region and cursor location
|
||||
sys_txt_set_color(channel, foreground, background);
|
||||
sys_txt_set_region(channel, &old_region);
|
||||
sys_txt_set_xy(channel, cursor.x, cursor.y);
|
||||
sys_txt_set_color(dev, foreground, background);
|
||||
sys_txt_set_region(dev, &old_region);
|
||||
sys_txt_set_xy(dev, cursor.x, cursor.y);
|
||||
|
||||
// Set cursor visibility based on if the screen is active
|
||||
if (is_active) {
|
||||
sys_chan_ioctrl(channel, 0x06, 0, 0);
|
||||
} else {
|
||||
sys_chan_ioctrl(channel, 0x07, 0, 0);
|
||||
}
|
||||
sys_chan_ioctrl(0, 0x06, 0, 0);
|
||||
sys_chan_ioctrl(1, 0x07, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -785,13 +789,15 @@ void cli_setup_screen(short channel, const char * path, short is_active) {
|
|||
t_rect full_region, command_region;
|
||||
char message[80];
|
||||
|
||||
short dev = sys_chan_device(channel);
|
||||
|
||||
// Get the size of the screen
|
||||
full_region.origin.x = 0;
|
||||
full_region.origin.y = 0;
|
||||
full_region.size.width = 0;
|
||||
full_region.size.height = 0;
|
||||
sys_txt_set_region(channel, &full_region);
|
||||
sys_txt_get_region(channel, &full_region);
|
||||
sys_txt_set_region(dev, &full_region);
|
||||
sys_txt_get_region(dev, &full_region);
|
||||
|
||||
// Clear the screen
|
||||
print(channel, "\x1b[2J\x1b[H");
|
||||
|
@ -803,7 +809,7 @@ void cli_setup_screen(short channel, const char * path, short is_active) {
|
|||
command_region.size.height = full_region.size.height - 1;
|
||||
|
||||
// Restrict the region to the command panel
|
||||
sys_txt_set_region(channel, &command_region);
|
||||
sys_txt_set_region(dev, &command_region);
|
||||
|
||||
// Draw the window
|
||||
cli_draw_window(channel, path, is_active);
|
||||
|
@ -829,6 +835,7 @@ short cli_repl(short channel) {
|
|||
short old_channel;
|
||||
|
||||
old_channel = channel;
|
||||
g_channels_swapped = 1;
|
||||
|
||||
g_cwd_changed = 1;
|
||||
cursor.x = 0;
|
||||
|
@ -836,7 +843,7 @@ short cli_repl(short channel) {
|
|||
|
||||
while (1) {
|
||||
// Refresh window if the current working directory has changed
|
||||
if (g_cwd_changed || (old_channel != g_current_channel)) {
|
||||
if (g_cwd_changed || g_channels_swapped) {
|
||||
g_cwd_changed = 0;
|
||||
|
||||
// Get and display the new working directory
|
||||
|
@ -844,13 +851,13 @@ short cli_repl(short channel) {
|
|||
// char message[80];
|
||||
// sprintf(message, "%d", strlen(cwd_buffer));
|
||||
print(0, "");
|
||||
if (old_channel != g_current_channel) {
|
||||
|
||||
if (g_channels_swapped) {
|
||||
// If channel has changed, deactivate old channel
|
||||
cli_draw_window(old_channel, cwd_buffer, 0);
|
||||
cli_draw_window(1, cwd_buffer, 0);
|
||||
old_channel = g_current_channel;
|
||||
g_channels_swapped = 0;
|
||||
}
|
||||
cli_draw_window(g_current_channel, cwd_buffer, 1);
|
||||
cli_draw_window(0, cwd_buffer, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -858,7 +865,9 @@ short cli_repl(short channel) {
|
|||
result = cli_readline(g_current_channel, command_line);
|
||||
switch (result) {
|
||||
case -1:
|
||||
g_current_channel = (g_current_channel == 0) ? 1 : 0;
|
||||
// g_current_channel = (g_current_channel == 0) ? 1 : 0;
|
||||
sys_chan_swap(0, 1);
|
||||
g_channels_swapped = 1;
|
||||
break;
|
||||
|
||||
case -2:
|
||||
|
@ -886,7 +895,7 @@ short cli_repl(short channel) {
|
|||
cli_process_line(g_current_channel, command_line);
|
||||
|
||||
print(g_current_channel, "\n");
|
||||
sys_txt_get_xy(channel, &cursor);
|
||||
sys_txt_get_xy(sys_chan_device(g_current_channel), &cursor);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -66,18 +66,18 @@ extern short cmd_help(short channel, int argc, const char * argv[]);
|
|||
extern short cli_exec_batch(short channel, const char * path);
|
||||
|
||||
/**
|
||||
* Set the number of the channel to use for interactions
|
||||
* Set the number of the screen to use for interactions
|
||||
*
|
||||
* @param channel the number of the text device to use
|
||||
* @param screen the number of the text device to use
|
||||
*/
|
||||
extern void cli_channel_set(short channel);
|
||||
extern void cli_txt_screen_set(short screen);
|
||||
|
||||
/**
|
||||
* Get the number of the channel to use for interactions
|
||||
* Get the number of the screen used for interactions
|
||||
*
|
||||
* @return channel the number of the text device to use
|
||||
* @return the number of the text device to use
|
||||
*/
|
||||
extern short cli_channel_get();
|
||||
extern short cli_txt_screen_get();
|
||||
|
||||
/**
|
||||
* Indicate that the current working directory has changed
|
||||
|
|
|
@ -575,7 +575,7 @@ short cli_screen_set(short channel, const char * value) {
|
|||
|
||||
sys_get_info(&info);
|
||||
if (screen < info.screens) {
|
||||
cli_channel_set(screen);
|
||||
cli_txt_screen_set(screen);
|
||||
} else {
|
||||
sprintf(message, "Screen #%d not present.\n", screen);
|
||||
print(channel, message);
|
||||
|
@ -587,7 +587,7 @@ short cli_screen_set(short channel, const char * value) {
|
|||
* Get the number of the text screen to use for interactions
|
||||
*/
|
||||
short cli_screen_get(short channel, const char * value) {
|
||||
sprintf(value, "%d", cli_channel_get());
|
||||
sprintf(value, "%d", cli_txt_screen_get());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -617,7 +617,7 @@ void cli_set_init() {
|
|||
cli_set_register("KEYCOLOR", "KEYCOLOR 0x0RGB -- set the keyboard color", cli_keycolor_set, cli_keycolor_get);
|
||||
}
|
||||
|
||||
if (info.screens == 1) {
|
||||
if (info.screens > 1) {
|
||||
cli_set_register("SCREEN", "SCREEN <0 - 1> -- set the channel number to use for interactions", cli_screen_set, cli_screen_get);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
* Examples include: console, serial port, an open file, etc.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "dev/channel.h"
|
||||
#include "errors.h"
|
||||
#include "simpleio.h"
|
||||
|
@ -475,3 +477,62 @@ short chan_ioctrl(short channel, short command, uint8_t * buffer, short size) {
|
|||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the device associated with the channel
|
||||
*
|
||||
* @param channel the ID of the channel to query
|
||||
* @return the ID of the device associated with the channel, negative number for error
|
||||
*/
|
||||
short chan_device(short channel) {
|
||||
if (channel >= CHAN_MAX) {
|
||||
// If either channel ID is bad...
|
||||
return ERR_BADCHANNEL;
|
||||
|
||||
} else {
|
||||
if (g_channels[channel].number != channel) {
|
||||
// Channel is closed
|
||||
return ERR_BADCHANNEL;
|
||||
|
||||
} else {
|
||||
return g_channels[channel].dev;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Swap the channel ID assignments for two channels
|
||||
*
|
||||
* Before call: channel1 = "Channel A", channel2 = "Channel B"
|
||||
* After call: channel1 = "Channel B", channel2 = "Channel A"
|
||||
*
|
||||
* @param channel1 the ID of one of the channels
|
||||
* @param channel2 the ID of the other channel
|
||||
* @return 0 on success, any other number is an error
|
||||
*/
|
||||
short chan_swap(short channel1, short channel2) {
|
||||
if ((channel1 >= CHAN_MAX) || (channel2 >= CHAN_MAX)) {
|
||||
// If either channel ID is bad...
|
||||
return ERR_BADCHANNEL;
|
||||
|
||||
} else {
|
||||
uint8_t tmp_data[CHAN_DATA_SIZE];
|
||||
p_channel chan1 = 0, chan2 = 0;
|
||||
short i = 0, tmp_dev = 0;
|
||||
|
||||
chan1 = &g_channels[channel1];
|
||||
chan2 = &g_channels[channel2];
|
||||
|
||||
// Swap the devices
|
||||
tmp_dev = chan1->dev;
|
||||
chan1->dev = chan2->dev;
|
||||
chan2->dev = tmp_dev;
|
||||
|
||||
// Swap the data blocks
|
||||
memcpy(tmp_data, chan1->data, CHAN_DATA_SIZE);
|
||||
memcpy(chan1->data, chan2->data, CHAN_DATA_SIZE);
|
||||
memcpy(chan2->data, tmp_data, CHAN_DATA_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -265,4 +265,16 @@ extern short chan_seek(short channel, long position, short base);
|
|||
*/
|
||||
extern short chan_ioctrl(short channel, short command, uint8_t * buffer, short size);
|
||||
|
||||
/**
|
||||
* Swap the channel ID assignments for two channels
|
||||
*
|
||||
* Before call: channel1 = "Channel A", channel2 = "Channel B"
|
||||
* After call: channel1 = "Channel B", channel2 = "Channel A"
|
||||
*
|
||||
* @param channel1 the ID of one of the channels
|
||||
* @param channel2 the ID of the other channel
|
||||
* @return 0 on success, any other number is an error
|
||||
*/
|
||||
extern short chan_swap(short channel1, short channel2);
|
||||
|
||||
#endif
|
||||
|
|
5128
src/foenixmcp.s68
5128
src/foenixmcp.s68
File diff suppressed because it is too large
Load diff
|
@ -49,6 +49,8 @@
|
|||
#define KFN_CHAN_REGISTER 0x19 /* Register a channel device driver */
|
||||
#define KFN_CHAN_OPEN 0x1A /* Open a channel device */
|
||||
#define KFN_CHAN_CLOSE 0x1B /* Close an open channel (not for files) */
|
||||
#define KFN_CHAN_SWAP 0x1C /* Swap the channel ID assignment of two channels */
|
||||
#define KFN_CHAN_DEVICE 0x1D /* Get the number of the device associated with the channel */
|
||||
|
||||
|
||||
/* Block device system calls */
|
||||
|
@ -344,6 +346,26 @@ extern short sys_chan_open(short dev, const uint8_t * path, short mode);
|
|||
*/
|
||||
extern short sys_chan_close(short chan);
|
||||
|
||||
/**
|
||||
* Swap the channel ID assignments for two channels
|
||||
*
|
||||
* Before call: channel1 = "Channel A", channel2 = "Channel B"
|
||||
* After call: channel1 = "Channel B", channel2 = "Channel A"
|
||||
*
|
||||
* @param channel1 the ID of one of the channels
|
||||
* @param channel2 the ID of the other channel
|
||||
* @return 0 on success, any other number is an error
|
||||
*/
|
||||
extern short sys_chan_swap(short channel1, short channel2);
|
||||
|
||||
/**
|
||||
* Return the device associated with the channel
|
||||
*
|
||||
* @param channel the ID of the channel to query
|
||||
* @return the ID of the device associated with the channel, negative number for error
|
||||
*/
|
||||
extern short sys_chan_device(short channel);
|
||||
|
||||
/*
|
||||
* Compute the size information for the text screen based on the current settings in VICKY
|
||||
* These settings are needed to correctly position text on the screen.
|
||||
|
|
52
src/log.c
52
src/log.c
|
@ -123,81 +123,69 @@ void panic(void) {
|
|||
txt_clear(0, 2);
|
||||
|
||||
txt_set_xy(0, column, row++);
|
||||
sprintf(buffer, "\xDA\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xBF");
|
||||
print(0, buffer);
|
||||
txt_print(0, "\xDA\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xBF");
|
||||
|
||||
txt_set_xy(0, column, row++);
|
||||
sprintf(buffer, "\xB3 \xB3");
|
||||
print(0, buffer);
|
||||
txt_print(0, "\xB3 \xB3");
|
||||
|
||||
txt_set_xy(0, column, row++);
|
||||
sprintf(buffer, "\xB3 Oh dear, something has gone wrong... \xB3");
|
||||
print(0, buffer);
|
||||
txt_print(0, "\xB3 Oh dear, something has gone wrong... \xB3");
|
||||
|
||||
txt_set_xy(0, column, row++);
|
||||
sprintf(buffer, "\xB3 \xB3");
|
||||
print(0, buffer);
|
||||
txt_print(0, "\xB3 \xB3");
|
||||
|
||||
txt_set_xy(0, column, row++);
|
||||
switch (panic_number) {
|
||||
case 2:
|
||||
sprintf(buffer, "\xB3 Bus Error \xB3");
|
||||
txt_print(0, "\xB3 Bus Error \xB3");
|
||||
address_expected = 1;
|
||||
break;
|
||||
case 3:
|
||||
sprintf(buffer, "\xB3 Address Error \xB3");
|
||||
txt_print(0, "\xB3 Address Error \xB3");
|
||||
address_expected = 1;
|
||||
break;
|
||||
case 4:
|
||||
sprintf(buffer, "\xB3 Illegal Instruction Error \xB3");
|
||||
txt_print(0, "\xB3 Illegal Instruction Error \xB3");
|
||||
break;
|
||||
case 5:
|
||||
sprintf(buffer, "\xB3 Division by Zero Error \xB3");
|
||||
txt_print(0, "\xB3 Division by Zero Error \xB3");
|
||||
break;
|
||||
case 6:
|
||||
sprintf(buffer, "\xB3 Range Check Exception \xB3");
|
||||
txt_print(0, "\xB3 Range Check Exception \xB3");
|
||||
break;
|
||||
case 7:
|
||||
sprintf(buffer, "\xB3 Overflow Exception \xB3");
|
||||
txt_print(0, "\xB3 Overflow Exception \xB3");
|
||||
break;
|
||||
case 8:
|
||||
sprintf(buffer, "\xB3 Privilege Exception \xB3");
|
||||
txt_print(0, "\xB3 Privilege Exception \xB3");
|
||||
break;
|
||||
case 24:
|
||||
sprintf(buffer, "\xB3 Spurious Interrupt \xB3");
|
||||
txt_print(0, "\xB3 Spurious Interrupt \xB3");
|
||||
break;
|
||||
|
||||
default:
|
||||
sprintf(buffer, "\xB3 Unknown Exception \xB3");
|
||||
txt_print(0, "\xB3 Unknown Exception \xB3");
|
||||
break;
|
||||
}
|
||||
print(0, buffer);
|
||||
|
||||
txt_set_xy(0, column, row++);
|
||||
sprintf(buffer, "\xB3 \xB3");
|
||||
print(0, buffer);
|
||||
txt_print(0, "\xB3 \xB3");
|
||||
|
||||
if (address_expected) {
|
||||
txt_set_xy(0, column, row++);
|
||||
print(0, "\xB3 PC: ");
|
||||
print_hex_32(0, panic_pc);
|
||||
print(0, " Address: ");
|
||||
print_hex_32(0, panic_address);
|
||||
print(0, " \xB3");
|
||||
sprintf(buffer, "\xB3 PC: %08X Address: %08X \xB3", panic_pc, panic_address);
|
||||
txt_print(0, buffer);
|
||||
} else {
|
||||
txt_set_xy(0, column, row++);
|
||||
print(0, "\xB3 PC: ");
|
||||
print_hex_32(0, panic_pc);
|
||||
print(0, " \xB3");
|
||||
sprintf(buffer, "\xB3 PC: %08X \xB3", panic_pc);
|
||||
txt_print(0, buffer);
|
||||
}
|
||||
|
||||
txt_set_xy(0, column, row++);
|
||||
sprintf(buffer, "\xB3 \xB3");
|
||||
print(0, buffer);
|
||||
txt_print(0, "\xB3 \xB3");
|
||||
|
||||
txt_set_xy(0, column, row++);
|
||||
sprintf(buffer, "\xC0\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xD9");
|
||||
print(0, buffer);
|
||||
txt_print(0, "\xC0\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xD9");
|
||||
|
||||
/* Wait forever */
|
||||
while (1) ;
|
||||
|
|
|
@ -110,6 +110,12 @@ unsigned long syscall_dispatch(int32_t function, int32_t param0, int32_t param1,
|
|||
case KFN_CHAN_REGISTER:
|
||||
return cdev_register((p_dev_chan)param0);
|
||||
|
||||
case KFN_CHAN_SWAP:
|
||||
return chan_swap((short)param0, (short)param1);
|
||||
|
||||
case KFN_CHAN_DEVICE:
|
||||
return chan_device((short)param0);
|
||||
|
||||
default:
|
||||
return ERR_GENERAL;
|
||||
}
|
||||
|
|
20051
src/mapfile
20051
src/mapfile
File diff suppressed because it is too large
Load diff
|
@ -264,6 +264,26 @@ short sys_chan_close(short chan) {
|
|||
return syscall(KFN_CHAN_CLOSE, chan);
|
||||
}
|
||||
|
||||
/**
|
||||
* Swap the channel ID assignments for two channels
|
||||
*
|
||||
* Before call: channel1 = "Channel A", channel2 = "Channel B"
|
||||
* After call: channel1 = "Channel B", channel2 = "Channel A"
|
||||
*/
|
||||
short sys_chan_swap(short channel1, short channel2) {
|
||||
return syscall(KFN_CHAN_SWAP, channel1, channel2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the device associated with the channel
|
||||
*
|
||||
* @param channel the ID of the channel to query
|
||||
* @return the ID of the device associated with the channel, negative number for error
|
||||
*/
|
||||
short sys_chan_device(short channel) {
|
||||
return syscall(KFN_CHAN_DEVICE, channel);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the size information for the text screen based on the current settings in VICKY
|
||||
* These settings are needed to correctly position text on the screen.
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#define __VERSION_H
|
||||
|
||||
#define VER_MAJOR 0
|
||||
#define VER_MINOR 5
|
||||
#define VER_BUILD 4
|
||||
#define VER_MINOR 51
|
||||
#define VER_BUILD 6
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue