Compare commits
10 commits
c5b0e00e04
...
21fe8ef908
Author | SHA1 | Date | |
---|---|---|---|
21fe8ef908 | |||
7641982319 | |||
97cedc8659 | |||
dbe1fd298b | |||
9b7dab7c2a | |||
5279776737 | |||
83d3c74839 | |||
275e0d7ec8 | |||
9dacef1f57 | |||
206f2d5e6b |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
|
@ -1,7 +1,10 @@
|
||||||
.public restart_cli
|
.public restart_cli
|
||||||
|
.public io_copy_down
|
||||||
|
.public io_copy_up
|
||||||
|
|
||||||
.extern proc_shell_address
|
.extern proc_shell_address
|
||||||
.extern _Vfp
|
.extern _Vfp
|
||||||
|
.extern _Dp
|
||||||
.extern _DirectPageStart
|
.extern _DirectPageStart
|
||||||
|
|
||||||
#ifndef __CALYPSI_DATA_MODEL_SMALL__
|
#ifndef __CALYPSI_DATA_MODEL_SMALL__
|
||||||
|
@ -11,6 +14,42 @@
|
||||||
.section stack
|
.section stack
|
||||||
.section farcode
|
.section farcode
|
||||||
|
|
||||||
|
;
|
||||||
|
; void io_copy_down(uint16_t count, uint16_t dest, uint16_t src)
|
||||||
|
;
|
||||||
|
io_copy_down: pha
|
||||||
|
phx
|
||||||
|
phy
|
||||||
|
phb
|
||||||
|
|
||||||
|
ldy dp:.tiny (_Dp)
|
||||||
|
ldx dp:.tiny (_Dp+4)
|
||||||
|
mvn #0xf0, #0xf0
|
||||||
|
|
||||||
|
plb
|
||||||
|
ply
|
||||||
|
plx
|
||||||
|
pla
|
||||||
|
rtl
|
||||||
|
|
||||||
|
;
|
||||||
|
; void io_copy_up(uint16_t count, uint16_t dest, uint16_t src)
|
||||||
|
;
|
||||||
|
io_copy_up: pha
|
||||||
|
phx
|
||||||
|
phy
|
||||||
|
phb
|
||||||
|
|
||||||
|
ldy dp:.tiny (_Dp)
|
||||||
|
ldx dp:.tiny (_Dp+4)
|
||||||
|
mvp #0xf0, #0xf0
|
||||||
|
|
||||||
|
plb
|
||||||
|
ply
|
||||||
|
plx
|
||||||
|
pla
|
||||||
|
rtl
|
||||||
|
|
||||||
;
|
;
|
||||||
; Reset the stack to the initial value.
|
; Reset the stack to the initial value.
|
||||||
; Reset the direct page and data bank registers
|
; Reset the direct page and data bank registers
|
||||||
|
|
|
@ -7,11 +7,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "log_level.h"
|
#include "log_level.h"
|
||||||
#ifdef DEFAULT_LOG_LEVEL
|
|
||||||
//#undef DEFAULT_LOG_LEVEL
|
|
||||||
#endif
|
|
||||||
#ifndef DEFAULT_LOG_LEVEL
|
#ifndef DEFAULT_LOG_LEVEL
|
||||||
#define DEFAULT_LOG_LEVEL LOG_TRACE
|
#define DEFAULT_LOG_LEVEL LOG_ERROR
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
|
@ -762,6 +762,8 @@ short con_ioctrl(p_channel chan, short command, uint8_t * buffer, short size) {
|
||||||
/* Return the result of the BREAK key test */
|
/* Return the result of the BREAK key test */
|
||||||
#if MODEL == MODEL_FOENIX_A2560K
|
#if MODEL == MODEL_FOENIX_A2560K
|
||||||
return kbdmo_break();
|
return kbdmo_break();
|
||||||
|
#elif MODEL == MODEL_FOENIX_F256 || MODEL == MODEL_FOENIX_F256K || MODEL == MODEL_FOENIX_F256K2 || MODEL == MODEL_FOENIX_F256JR2
|
||||||
|
return kbd_break();
|
||||||
#else
|
#else
|
||||||
/* TODO: flesh this out for the A2560U */
|
/* TODO: flesh this out for the A2560U */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -492,19 +492,12 @@ SYSTEMCALL void int_clear(unsigned short n) {
|
||||||
void int_handle_irq() {
|
void int_handle_irq() {
|
||||||
uint8_t mask_bits = 0;
|
uint8_t mask_bits = 0;
|
||||||
|
|
||||||
// vky_text_matrix[0] += 1;
|
|
||||||
|
|
||||||
// if (*irq_ram_vector != 0) {
|
|
||||||
// p_int_handler handler = (p_int_handler)(*irq_ram_vector);
|
|
||||||
// handler();
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// vky_text_matrix[1] += 1;
|
|
||||||
|
|
||||||
// Process any pending interrupts in group 0
|
// Process any pending interrupts in group 0
|
||||||
mask_bits = *PENDING_GRP0;
|
mask_bits = *PENDING_GRP0;
|
||||||
if (mask_bits) {
|
if (mask_bits) {
|
||||||
|
// Clear the pending bits for group 0
|
||||||
|
*PENDING_GRP0 = mask_bits;
|
||||||
|
|
||||||
if ((mask_bits & 0x01) && int_handle_00) int_handle_00(); // Start of frame
|
if ((mask_bits & 0x01) && int_handle_00) int_handle_00(); // Start of frame
|
||||||
if ((mask_bits & 0x02) && int_handle_01) int_handle_01(); // Start of line
|
if ((mask_bits & 0x02) && int_handle_01) int_handle_01(); // Start of line
|
||||||
if ((mask_bits & 0x04) && int_handle_02) int_handle_02(); // PS/2 Keyboard
|
if ((mask_bits & 0x04) && int_handle_02) int_handle_02(); // PS/2 Keyboard
|
||||||
|
@ -513,42 +506,31 @@ void int_handle_irq() {
|
||||||
if ((mask_bits & 0x20) && int_handle_05) int_handle_05(); // Timer 1
|
if ((mask_bits & 0x20) && int_handle_05) int_handle_05(); // Timer 1
|
||||||
if ((mask_bits & 0x40) && int_handle_06) int_handle_06(); // Reserved
|
if ((mask_bits & 0x40) && int_handle_06) int_handle_06(); // Reserved
|
||||||
if ((mask_bits & 0x80) && int_handle_07) int_handle_07(); // Cartridge
|
if ((mask_bits & 0x80) && int_handle_07) int_handle_07(); // Cartridge
|
||||||
|
|
||||||
// Clear the pending bits for group 0
|
|
||||||
*PENDING_GRP0 = mask_bits;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process any pending interrupts in group 1
|
// Process any pending interrupts in group 1
|
||||||
mask_bits = *PENDING_GRP1;
|
mask_bits = *PENDING_GRP1;
|
||||||
if (mask_bits) {
|
if (mask_bits) {
|
||||||
volatile __attribute__((far)) char * text = (char *)0xafa000;
|
// Clear the pending bits for group 1
|
||||||
*text = *text + 1;
|
*PENDING_GRP1 = mask_bits;
|
||||||
|
|
||||||
if ((mask_bits & 0x01) && int_handle_10) {
|
if ((mask_bits & 0x01) && int_handle_10) int_handle_10(); // UART
|
||||||
volatile __attribute__((far)) char * text = (char *)0xafa001;
|
|
||||||
*text = *text + 1;
|
|
||||||
int_handle_10(); // PS/2 Keyboard
|
|
||||||
}
|
|
||||||
if ((mask_bits & 0x00) && int_handle_10) int_handle_10(); // UART
|
|
||||||
if ((mask_bits & 0x10) && int_handle_14) int_handle_14(); // RTC
|
if ((mask_bits & 0x10) && int_handle_14) int_handle_14(); // RTC
|
||||||
if ((mask_bits & 0x20) && int_handle_15) int_handle_15(); // VIA
|
if ((mask_bits & 0x20) && int_handle_15) int_handle_15(); // VIA
|
||||||
if ((mask_bits & 0x40) && int_handle_16) int_handle_16(); // F256K Matrix Keyboard
|
if ((mask_bits & 0x40) && int_handle_16) int_handle_16(); // F256K Matrix Keyboard
|
||||||
if ((mask_bits & 0x80) && int_handle_17) int_handle_17(); // SD card inserted
|
if ((mask_bits & 0x80) && int_handle_17) int_handle_17(); // SD card inserted
|
||||||
|
|
||||||
// Clear the pending bits for group 1
|
|
||||||
*PENDING_GRP1 = mask_bits;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process any pending interrupts in group 2
|
// Process any pending interrupts in group 2
|
||||||
mask_bits = *PENDING_GRP2;
|
mask_bits = *PENDING_GRP2;
|
||||||
if (mask_bits) {
|
if (mask_bits) {
|
||||||
if ((mask_bits & 0x01) && int_handle_20) int_handle_20(); // IED Data IN
|
|
||||||
if ((mask_bits & 0x02) && int_handle_21) int_handle_21(); // IED Clock IN
|
|
||||||
if ((mask_bits & 0x02) && int_handle_22) int_handle_22(); // IED ATN IN
|
|
||||||
if ((mask_bits & 0x02) && int_handle_22) int_handle_23(); // IED SREQ IN
|
|
||||||
|
|
||||||
// Clear the pending bits for group 2
|
// Clear the pending bits for group 2
|
||||||
*PENDING_GRP2 = mask_bits;
|
*PENDING_GRP2 = mask_bits;
|
||||||
|
|
||||||
|
if ((mask_bits & 0x01) && int_handle_20) int_handle_20(); // IED Data IN
|
||||||
|
if ((mask_bits & 0x02) && int_handle_21) int_handle_21(); // IED Clock IN
|
||||||
|
if ((mask_bits & 0x04) && int_handle_22) int_handle_22(); // IED ATN IN
|
||||||
|
if ((mask_bits & 0x08) && int_handle_22) int_handle_23(); // IED SREQ IN
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,16 +19,21 @@
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "errors.h"
|
||||||
#include "interrupt.h"
|
#include "interrupt.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "ps2_reg.h"
|
#include "ps2_reg.h"
|
||||||
#include "ring_buffer.h"
|
#include "ring_buffer.h"
|
||||||
#include "sys_macros.h"
|
#include "sys_macros.h"
|
||||||
|
#include "timers.h"
|
||||||
|
|
||||||
//
|
//
|
||||||
// Constants
|
// Constants
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#define KBD_TIMEOUT (60 * 5)
|
||||||
|
#define KBD_RETRIES 10
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Modifier bit flags
|
* Modifier bit flags
|
||||||
*/
|
*/
|
||||||
|
@ -143,17 +148,33 @@ static bool break_pressed = false;
|
||||||
// Code
|
// Code
|
||||||
//
|
//
|
||||||
|
|
||||||
static void kbd_send_cmd(uint8_t byte) {
|
/**
|
||||||
|
* Clear out the FIFO for the keyboard
|
||||||
|
*/
|
||||||
|
static void kbd_clear_fifo() {
|
||||||
|
*PS2_CTRL |= PS2_CTRL_KBD_CLR;
|
||||||
|
*PS2_CTRL &= ~PS2_CTRL_KBD_CLR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static short kbd_send_cmd(uint8_t byte) {
|
||||||
uint8_t status = 0;
|
uint8_t status = 0;
|
||||||
|
|
||||||
*PS2_OUT = byte;
|
*PS2_OUT = byte;
|
||||||
*PS2_CTRL |= PS2_CTRL_KBD_WR;
|
*PS2_CTRL |= PS2_CTRL_KBD_WR;
|
||||||
|
|
||||||
|
long timeout = timers_jiffies() + KBD_TIMEOUT;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
if (timeout < timers_jiffies()) {
|
||||||
|
*PS2_CTRL &= ~PS2_CTRL_KBD_WR;
|
||||||
|
return DEV_TIMEOUT;
|
||||||
|
}
|
||||||
status = *PS2_STAT;
|
status = *PS2_STAT;
|
||||||
} while ((status & (PS2_STAT_KBD_ACK | PS2_STAT_KBD_NAK)) == 0);
|
} while ((status & (PS2_STAT_KBD_ACK | PS2_STAT_KBD_NAK)) == 0);
|
||||||
|
|
||||||
*PS2_CTRL &= ~PS2_CTRL_KBD_WR;
|
*PS2_CTRL &= ~PS2_CTRL_KBD_WR;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -406,7 +427,7 @@ static void kbd_process_set2_bytecode(uint8_t byte_code) {
|
||||||
*/
|
*/
|
||||||
SYSTEMCALL void kbd_handle_irq() {
|
SYSTEMCALL void kbd_handle_irq() {
|
||||||
// Check to see if there is a keyboard bytecode waiting... process it if so
|
// Check to see if there is a keyboard bytecode waiting... process it if so
|
||||||
if ((*PS2_STAT & PS2_STAT_KBD_EMP) == 0) {
|
while ((*PS2_STAT & PS2_STAT_KBD_EMP) == 0) {
|
||||||
kbd_process_set2_bytecode(*PS2_KBD_IN);
|
kbd_process_set2_bytecode(*PS2_KBD_IN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -445,6 +466,11 @@ bool kbd_break() {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
short kbd_sc_init() {
|
short kbd_sc_init() {
|
||||||
|
short result = 0;
|
||||||
|
|
||||||
|
// Make sure the keyboard interrupt is disabled
|
||||||
|
int_disable(INT_KBD_PS2);
|
||||||
|
|
||||||
// Initialize the keyboard buffers
|
// Initialize the keyboard buffers
|
||||||
rb_word_init(&scan_code_buffer);
|
rb_word_init(&scan_code_buffer);
|
||||||
rb_word_init(&char_buffer);
|
rb_word_init(&char_buffer);
|
||||||
|
@ -454,11 +480,50 @@ short kbd_sc_init() {
|
||||||
modifiers = 0;
|
modifiers = 0;
|
||||||
break_pressed = false;
|
break_pressed = false;
|
||||||
|
|
||||||
|
// Reset the keyboard
|
||||||
|
result = kbd_send_cmd(0xff);
|
||||||
|
if (result < 0) {
|
||||||
|
INFO1("PS/2: unable to reset the keyboard: %s", err_message(ressult));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
INFO("kbd_sc_init: ps/2 keyboard reset");
|
||||||
|
|
||||||
|
kbd_clear_fifo();
|
||||||
|
|
||||||
|
// Disable scanning
|
||||||
|
result = kbd_send_cmd(0xf5);
|
||||||
|
if (result < 0) {
|
||||||
|
INFO1("PS/2: unable to disable keyboard scanning: %s", err_message(ressult));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
INFO("kbd_sc_init: ps/2 scanning disabled");
|
||||||
|
|
||||||
|
// Set scan code set #2
|
||||||
|
result = kbd_send_cmd(0xf0);
|
||||||
|
if (result < 0) {
|
||||||
|
INFO1("PS/2: unable to set scan code: %s", err_message(ressult));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = kbd_send_cmd(0x02);
|
||||||
|
if (result < 0) {
|
||||||
|
INFO1("PS/2: unable to send scan code set: %s", err_message(ressult));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
INFO("kbd_sc_init: ps/2 scan code set #2 selected");
|
||||||
|
|
||||||
|
// Enable scanning
|
||||||
|
result = kbd_send_cmd(0xf4);
|
||||||
|
if (result < 0) {
|
||||||
|
INFO1("PS/2: unable to restart keyboard scanning: %s", err_message(ressult));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
INFO("kbd_sc_init: ps/2 scanning enabled");
|
||||||
|
|
||||||
// Register and enable the PS/2 interrupt handler
|
// Register and enable the PS/2 interrupt handler
|
||||||
int_register(INT_KBD_PS2, (p_int_handler)kbd_handle_irq);
|
int_register(INT_KBD_PS2, (p_int_handler)kbd_handle_irq);
|
||||||
int_enable(INT_KBD_PS2);
|
int_enable(INT_KBD_PS2);
|
||||||
|
|
||||||
return 0;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -23,6 +23,7 @@
|
||||||
#include "interrupt.h"
|
#include "interrupt.h"
|
||||||
#include "F256/sdc_spi.h"
|
#include "F256/sdc_spi.h"
|
||||||
#include "sdc_f256.h"
|
#include "sdc_f256.h"
|
||||||
|
#include "utilities.h"
|
||||||
|
|
||||||
/* MMC/SD command (SPI mode) */
|
/* MMC/SD command (SPI mode) */
|
||||||
#define CMD0 (0) /* GO_IDLE_STATE */
|
#define CMD0 (0) /* GO_IDLE_STATE */
|
||||||
|
@ -379,7 +380,7 @@ static short sdc_read(p_dev_block dev, long lba, uint8_t * buffer, short size) {
|
||||||
p_sd_card_info card = (p_sd_card_info)dev->data;
|
p_sd_card_info card = (p_sd_card_info)dev->data;
|
||||||
p_sdc_spi sd = card->reg;
|
p_sdc_spi sd = card->reg;
|
||||||
uint8_t cmd;
|
uint8_t cmd;
|
||||||
short count = size % 512 + 1;
|
short count = ceil_div_short(size, 512);
|
||||||
|
|
||||||
if (card->status & SDC_STAT_NOINIT) {
|
if (card->status & SDC_STAT_NOINIT) {
|
||||||
return ERR_NOT_READY;
|
return ERR_NOT_READY;
|
||||||
|
@ -420,7 +421,7 @@ static short sdc_write(p_dev_block dev, long lba, const uint8_t * buffer, short
|
||||||
p_sd_card_info card = (p_sd_card_info)dev->data;
|
p_sd_card_info card = (p_sd_card_info)dev->data;
|
||||||
p_sdc_spi sd = card->reg;
|
p_sdc_spi sd = card->reg;
|
||||||
uint8_t cmd;
|
uint8_t cmd;
|
||||||
short count = size % 512 + 1;
|
short count = ceil_div_short(size, 512);
|
||||||
|
|
||||||
if (card->status & SDC_STAT_NOINIT) {
|
if (card->status & SDC_STAT_NOINIT) {
|
||||||
return ERR_NOT_READY;
|
return ERR_NOT_READY;
|
||||||
|
|
|
@ -406,15 +406,60 @@ static short txt_f256_set_color(unsigned char foreground, unsigned char backgrou
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern void io_copy_down(uint16_t count, uint16_t dest, uint16_t src);
|
||||||
|
extern void io_copy_up(uint16_t count, uint16_t dest, uint16_t src);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy data in the I/O space using the MVN/MVP instructions
|
||||||
|
*
|
||||||
|
* @param count the number of bytes to copy
|
||||||
|
* @param dest the address within the I/O bank to copy to
|
||||||
|
* @param src the address within the I/O bank to copy from
|
||||||
|
*/
|
||||||
|
static void io_copy(uint16_t count, uint16_t dest, uint16_t src) {
|
||||||
|
if (dest < src) {
|
||||||
|
io_copy_down(count, dest, src);
|
||||||
|
} else {
|
||||||
|
io_copy_up(count, dest, src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scroll the screen for the most common case: full screen scrolls up by one full row.
|
||||||
|
*/
|
||||||
|
static void txt_f256_scroll_simple() {
|
||||||
|
uint16_t rows = f256_max_size.height;
|
||||||
|
uint16_t columns = f256_max_size.width;
|
||||||
|
uint16_t count = (rows - 1) * columns;
|
||||||
|
|
||||||
|
// Move the rows up
|
||||||
|
uint16_t text_dest = (uint16_t)((uint32_t)tvky_text_matrix & 0xffff);
|
||||||
|
uint16_t text_src = text_dest + columns;
|
||||||
|
io_copy_down(count, text_dest, text_src);
|
||||||
|
|
||||||
|
uint16_t color_dest = (uint16_t)((uint32_t)tvky_color_matrix & 0xffff);
|
||||||
|
uint16_t color_src = color_dest + columns;
|
||||||
|
io_copy_down(count, color_dest, color_src);
|
||||||
|
|
||||||
|
// Clear the bottom line
|
||||||
|
for (uint16_t i = count; i < rows * columns; i++) {
|
||||||
|
tvky_text_matrix[i] = ' ';
|
||||||
|
tvky_color_matrix[i] = f256_color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scroll the text in the current region
|
* Scroll the text in the current region
|
||||||
|
*
|
||||||
|
* Supports the general case
|
||||||
*
|
*
|
||||||
* @param screen the number of the text device
|
* @param screen the number of the text device
|
||||||
* @param horizontal the number of columns to scroll (negative is left, positive is right)
|
* @param horizontal the number of columns to scroll (negative is left, positive is right)
|
||||||
* @param vertical the number of rows to scroll (negative is down, positive is up)
|
* @param vertical the number of rows to scroll (negative is down, positive is up)
|
||||||
*/
|
*/
|
||||||
static void txt_f256_scroll(short horizontal, short vertical) {
|
static void txt_f256_scroll_complex(short horizontal, short vertical) {
|
||||||
short x, x0, x1, x2, x3, dx;
|
short x, x0, x1, x2, x3, dx;
|
||||||
short y, y0, y1, y2, y3, dy;
|
short y, y0, y1, y2, y3, dy;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -468,12 +513,24 @@ static void txt_f256_scroll(short horizontal, short vertical) {
|
||||||
row_src += delta_y;
|
row_src += delta_y;
|
||||||
int offset_dst = row_dst + x0 - dx;
|
int offset_dst = row_dst + x0 - dx;
|
||||||
int offset_src = row_src + horizontal + x0 - dx;
|
int offset_src = row_src + horizontal + x0 - dx;
|
||||||
for (x = x0; x != x2; x += dx) {
|
|
||||||
offset_dst += dx;
|
// Move the rows up
|
||||||
offset_src += dx;
|
uint16_t count = x2 - x0;
|
||||||
tvky_text_matrix[offset_dst] = tvky_text_matrix[offset_src];
|
|
||||||
tvky_color_matrix[offset_dst] = tvky_color_matrix[offset_src];
|
uint16_t text_dest = (uint16_t)((uint32_t)tvky_text_matrix & 0xffff) + offset_dst;
|
||||||
}
|
uint16_t text_src = (uint16_t)((uint32_t)tvky_text_matrix & 0xffff) + offset_src;
|
||||||
|
io_copy(count, text_dest, text_src);
|
||||||
|
|
||||||
|
uint16_t color_dest = (uint16_t)((uint32_t)tvky_color_matrix & 0xffff) + offset_dst;
|
||||||
|
uint16_t color_src = (uint16_t)((uint32_t)tvky_color_matrix & 0xffff) + offset_src;
|
||||||
|
io_copy(count, color_dest, color_src);
|
||||||
|
|
||||||
|
// for (x = x0; x != x2; x += dx) {
|
||||||
|
// offset_dst += dx;
|
||||||
|
// offset_src += dx;
|
||||||
|
// tvky_text_matrix[offset_dst] = tvky_text_matrix[offset_src];
|
||||||
|
// tvky_color_matrix[offset_dst] = tvky_color_matrix[offset_src];
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear the rectangles */
|
/* Clear the rectangles */
|
||||||
|
@ -499,6 +556,22 @@ static void txt_f256_scroll(short horizontal, short vertical) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Scroll the text in the current region
|
||||||
|
*
|
||||||
|
* @param horizontal the number of columns to scroll (negative is left, positive is right)
|
||||||
|
* @param vertical the number of rows to scroll (negative is down, positive is up)
|
||||||
|
*/
|
||||||
|
static void txt_f256_scroll(short horizontal, short vertical) {
|
||||||
|
// If we're scrolling up one, and the region is the full screen, use a faster scrolling routine
|
||||||
|
if ((horizontal == 0) && (vertical == 1) &&
|
||||||
|
(f256_region.origin.x == 0) && (f256_region.origin.y == 0) &&
|
||||||
|
(f256_region.size.width == f256_max_size.width) && (f256_region.size.height == f256_max_size.height)) {
|
||||||
|
txt_f256_scroll_simple();
|
||||||
|
} else {
|
||||||
|
txt_f256_scroll_complex(horizontal, vertical);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fill the current region with a character in the current color
|
* Fill the current region with a character in the current color
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "log_level.h"
|
#include "log_level.h"
|
||||||
#define DEFAULT_LOG_LEVEL LOG_INFO
|
#define DEFAULT_LOG_LEVEL LOG_ERROR
|
||||||
#define LOG_CHANNEL LOG_CHANNEL_UART0
|
#define LOG_CHANNEL LOG_CHANNEL_CHANNEL_A
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
|
@ -7,6 +7,16 @@
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the ceiling of a/b using only short operations
|
||||||
|
*
|
||||||
|
* @param a the numerator
|
||||||
|
* @param b the denominator
|
||||||
|
* @return the smallest short c such that c >= a / b
|
||||||
|
*/
|
||||||
|
short ceil_div_short(short a, short b) {
|
||||||
|
return (a + (b - 1)) / b;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Re-entrant version of strtok_r, because VBCC does not provide it
|
* Re-entrant version of strtok_r, because VBCC does not provide it
|
||||||
|
|
|
@ -13,6 +13,15 @@
|
||||||
/** Return the maximum value of x or y */
|
/** Return the maximum value of x or y */
|
||||||
#define max(x, y) ((x < y) ? y : x)
|
#define max(x, y) ((x < y) ? y : x)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the ceiling of a/b using only short operations
|
||||||
|
*
|
||||||
|
* @param a the numerator
|
||||||
|
* @param b the denominator
|
||||||
|
* @return the smallest short c such that c >= a / b
|
||||||
|
*/
|
||||||
|
extern short ceil_div_short(short a, short b);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Re-entrant version of strtok_r, because VBCC does not provide it
|
* Re-entrant version of strtok_r, because VBCC does not provide it
|
||||||
*
|
*
|
||||||
|
|
|
@ -7,6 +7,6 @@
|
||||||
|
|
||||||
#define VER_MAJOR 1
|
#define VER_MAJOR 1
|
||||||
#define VER_MINOR 1
|
#define VER_MINOR 1
|
||||||
#define VER_BUILD 9
|
#define VER_BUILD 29
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue