/** * KSvt100 * * This library offers a common interface for keyboard and screen devices * using VT100 control codes * * This is a stripped down version of KS to only support VT100, but includes * color codes */ /* ks.h Keyboard & screen functions library for CP/M & MESCC - Mike's Enhanced Small C Compiler. Stripped down version for VT100+color by Anna Christina Naß Copyright (c) 2016, 2017 Miguel I. Garcia Lopez / FloppySoftware, Spain This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ int xks_rows = 25; // Screen rows int xks_cols = 80; // Screen columns BYTE *xks_clrscr = "\e[H\e[J"; // Clear screen BYTE *xks_poscur = "\e[%r;%cH"; // Position cursor BYTE *xks_shwcur = "\e[?25h"; // Show cursor BYTE *xks_hidcur = "\e[?25l"; // Hide cursor BYTE *xks_yrever = "\e[7m"; // Reverse on BYTE *xks_nrever = "\e[m"; // Reverse off BYTE *xks_yuline = "\e[4m"; // Underline on BYTE *xks_nuline = "\e[m"; // Underline off #define RESET "\e[0m" // reset all attributes #define FGBLK "\e[30m" // black #define FGRED "\e[31m" // red #define FGGRN "\e[32m" // green #define FGYEL "\e[33m" // yellow #define FGBLU "\e[34m" // blue #define FGMAG "\e[35m" // magenta #define FGCYN "\e[36m" // cyan #define FGWHT "\e[37m" // white/gray #define FGBGRY "\e[30;1m" // gray ("bright black") #define FGBRED "\e[31;1m" // bright red #define FGBGRN "\e[32;1m" // bright green #define FGBYEL "\e[33;1m" // bright yellow #define FGBBLU "\e[34;1m" // bright blue #define FGBMAG "\e[35;1m" // bright magenta #define FGBCYN "\e[36;1m" // bright cyan #define FGBWHT "\e[37;1m" // bright white #define BGBLK "\e[40m" // black #define BGRED "\e[41m" // red #define BGGRN "\e[42m" // green #define BGYEL "\e[43m" // yellow #define BGBLU "\e[44m" // blue #define BGMAG "\e[45m" // magenta #define BGCYN "\e[46m" // cyan #define BGWHT "\e[47m" // white /** * @fn int KsHello(char *tty_name) * @brief Initialize the KS library. * Call this function before any other function (with a few exceptions). * @param code - TTY code * @return 0 on success, -1 on failure */ KsHello(code) int code; { // Setup BIOS jumps, etc. xKsInit(); return 0; } /** * @fn void KsBye(void) * @brief Reset the KS library. * Call this function before you stop your program, in order to reset the TTY. */ KsBye() { // Nothing yet } /** * @fn int KsGetCode(char *name) * @brief Get the code for a TTY name. * This function can be called before KsHello(). * @param name - TTY name * @return TTY code if found, or -1 on unknown name */ KsGetCode(name) char *name; { if(strcmp(name, "VT100")) { return 0; } else { return -1; } } /** * @fn int KsGetName(int code) * @brief Get the name for a TTY code. * This function can be called before KsHello(). * @param code - TTY code * @return TTY name, or NULL on unknown code */ KsGetName(code) int code; { if(code==0) { return "VT100"; } else { return NULL; } } /** * @fn char **KsGetNames(void) * @brief Get all supported TTY names. * This function can be called before KsHello(). * @return Pointer to an array of pointers to char */ KsGetNames() { WORD xks_names[1]; xks_names[0] = "VT100"; return xks_names; } /** * @fn int KsGetHowMany(void) * @brief Get the number of supported TTYs. * This function can be called before KsHello(). * @return Number of supported TTYs */ KsGetHowMany() { return 1; } /** * @fn void KsClear(void) * @brief Clear the screen and move the cursor to 0,0. */ KsClear() { KsPutRawStr(xks_clrscr); } /** * @fn void KsPosCursor(int row, int col) * @brief Move the cursor on screen. * @param row - screen row from 0 * @param col - screen column from 0 */ KsPosCursor(row, col) int row, col; { char *p; int v; for(p = xks_poscur; *p; ++p) { if(*p != '%') { KsPutRawCh(*p); } else { v = (*(++p) == 'r' ? row : col); xKsPutDec(1 + v); } } } /** * @fn void KsSetCursor(int toggle) * @brief Show or hide the cursor on screen. * @param toggle - 0 to hide, other to show */ KsSetCursor(toggle) int toggle; { if(xks_shwcur) { KsPutRawStr(toggle ? xks_shwcur : xks_hidcur); } } /** * @fn void KsUnderline(int toggle) * @brief Set or reset underline text. * If the TTY does not have this capability, does nothing. * @param toggle - 0 to reset, other to set */ KsUnderline(toggle) int toggle; { if(xks_yuline) { KsPutRawStr(toggle ? xks_yuline : xks_nuline); } } /** * @fn void KsReverse(int toggle) * @brief Set or reset reverse text. * If the TTY does not have this capability, does nothing. * @param toggle - 0 to reset, other to set */ KsReverse(toggle) int toggle; { if(xks_yrever) { KsPutRawStr(toggle ? xks_yrever : xks_nrever); } } /** * @fn int KsGetRows(void) * @brief Get TTY rows. * @return TTY rows. */ KsGetRows() { return xks_rows; } /** * @fn int KsGetCols(void) * @brief Get TTY columns. * @return TTY columns. */ KsGetCols() { return xks_cols; } /** * @fn void KsCenterStr(int row, char *s) * @brief Print a string centered on screen. * @param row - screen row * @param s - string */ KsCenterStr(row, s) int row; char *s; { KsPosCursor(row, (KsGetCols() - strlen(s)) / 2); KsPutStr(s); } /** * @fn void KsPutRawCh(int ch) * @brief Send a character to the TTY. * @param ch - character */ #asm KsPutRawCh ld c,l jp xKsConOut #endasm /** * @fn void KsPutRawStr(char *s) * @brief Send a string to the TTY using KsPutRawCh(). * @param s - string */ KsPutRawStr(s) char *s; { while(*s) { KsPutRawCh(*s++); } } /** * @fn void KsPutCh(int ch) * @brief Send a character to the TTY. * This functions performs the following translations: * - '\n' to '\r' + '\n' * @param ch - character */ #asm KsPutCh ld a,l cp 10 jp nz,KsPutRawCh ld l,13 call KsPutRawCh ld l,10 jp KsPutRawCh #endasm /** * @fn void KsPutStr(char *s) * @brief Send a string to the TTY using KsPutCh(). * @param s - string */ KsPutStr(s) char *s; { while(*s) { KsPutCh(*s++); } } /** * @fn int KsGetKb(void) * @brief Check if there is an input character from the keyboard. * @return 0 for NO, other for YES */ #asm KsGetKb: call xKsConInSt ld h,a ld l,a ret #endasm /** * @fn int KsGetCh(void) * @brief Get character from the keyboard, waiting for one if necessary. * @return character */ #asm KsGetCh call xKsConIn ld h,0 ld l,a ret #endasm /* Private functions ----------------- */ // void xKsInit(void) : Set BIOS JUMPs. #asm xKsInit ld hl,(1) inc hl inc hl inc hl ld de,xKsConInSt ld bc,9 ldir ret xKsConInSt jp 0 ; BIOS ConSt xKsConIn jp 0 ; BIOS ConIn xKsConOut jp 0 ; BIOS ConOut #endasm // void xKsPutDec(int num) : Send positive decimal number to TTY. xKsPutDec(num) int num; { #ifdef SPRINTF_H char buf[6]; sprintf(buf, "%d", num); KsPutRawStr(buf); #else char buf[6]; int i; for(i = 0; i < 6; ++i) { if(num > 9) { buf[i] = num % 10; num /= 10; } else { buf[i++] = num; break; } } do { KsPutRawCh('0' + buf[--i]); } while(i); #endif }