#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#define PS2_KC_BKSP 0x80
#define PS2_KC_UP 0x81
#define PS2_KC_DOWN 0x82
#define PS2_KC_LEFT 0x83
#define PS2_KC_RIGHT 0x84
#define PS2_KC_PGDN 0x85
#define PS2_KC_PGUP 0x86
#define PS2_KC_END 0x87
#define PS2_KC_HOME 0x88
#define PS2_KC_INS 0x89
#define PS2_KC_DEL 0x8A
#define PS2_KC_ESC 0x8B
#define PS2_KC_CLON 0x8C // caps_lock on
#define PS2_KC_CLOFF 0x8D // caps_lock off
const byte MSPIM_SCK = 0;
byte PROGMEM charROM [1024] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E,
0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E,
0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00,
0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00,
0x38, 0x7C, 0x38, 0xFE, 0xFE, 0x7C, 0x38, 0x7C,
0x10, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C,
0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00,
0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF,
0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00,
0xFF, 0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF,
0x0F, 0x07, 0x0F, 0x7D, 0xCC, 0xCC, 0xCC, 0x78,
0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18,
0x3F, 0x33, 0x3F, 0x30, 0x30, 0x70, 0xF0, 0xE0,
0x7F, 0x63, 0x7F, 0x63, 0x63, 0x67, 0xE6, 0xC0,
0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99,
0x80, 0xE0, 0xF8, 0xFE, 0xF8, 0xE0, 0x80, 0x00,
0x02, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x02, 0x00,
0x18, 0x3C, 0x7E, 0x18, 0x18, 0x7E, 0x3C, 0x18,
0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00,
0x7F, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x00,
0x3E, 0x63, 0x38, 0x6C, 0x6C, 0x38, 0xCC, 0x78,
0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x00,
0x18, 0x3C, 0x7E, 0x18, 0x7E, 0x3C, 0x18, 0xFF,
0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x00,
0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00,
0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00,
0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00,
0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00,
0x00, 0x24, 0x66, 0xFF, 0x66, 0x24, 0x00, 0x00,
0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00,
0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00,
0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00,
0x30, 0x7C, 0xC0, 0x78, 0x0C, 0xF8, 0x30, 0x00,
0x00, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xC6, 0x00,
0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00,
0x60, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00,
0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00,
0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00,
0x00, 0x30, 0x30, 0xFC, 0x30, 0x30, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60,
0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00,
0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00,
0x7C, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0x7C, 0x00,
0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xFC, 0x00,
0x78, 0xCC, 0x0C, 0x38, 0x60, 0xCC, 0xFC, 0x00,
0x78, 0xCC, 0x0C, 0x38, 0x0C, 0xCC, 0x78, 0x00,
0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x1E, 0x00,
0xFC, 0xC0, 0xF8, 0x0C, 0x0C, 0xCC, 0x78, 0x00,
0x38, 0x60, 0xC0, 0xF8, 0xCC, 0xCC, 0x78, 0x00,
0xFC, 0xCC, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00,
0x78, 0xCC, 0xCC, 0x78, 0xCC, 0xCC, 0x78, 0x00,
0x78, 0xCC, 0xCC, 0x7C, 0x0C, 0x18, 0x70, 0x00,
0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00,
0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60,
0x18, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x18, 0x00,
0x00, 0x00, 0xFC, 0x00, 0x00, 0xFC, 0x00, 0x00,
0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00,
0x78, 0xCC, 0x0C, 0x18, 0x30, 0x00, 0x30, 0x00,
0x7C, 0xC6, 0xDE, 0xDE, 0xDE, 0xC0, 0x78, 0x00,
0x30, 0x78, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0x00,
0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00,
0x3C, 0x66, 0xC0, 0xC0, 0xC0, 0x66, 0x3C, 0x00,
0xF8, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00,
0xFE, 0x62, 0x68, 0x78, 0x68, 0x62, 0xFE, 0x00,
0xFE, 0x62, 0x68, 0x78, 0x68, 0x60, 0xF0, 0x00,
0x3C, 0x66, 0xC0, 0xC0, 0xCE, 0x66, 0x3E, 0x00,
0xCC, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0xCC, 0x00,
0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
0x1E, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00,
0xE6, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00,
0xF0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00,
0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00,
0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0xC6, 0x00,
0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00,
0xFC, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00,
0x78, 0xCC, 0xCC, 0xCC, 0xDC, 0x78, 0x1C, 0x00,
0xFC, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0xE6, 0x00,
0x78, 0xCC, 0xE0, 0x70, 0x1C, 0xCC, 0x78, 0x00,
0xFC, 0xB4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFC, 0x00,
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00,
0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0xEE, 0xC6, 0x00,
0xC6, 0xC6, 0x6C, 0x38, 0x38, 0x6C, 0xC6, 0x00,
0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x78, 0x00,
0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xFE, 0x00,
0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00,
0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00,
0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00,
0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xDC, 0x00,
0x00, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00,
0x1C, 0x0C, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00,
0x00, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00,
0x38, 0x6C, 0x60, 0xF0, 0x60, 0x60, 0xF0, 0x00,
0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8,
0xE0, 0x60, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00,
0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
0x0C, 0x00, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78,
0xE0, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x00,
0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
0x00, 0x00, 0xCC, 0xFE, 0xFE, 0xD6, 0xC6, 0x00,
0x00, 0x00, 0xF8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00,
0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00,
0x00, 0x00, 0xDC, 0x66, 0x66, 0x7C, 0x60, 0xF0,
0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E,
0x00, 0x00, 0xDC, 0x76, 0x66, 0x60, 0xF0, 0x00,
0x00, 0x00, 0x7C, 0xC0, 0x78, 0x0C, 0xF8, 0x00,
0x10, 0x30, 0x7C, 0x30, 0x30, 0x34, 0x18, 0x00,
0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00,
0x00, 0x00, 0xC6, 0xD6, 0xFE, 0xFE, 0x6C, 0x00,
0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00,
0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8,
0x00, 0x00, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00,
0x1C, 0x30, 0x30, 0xE0, 0x30, 0x30, 0x1C, 0x00,
0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00,
0xE0, 0x30, 0x30, 0x1C, 0x30, 0x30, 0xE0, 0x00,
0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00,
};
unsigned int scanline=0;
unsigned int videoptr=0;
volatile byte VBE=0;
byte xpos=0;
byte ypos=0;
byte txtback=0;
byte txtfore=255;
boolean ps2Keyboard_shift; // indicates shift key is pressed
boolean ps2Keyboard_ctrl; // indicates the ctrl key is pressed
boolean ps2Keyboard_alt; // indicates the alt key is pressed
boolean ps2Keyboard_extend; // remembers a keyboard extended char received
boolean ps2Keyboard_release; // distinguishes key presses from releases
boolean ps2Keyboard_caps_lock; // remembers shift lock has been pressed
char videomem[8000];
void setup() {
//Setup for NTSC with 14.318MHz Fcpu clock
UBRR0 = 0; // must be zero before enabling the transmitter
UCSR0A = _BV (TXC0); // any old transmit now complete
pinMode (MSPIM_SCK, OUTPUT); // set XCK pin as output to enable master mode
UCSR0C = _BV (UMSEL00) | _BV (UMSEL01); // Master SPI mode
UCSR0B = _BV (TXEN0); // transmit enable
// must be done last, see page 206
UBRR0 = 0; // 7.16MHz pixel clock
pinMode(15, OUTPUT); //Set PD7 as output for Sync
pinMode(8, OUTPUT); //Set PD0 as output for video
cli();
//set timer0 interrupt at 15699Hz
TCCR0A = 0;// set entire TCCR0A register to 0
TCCR0B = 0;// same for TCCR0B
TCNT0 = 0;//initialize counter value to 0
// set compare match register for 15699hz increments
OCR0A = 113;// = (16*10^6) / (15699*8) - 1 (must be <256)
// turn on CTC mode
TCCR0A |= (1 << WGM01);
// Set CS01 and CS00 bits for 9 prescaler
TCCR0B |= (1 << CS01) | (0 << CS00);
// enable timer compare interrupt
TIMSK0 |= (1 << OCIE0A);
set_sleep_mode (SLEEP_MODE_IDLE);
sei();
//------------ PS/2 Keyboard setup ----------------------------
// Enable receiver
UCSR1B = 16 | 8;
/* Set frame format: 1data, 1parity, 1stop bit */
UCSR1C = 64 | 6;
ps2Keyboard_shift = false;
ps2Keyboard_ctrl = false;
ps2Keyboard_alt = false;
ps2Keyboard_extend = false;
ps2Keyboard_release = false;
ps2Keyboard_caps_lock = false;
//----------------------------------------------------------------------------------------------
for (int x=0; x <8000; x++){
videomem[x]=B01010101;
}
}
void TVdelay(unsigned int millisec) {
unsigned long cnt=millisec*100L;
for (unsigned long x=0; x < cnt; x++){
while (VBE==1) sleep_cpu();
}
}
void loop() {
TVdelay(100); //Dont use delay() to make delays, but TVdelay(millis) to do delays, there is no delay function.
printstring("\x80\x87\fBambino BIOS v1.01\n\n\n"); //clear the screen with BGcolor black and FGcolor white.
printstring("VideoBlaster v1.05\n");
while(-1) {
while (VBE==1) sleep_cpu();
//If VBE=1 the CPU have to sleep for the video to be smooth.
//put anything you like in this loop but make sure it returns before the next frame is painted.
// Use printstring(string) to write an entier string to chrout.
// Use chrout(char ascii) to write a singel char to the terminal screen. chr x80 - x87 sets BG and FG attributes.
// Use chrin() to read a singel char from the keyboard.
// use pset(x,y) to set a single dot on the 320x200 screen.
// Use point(x,y,c) to set a color dot on the 320x200 screen (c is color 0-3).
// All the other functions are used by the Bambino BIOS and wont remain the same in the future.
// Dont touch the variables scanline and videoptr, they are not volatile on purpose because of speed reasons.
}
}
ISR(TIMER0_COMPA_vect){//timer0 interrupt
asm("nop\n");
byte p=40;
UCSR0C = 192;
UCSR0B = _BV(TXEN0);
PORTD = 0;
if ((scanline>2)&&(scanline<40)||(scanline>239)) {
UCSR0B = 0;
asm("nop\n");
asm("nop\n");
asm("nop\n"); // Dont touch any of these NOPs
asm("nop\n"); // They are all here for timing.
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
PORTD =128;
VBE=0;
}
if (scanline<3) {
UCSR0B = 0;
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
PORTD =0;
videoptr=0;
}
if ((scanline>39)&&(scanline<240)) {
UDR0 = 0x00; //Load first byte
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
//asm("nop\n");
PORTD =128;
VBE=1;
//asm("nop\n");
//asm("nop\n");
//Color burst
UDR0 = B00001010;
UDR0 = B10101010;
while ((UCSR0A & _BV (UDRE0)) == 0)
{}
UDR0 = B10101000;
while ((UCSR0A & _BV (UDRE0)) == 0)
{}
UDR0 = B00000000;
while ((UCSR0A & _BV (UDRE0)) == 0)
{}
//Back porch
UCSR0C = 193; //This is the phasechange to the colorburst. If you put 192 here instead, you will get blue/green as colors.
UDR0 = B00000000;
while ((UCSR0A & _BV (UDRE0)) == 0)
{}
UDR0 = B00000000;
while ((UCSR0A & _BV (UDRE0)) == 0)
{}
//UDR0 = B00000000;
//UCSR0C = 193;
UDR0 = 0;
while (p--) {
while ((UCSR0A & _BV (UDRE0)) == 0)
{}
UDR0 = videomem[videoptr++];
}
}
UCSR0B = 0;
scanline++;
if (scanline>261) scanline=0;
}
void pset(unsigned int x,unsigned y) {
unsigned int pixelbyte=videoptr+(y*40)+(x>>3);
videomem[pixelbyte]=videomem[pixelbyte] | (128>>(x&7));
}
void point(unsigned int x,unsigned y,byte color) {
x=x&510;
color=((color<<6)&192)>>(x&7);
unsigned int pixelbyte=videoptr+(y*40)+(x>>3);
byte mask=255-(192>>(x&7));
videomem[pixelbyte]=videomem[pixelbyte] & mask | color;
}
void screenclr(byte bgcolor) {
bgcolor=bgcolor&3;
bgcolor=bgcolor | (bgcolor<<2);
bgcolor=bgcolor | (bgcolor<<4);
for (int x=0; x <8000; x++){
videomem[x]=bgcolor;
}
xpos=0;
ypos=0;
}
void drawchar(byte x,byte y,byte ascii) {
if ((x<40)&&(y<25)) {
for (byte i=0; i < 8; i++) {
byte mask=(255-pgm_read_byte(&charROM[(ascii*8)+i]))&txtback;
videomem[(y*320)+x+(i*40)]=(pgm_read_byte(&charROM[(ascii*8)+i])&txtfore)|mask;
}
}
}
void chrout(char ascii) {
switch (ascii) {
case 13:
xpos=0;
ypos++;
if (ypos>24) {
scrollscr();
xpos=0;
ypos=24;
}
break;
case 10:
xpos=0;
ypos++;
if (ypos>24) {
scrollscr();
xpos=0;
ypos=24;
}
break;
case 12:
screenclr(txtback&3);
xpos=0;
ypos=0;
break;
case 0x80:
settxtBGcolor(0);
break;
case 0x81:
settxtBGcolor(1);
break;
case 0x82:
settxtBGcolor(2);
break;
case 0x83:
settxtBGcolor(3);
break;
case 0x84:
settxtFGcolor(0);
break;
case 0x85:
settxtFGcolor(1);
break;
case 0x86:
settxtFGcolor(2);
break;
case 0x87:
settxtFGcolor(3);
break;
default:
drawchar(xpos,ypos,ascii);
xpos++;
if (xpos>39) {
xpos=0;
ypos++;
if (ypos>24) {
scrollscr();
xpos=0;
ypos=24;
}
}
}
}
void scrollscr() {
for (unsigned int i=320; i < 8000; i++) {
videomem[i-320]=videomem[i];
}
for (unsigned int i=7680; i < 8000; i++) {
videomem[i]=0;
}
}
void settxtBGcolor(byte color) {
color=color&3;
color=color | (color<<2);
color=color | (color<<4);
txtback=color;
}
void settxtFGcolor(byte color) {
color=color&3;
color=color | (color<<2);
color=color | (color<<4);
txtfore=color;
}
void printstring(char string[]) {
byte i=0;
while(string[i]) {
chrout(string[i++]);
}
}
char chrin() {
byte result=0;
byte realkey=0;
if (UCSR1A&128) {
result=UDR1;
switch (result) {
case 0xF0: { // key release char
ps2Keyboard_release = true;
ps2Keyboard_extend = false;
result=0;
break;
}
case 0xFA: { // command acknowlegde byte
break;
}
case 0xE0: { // extended char set
ps2Keyboard_extend = true;
break;
}
case 0x12: // left shift
case 0x59: { // right shift
ps2Keyboard_shift = ps2Keyboard_release? false : true;
ps2Keyboard_release = false;
result=0;
break;
}
case 0x11: { // alt key (right alt is extended 0x11)
ps2Keyboard_alt = ps2Keyboard_release? false : true;
ps2Keyboard_release = false;
result=0;
break;
}
case 0x14: { // ctrl key (right ctrl is extended 0x14)
ps2Keyboard_ctrl = ps2Keyboard_release? false : true;
ps2Keyboard_release = false;
break;
}
case 0x58: { // caps lock key
if (!ps2Keyboard_release) {
ps2Keyboard_caps_lock = ps2Keyboard_caps_lock? false : true;
}
else {
ps2Keyboard_release = false;
}
result=0;
break;
}
default: { // a real key
if (ps2Keyboard_release) { // although ignore if its just released
ps2Keyboard_release = false;
result=0;
}
else { // real keys go into CharBuffer
realkey=result;
}
}
}
switch (result) {
case 0x1C: result = 'a'; break;
case 0x32: result = 'b'; break;
case 0x21: result = 'c'; break;
case 0x23: result = 'd'; break;
case 0x24: result = 'e'; break;
case 0x2B: result = 'f'; break;
case 0x34: result = 'g'; break;
case 0x33: result = 'h'; break;
case 0x43: result = 'i'; break;
case 0x3B: result = 'j'; break;
case 0x42: result = 'k'; break;
case 0x4B: result = 'l'; break;
case 0x3A: result = 'm'; break;
case 0x31: result = 'n'; break;
case 0x44: result = 'o'; break;
case 0x4D: result = 'p'; break;
case 0x15: result = 'q'; break;
case 0x2D: result = 'r'; break;
case 0x1B: result = 's'; break;
case 0x2C: result = 't'; break;
case 0x3C: result = 'u'; break;
case 0x2A: result = 'v'; break;
case 0x1D: result = 'w'; break;
case 0x22: result = 'x'; break;
case 0x35: result = 'y'; break;
case 0x1A: result = 'z'; break;
// note that caps lock only used on a-z
case 0x41: result = ps2Keyboard_shift? ';' : ','; break;
case 0x49: result = ps2Keyboard_shift? ':' : '.'; break;
case 0x4A: result = ps2Keyboard_shift? '?' : '/'; break;
case 0x54: result = ps2Keyboard_shift? '{' : '['; break;
case 0x5B: result = ps2Keyboard_shift? '}' : ']'; break;
case 0x4E: result = ps2Keyboard_shift? '_' : '-'; break;
case 0x55: result = ps2Keyboard_shift? '+' : '='; break;
case 0x29: result = ' '; break;
case 0x45: result = ps2Keyboard_shift? '=' : '0'; break;
case 0x16: result = ps2Keyboard_shift? '!' : '1'; break;
case 0x1E: result = ps2Keyboard_shift? 0x22 : '2'; break;
case 0x26: result = ps2Keyboard_shift? '#' : '3'; break;
case 0x25: result = ps2Keyboard_shift? '$' : '4'; break;
case 0x2E: result = ps2Keyboard_shift? '%' : '5'; break;
case 0x36: result = ps2Keyboard_shift? '&' : '6'; break;
case 0x3D: result = ps2Keyboard_shift? '/' : '7'; break;
case 0x3E: result = ps2Keyboard_shift? '(' : '8'; break;
case 0x46: result = ps2Keyboard_shift? ')' : '9'; break;
case 0x0D: result = '\t'; break;
case 0x5A: result = 13; break;
case 0x66: result = PS2_KC_BKSP; break;
case 0x69: result = ps2Keyboard_extend? PS2_KC_END : '1'; break;
case 0x6B: result = ps2Keyboard_extend? PS2_KC_LEFT : '4'; break;
case 0x6C: result = ps2Keyboard_extend? PS2_KC_HOME : '7'; break;
case 0x70: result = ps2Keyboard_extend? PS2_KC_INS : '0'; break;
case 0x71: result = ps2Keyboard_extend? PS2_KC_DEL : '.'; break;
case 0x72: result = ps2Keyboard_extend? PS2_KC_DOWN : '2'; break;
case 0x73: result = '5'; break;
case 0x74: result = ps2Keyboard_extend? PS2_KC_RIGHT : '6'; break;
case 0x75: result = ps2Keyboard_extend? PS2_KC_UP : '8'; break;
case 0x76: result = PS2_KC_ESC; break;
case 0x79: result = '+'; break;
case 0x7A: result = ps2Keyboard_extend? PS2_KC_PGDN : '3'; break;
case 0x7B: result = '-'; break;
case 0x7C: result = '*'; break;
case 0x7D: result = ps2Keyboard_extend? PS2_KC_PGUP : '9'; break;
} // end switch(result)
}
if (((result>='a') && (result<='z')) &&
((ps2Keyboard_shift && !ps2Keyboard_caps_lock) ||
(!ps2Keyboard_shift && ps2Keyboard_caps_lock))) {
result = result + ('A'-'a');
}
return result;
}