Quantum Leaps 696f5cef7b 4.5.02
2012-08-14 18:07:04 -04:00

317 lines
15 KiB
C

/*****************************************************************************
* Product: VGA screen output
* Last Updated for Version: 4.1.01
* Date of the Last Update: Nov 03, 2009
*
* Q u a n t u m L e a P s
* ---------------------------
* innovating embedded systems
*
* Copyright (C) 2002-2008 Quantum Leaps, LLC. All rights reserved.
*
* This software may be distributed and modified under the terms of the GNU
* General Public License version 2 (GPL) as published by the Free Software
* Foundation and appearing in the file GPL.TXT included in the packaging of
* this file. Please note that GPL Section 2[b] requires that all works based
* on this software must also be made publicly available under the terms of
* the GPL ("Copyleft").
*
* Alternatively, this software may be distributed and modified under the
* terms of Quantum Leaps commercial licenses, which expressly supersede
* the GPL and are specifically designed for licensees interested in
* retaining the proprietary status of their code.
*
* Contact information:
* Quantum Leaps Web site: http://www.quantum-leaps.com
* e-mail: info@quantum-leaps.com
*****************************************************************************/
#include "qp_port.h"
#include "video.h"
#include <conio.h>
#include <stdlib.h>
Q_DEFINE_THIS_FILE
#define VIDEO_BASE 0xB800
#define VIDEO_WIDTH 80
#define VIDEO_HEIGHT 25
#define OFF(x_, y_) ((((y_) * VIDEO_WIDTH) + (x_)) * 2)
/*..........................................................................*/
void Video_clearScreen(uint8_t bgColor) {
system("CLS");
Video_clearRect(0, 0, VIDEO_WIDTH, VIDEO_HEIGHT, bgColor);
}
/*..........................................................................*/
void Video_clearRect(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2,
uint8_t bgColor)
{
uint8_t far *pscrX = (uint8_t far *)MK_FP(VIDEO_BASE,
(uint16_t)(((y1 * VIDEO_WIDTH) + x1) * 2));
x2 -= x1;
y2 -= y1;
for (x1 = 0; x1 < x2; ++x1, pscrX += 2) { /* loop over x */
uint8_t far *pscrXY = pscrX;
for (y1 = 0; y1 < y2; ++y1, pscrXY += 2*VIDEO_WIDTH) {
pscrXY[0] = 0x20; /* Put space in video RAM */
pscrXY[1] = bgColor; /* Put video attribute in video RAM */
}
}
}
/*..........................................................................*/
void Video_drawRect(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2,
uint8_t fgColor, uint8_t line)
{
uint8_t far *pscr = (uint8_t far *)MK_FP(VIDEO_BASE, 0);
uint16_t off;
uint8_t xy;
static uint8_t const line_char[][6] = {
{ ' ', ' ', ' ', ' ', ' ', ' ' },
{ 0xDA, 0xBF, 0xC0, 0xD9, 0xC4, 0xB3 },
{ 0xC9, 0xBB, 0xC8, 0xBC, 0xCD, 0xBA }
};
enum {
UL_CORNER,
UR_CORNER,
LL_CORNER,
LR_CORNER,
HOR_LINE,
VER_LINE
};
Q_REQUIRE(line < Q_DIM(line_char));
off = OFF(x1, y1);
pscr[off] = line_char[line][UL_CORNER];
pscr[off + 1] &= ~0x0F; /* clear the foreground color */
pscr[off + 1] |= fgColor; /* Put video attribute in video RAM */
off = OFF(x2 - 1, y1);
pscr[off] = line_char[line][UR_CORNER];
pscr[off + 1] &= ~0x0F; /* clear the foreground color */
pscr[off + 1] |= fgColor; /* Put video attribute in video RAM */
off = OFF(x1, y2 - 1);
pscr[off] = line_char[line][LL_CORNER];
pscr[off + 1] &= ~0x0F; /* clear the foreground color */
pscr[off + 1] |= fgColor; /* Put video attribute in video RAM */
off = OFF(x2 - 1, y2 - 1);
pscr[off] = line_char[line][LR_CORNER];
pscr[off + 1] &= ~0x0F; /* clear the foreground color */
pscr[off + 1] |= fgColor; /* Put video attribute in video RAM */
for (xy = x1 + 1; xy < x2 - 1; ++xy) {
off = OFF(xy, y1);
pscr[off] = line_char[line][HOR_LINE];
pscr[off + 1] &= ~0x0F; /* clear the foreground color */
pscr[off + 1] |= fgColor; /* Put video attribute in video RAM */
off = OFF(xy, y2 - 1);
pscr[off] = line_char[line][HOR_LINE];
pscr[off + 1] &= ~0x0F; /* clear the foreground color */
pscr[off + 1] |= fgColor; /* Put video attribute in video RAM */
}
for (xy = y1 + 1; xy < y2 - 1; ++xy) {
off = OFF(x1, xy);
pscr[off] = line_char[line][VER_LINE];
pscr[off + 1] &= ~0x0F; /* clear the foreground color */
pscr[off + 1] |= fgColor; /* Put video attribute in video RAM */
off = OFF(x2 - 1, xy);
pscr[off] = line_char[line][VER_LINE];
pscr[off + 1] &= ~0x0F; /* clear the foreground color */
pscr[off + 1] |= fgColor; /* Put video attribute in video RAM */
}
}
/*..........................................................................*/
void Video_printStrAt(uint8_t x, uint8_t y, uint8_t color,
char const *str)
{
/* calculate position on the video RAM (VGA) */
uint8_t far *pscr = (uint8_t far *)MK_FP(VIDEO_BASE,
(uint16_t)(((y * VIDEO_WIDTH) + x) * 2));
while (*str != (uint8_t)0) {
pscr[0] = *str++; /* Put character in video RAM */
pscr[1] &= ~0x0F; /* clear the foreground color */
pscr[1] |= color; /* Put video attribute in video RAM */
pscr += 2;
}
}
/*..........................................................................*/
void Video_printNumAt(uint8_t x, uint8_t y, uint8_t color, uint32_t num) {
uint8_t far *pscr = (uint8_t far *)MK_FP(VIDEO_BASE,
(uint16_t)(((y * VIDEO_WIDTH) + x) * 2));
pscr[3*2] = (char)('0' + (num % 10));
pscr[3*2 + 1] |= color;
num /= 10;
pscr[2*2] = (char)('0' + (num % 10));
pscr[2*2 + 1] |= color;
num /= 10;
if (num == 0) {
if (pscr[2*2] == '0') {
pscr[2*2] = 0x20;
}
}
else {
pscr[1*2] = (char)('0' + (num % 10));
pscr[1*2 + 1] |= color;
num /= 10;
if (num == 0) {
if (pscr[1*2] == '0') {
pscr[1*2] = 0x20;
}
}
else {
pscr[0] = (char)('0' + num % 10);
pscr[0 + 1] |= color;
if (pscr[0] == '0') {
pscr[0] = 0x20;
}
}
}
}
/*..........................................................................*/
void Video_drawBitmapAt(uint8_t x, uint8_t y,
uint8_t const *bitmap, uint8_t width, uint8_t height)
{
uint8_t far *pscrX = (uint8_t far *)MK_FP(VIDEO_BASE,
(uint16_t)(((y * VIDEO_WIDTH) + x) << 1));
uint8_t ix, iy;
uint8_t w = width;
uint8_t h = height;
/* perform the clipping */
if (x > VIDEO_WIDTH) {
x = VIDEO_WIDTH;
}
if (y > VIDEO_HEIGHT) {
y = VIDEO_HEIGHT;
}
if (w > VIDEO_WIDTH - x) {
w = VIDEO_WIDTH - x;
}
if (h > VIDEO_HEIGHT - y) {
h = VIDEO_HEIGHT - y;
}
for (ix = 0; ix < w; ++ix, pscrX += 2) { /* loop over x */
uint8_t far *pscrXY = pscrX;
for (iy = 0; iy < h; ++iy, pscrXY += 2*VIDEO_WIDTH) {
static uint8_t const pixel[2] = { 0x20, 0xDB };
uint8_t byte = bitmap[ix + (iy >> 3)*width];
*pscrXY = pixel[(byte >> (iy & 0x7)) & 1];
}
}
}
/*..........................................................................*/
void Video_drawStringAt(uint8_t x, uint8_t y, char const *str) {
static uint8_t const font5x7[95][5] = {
{ 0x00, 0x00, 0x00, 0x00, 0x00 }, /* ' ' */
{ 0x00, 0x00, 0x4F, 0x00, 0x00 }, /* ! */
{ 0x00, 0x07, 0x00, 0x07, 0x00 }, /* " */
{ 0x14, 0x7F, 0x14, 0x7F, 0x14 }, /* # */
{ 0x24, 0x2A, 0x7F, 0x2A, 0x12 }, /* $ */
{ 0x23, 0x13, 0x08, 0x64, 0x62 }, /* % */
{ 0x36, 0x49, 0x55, 0x22, 0x50 }, /* & */
{ 0x00, 0x05, 0x03, 0x00, 0x00 }, /* ' */
{ 0x00, 0x1C, 0x22, 0x41, 0x00 }, /* ( */
{ 0x00, 0x41, 0x22, 0x1C, 0x00 }, /* ) */
{ 0x14, 0x08, 0x3E, 0x08, 0x14 }, /* * */
{ 0x08, 0x08, 0x3E, 0x08, 0x08 }, /* + */
{ 0x00, 0x50, 0x30, 0x00, 0x00 }, /* , */
{ 0x08, 0x08, 0x08, 0x08, 0x08 }, /* - */
{ 0x00, 0x60, 0x60, 0x00, 0x00 }, /* . */
{ 0x20, 0x10, 0x08, 0x04, 0x02 }, /* / */
{ 0x3E, 0x51, 0x49, 0x45, 0x3E }, /* 0 */
{ 0x00, 0x42, 0x7F, 0x40, 0x00 }, /* 1 */
{ 0x42, 0x61, 0x51, 0x49, 0x46 }, /* 2 */
{ 0x21, 0x41, 0x45, 0x4B, 0x31 }, /* 3 */
{ 0x18, 0x14, 0x12, 0x7F, 0x10 }, /* 4 */
{ 0x27, 0x45, 0x45, 0x45, 0x39 }, /* 5 */
{ 0x3C, 0x4A, 0x49, 0x49, 0x30 }, /* 6 */
{ 0x01, 0x71, 0x09, 0x05, 0x03 }, /* 7 */
{ 0x36, 0x49, 0x49, 0x49, 0x36 }, /* 8 */
{ 0x06, 0x49, 0x49, 0x29, 0x1E }, /* 9 */
{ 0x00, 0x36, 0x36, 0x00, 0x00 }, /* : */
{ 0x00, 0x56, 0x36, 0x00, 0x00 }, /* ; */
{ 0x08, 0x14, 0x22, 0x41, 0x00 }, /* < */
{ 0x14, 0x14, 0x14, 0x14, 0x14 }, /* = */
{ 0x00, 0x41, 0x22, 0x14, 0x08 }, /* > */
{ 0x02, 0x01, 0x51, 0x09, 0x06 }, /* ? */
{ 0x32, 0x49, 0x79, 0x41, 0x3E }, /* @ */
{ 0x7E, 0x11, 0x11, 0x11, 0x7E }, /* A */
{ 0x7F, 0x49, 0x49, 0x49, 0x36 }, /* B */
{ 0x3E, 0x41, 0x41, 0x41, 0x22 }, /* C */
{ 0x7F, 0x41, 0x41, 0x22, 0x1C }, /* D */
{ 0x7F, 0x49, 0x49, 0x49, 0x41 }, /* E */
{ 0x7F, 0x09, 0x09, 0x09, 0x01 }, /* F */
{ 0x3E, 0x41, 0x49, 0x49, 0x7A }, /* G */
{ 0x7F, 0x08, 0x08, 0x08, 0x7F }, /* H */
{ 0x00, 0x41, 0x7F, 0x41, 0x00 }, /* I */
{ 0x20, 0x40, 0x41, 0x3F, 0x01 }, /* J */
{ 0x7F, 0x08, 0x14, 0x22, 0x41 }, /* K */
{ 0x7F, 0x40, 0x40, 0x40, 0x40 }, /* L */
{ 0x7F, 0x02, 0x0C, 0x02, 0x7F }, /* M */
{ 0x7F, 0x04, 0x08, 0x10, 0x7F }, /* N */
{ 0x3E, 0x41, 0x41, 0x41, 0x3E }, /* O */
{ 0x7F, 0x09, 0x09, 0x09, 0x06 }, /* P */
{ 0x3E, 0x41, 0x51, 0x21, 0x5E }, /* Q */
{ 0x7F, 0x09, 0x19, 0x29, 0x46 }, /* R */
{ 0x46, 0x49, 0x49, 0x49, 0x31 }, /* S */
{ 0x01, 0x01, 0x7F, 0x01, 0x01 }, /* T */
{ 0x3F, 0x40, 0x40, 0x40, 0x3F }, /* U */
{ 0x1F, 0x20, 0x40, 0x20, 0x1F }, /* V */
{ 0x3F, 0x40, 0x38, 0x40, 0x3F }, /* W */
{ 0x63, 0x14, 0x08, 0x14, 0x63 }, /* X */
{ 0x07, 0x08, 0x70, 0x08, 0x07 }, /* Y */
{ 0x61, 0x51, 0x49, 0x45, 0x43 }, /* Z */
{ 0x00, 0x7F, 0x41, 0x41, 0x00 }, /* [ */
{ 0x02, 0x04, 0x08, 0x10, 0x20 }, /* \ */
{ 0x00, 0x41, 0x41, 0x7F, 0x00 }, /* ] */
{ 0x04, 0x02, 0x01, 0x02, 0x04 }, /* ^ */
{ 0x40, 0x40, 0x40, 0x40, 0x40 }, /* _ */
{ 0x00, 0x01, 0x02, 0x04, 0x00 }, /* ` */
{ 0x20, 0x54, 0x54, 0x54, 0x78 }, /* a */
{ 0x7F, 0x48, 0x44, 0x44, 0x38 }, /* b */
{ 0x38, 0x44, 0x44, 0x44, 0x20 }, /* c */
{ 0x38, 0x44, 0x44, 0x48, 0x7F }, /* d */
{ 0x38, 0x54, 0x54, 0x54, 0x18 }, /* e */
{ 0x08, 0x7E, 0x09, 0x01, 0x02 }, /* f */
{ 0x0C, 0x52, 0x52, 0x52, 0x3E }, /* g */
{ 0x7F, 0x08, 0x04, 0x04, 0x78 }, /* h */
{ 0x00, 0x44, 0x7D, 0x40, 0x00 }, /* i */
{ 0x20, 0x40, 0x44, 0x3D, 0x00 }, /* j */
{ 0x7F, 0x10, 0x28, 0x44, 0x00 }, /* k */
{ 0x00, 0x41, 0x7F, 0x40, 0x00 }, /* l */
{ 0x7C, 0x04, 0x18, 0x04, 0x78 }, /* m */
{ 0x7C, 0x08, 0x04, 0x04, 0x78 }, /* n */
{ 0x38, 0x44, 0x44, 0x44, 0x38 }, /* o */
{ 0x7C, 0x14, 0x14, 0x14, 0x08 }, /* p */
{ 0x08, 0x14, 0x14, 0x18, 0x7C }, /* q */
{ 0x7C, 0x08, 0x04, 0x04, 0x08 }, /* r */
{ 0x48, 0x54, 0x54, 0x54, 0x20 }, /* s */
{ 0x04, 0x3F, 0x44, 0x40, 0x20 }, /* t */
{ 0x3C, 0x40, 0x40, 0x20, 0x7C }, /* u */
{ 0x1C, 0x20, 0x40, 0x20, 0x1C }, /* v */
{ 0x3C, 0x40, 0x30, 0x40, 0x3C }, /* w */
{ 0x44, 0x28, 0x10, 0x28, 0x44 }, /* x */
{ 0x0C, 0x50, 0x50, 0x50, 0x3C }, /* y */
{ 0x44, 0x64, 0x54, 0x4C, 0x44 }, /* z */
{ 0x00, 0x08, 0x36, 0x41, 0x00 }, /* { */
{ 0x00, 0x00, 0x7F, 0x00, 0x00 }, /* | */
{ 0x00, 0x41, 0x36, 0x08, 0x00 }, /* } */
{ 0x02, 0x01, 0x02, 0x04, 0x02 }, /* ~ */
};
while (*str != '\0') {
Video_drawBitmapAt(x, y, font5x7[*str - ' '], 5, 8);
++str;
x += 6;
}
}