summaryrefslogtreecommitdiff
path: root/kernel/old/cio.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--kernel/old/cio.c796
1 files changed, 0 insertions, 796 deletions
diff --git a/kernel/old/cio.c b/kernel/old/cio.c
deleted file mode 100644
index cfff543..0000000
--- a/kernel/old/cio.c
+++ /dev/null
@@ -1,796 +0,0 @@
-/*
-** SCCS ID: @(#)cio.c 2.10 1/22/25
-**
-** @file cio.c
-**
-** @author Warren R. Carithers
-**
-** Based on: c_io.c 1.13 (Ken Reek, Jon Coles, Warren R. Carithers)
-**
-** Console I/O routines
-**
-** This module implements a simple set of input and output routines
-** for the console screen and keyboard on the machines in the DSL.
-** Refer to the header file comments for complete details.
-**
-** Naming conventions:
-**
-** Externally-visible functions have names beginning with the
-** characters "cio_".
-**
-*/
-
-#include <cio.h>
-#include <lib.h>
-#include <support.h>
-#include <x86/arch.h>
-#include <x86/pic.h>
-#include <x86/ops.h>
-
-/*
-** Bit masks for the lower five and eight bits of a value
-*/
-#define BMASK5 0x1f
-#define BMASK8 0xff
-
-/*
-** Video parameters
-*/
-#define SCREEN_MIN_X 0
-#define SCREEN_MIN_Y 0
-#define SCREEN_X_SIZE 80
-#define SCREEN_Y_SIZE 25
-#define SCREEN_MAX_X ( SCREEN_X_SIZE - 1 )
-#define SCREEN_MAX_Y ( SCREEN_Y_SIZE - 1 )
-
-/*
-** Video state
-*/
-static unsigned int scroll_min_x, scroll_min_y;
-static unsigned int scroll_max_x, scroll_max_y;
-static unsigned int curr_x, curr_y;
-static unsigned int min_x, min_y;
-static unsigned int max_x, max_y;
-
-// pointer to input notification function
-static void (*notify)(int);
-
-#ifdef SA_DEBUG
-#include <stdio.h>
-#define cio_putchar putchar
-#define cio_puts(x) fputs( x, stdout )
-#endif
-
-
-/*
-** VGA definitions.
-*/
-
-// calculate the memory address of a specific character position
-// within VGA memory
-#define VIDEO_ADDR(x,y) ( unsigned short * ) \
- ( VID_BASE_ADDR + 2 * ( (y) * SCREEN_X_SIZE + (x) ) )
-
-// port addresses
-#define VGA_CTRL_IX_ADDR 0x3d4
-# define VGA_CTRL_CUR_HIGH 0x0e // cursor location, high byte
-# define VGA_CTRL_CUR_LOW 0x0f // cursor location, low byte
-#define VGA_CTRL_IX_DATA 0x3d5
-
-// attribute bits
-#define VGA_ATT_BBI 0x80 // blink, or background intensity
-#define VGA_ATT_BGC 0x70 // background color
-#define VGA_ATT_FICS 0x80 // foreground intensity or char font select
-#define VGA_ATT_FGC 0x70 // foreground color
-
-// color selections
-#define VGA_BG_BLACK 0x0000 // background colors
-#define VGA_BG_BLUE 0x1000
-#define VGA_BG_GREEN 0x2000
-#define VGA_BG_CYAN 0x3000
-#define VGA_BG_RED 0x4000
-#define VGA_BG_MAGENTA 0x5000
-#define VGA_BG_BROWN 0x6000
-#define VGA_BG_WHITE 0x7000
-
-#define VGA_FG_BLACK 0x0000 // foreground colors
-#define VGA_FG_BLUE 0x0100
-#define VGA_FG_GREEN 0x0200
-#define VGA_FG_CYAN 0x0300
-#define VGA_FG_RED 0x0400
-#define VGA_FG_MAGENTA 0x0500
-#define VGA_FG_BROWN 0x0600
-#define VGA_FG_WHITE 0x0700
-
-// color combinations
-#define VGA_WHITE_ON_BLACK (VGA_FG_WHITE | VGA_BG_BLACK)
-#define VGA_BLACK_ON_WHITE (VGA_FG_BLACK | VGA_BG_WHITE)
-
-/*
-** Internal support routines.
-*/
-
-/*
-** setcursor: set the cursor location (screen coordinates)
-*/
-static void setcursor( void ) {
- unsigned addr;
- unsigned int y = curr_y;
-
- if( y > scroll_max_y ) {
- y = scroll_max_y;
- }
-
- addr = (unsigned)( y * SCREEN_X_SIZE + curr_x );
-
- outb( VGA_CTRL_IX_ADDR, VGA_CTRL_CUR_HIGH );
- outb( VGA_CTRL_IX_DATA, ( addr >> 8 ) & BMASK8 );
- outb( VGA_CTRL_IX_ADDR, VGA_CTRL_CUR_LOW );
- outb( VGA_CTRL_IX_DATA, addr & BMASK8 );
-}
-
-/*
-** putchar_at: physical output to the video memory
-*/
-static void putchar_at( unsigned int x, unsigned int y, unsigned int c ) {
- /*
- ** If x or y is too big or small, don't do any output.
- */
- if( x <= max_x && y <= max_y ) {
- unsigned short *addr = VIDEO_ADDR( x, y );
-
- /*
- ** The character may have attributes associated with it; if
- ** so, use those, otherwise use white on black.
- */
- c &= 0xffff; // keep only the lower bytes
- if( c > BMASK8 ) {
- *addr = (unsigned short)c;
- } else {
- *addr = (unsigned short)c | VGA_WHITE_ON_BLACK;
- }
- }
-}
-
-/*
-** Globally-visible support routines.
-*/
-
-/*
-** Set the scrolling region
-*/
-void cio_setscroll( unsigned int s_min_x, unsigned int s_min_y,
- unsigned int s_max_x, unsigned int s_max_y ) {
- scroll_min_x = bound( min_x, s_min_x, max_x );
- scroll_min_y = bound( min_y, s_min_y, max_y );
- scroll_max_x = bound( scroll_min_x, s_max_x, max_x );
- scroll_max_y = bound( scroll_min_y, s_max_y, max_y );
- curr_x = scroll_min_x;
- curr_y = scroll_min_y;
- setcursor();
-}
-
-/*
-** Cursor movement in the scroll region
-*/
-void cio_moveto( unsigned int x, unsigned int y ) {
- curr_x = bound( scroll_min_x, x + scroll_min_x, scroll_max_x );
- curr_y = bound( scroll_min_y, y + scroll_min_y, scroll_max_y );
- setcursor();
-}
-
-/*
-** The putchar family
-*/
-void cio_putchar_at( unsigned int x, unsigned int y, unsigned int c ) {
- if( ( c & 0x7f ) == '\n' ) {
- unsigned int limit;
-
- /*
- ** If we're in the scroll region, don't let this loop
- ** leave it. If we're not in the scroll region, don't
- ** let this loop enter it.
- */
- if( x > scroll_max_x ) {
- limit = max_x;
- }
- else if( x >= scroll_min_x ) {
- limit = scroll_max_x;
- }
- else {
- limit = scroll_min_x - 1;
- }
- while( x <= limit ) {
- putchar_at( x, y, ' ' );
- x += 1;
- }
- }
- else {
- putchar_at( x, y, c );
- }
-}
-
-#ifndef SA_DEBUG
-void cio_putchar( unsigned int c ) {
- /*
- ** If we're off the bottom of the screen, scroll the window.
- */
- if( curr_y > scroll_max_y ) {
- cio_scroll( curr_y - scroll_max_y );
- curr_y = scroll_max_y;
- }
-
- switch( c & BMASK8 ) {
- case '\n':
- /*
- ** Erase to the end of the line, then move to new line
- ** (actual scroll is delayed until next output appears).
- */
- while( curr_x <= scroll_max_x ) {
- putchar_at( curr_x, curr_y, ' ' );
- curr_x += 1;
- }
- curr_x = scroll_min_x;
- curr_y += 1;
- break;
-
- case '\r':
- curr_x = scroll_min_x;
- break;
-
- default:
- putchar_at( curr_x, curr_y, c );
- curr_x += 1;
- if( curr_x > scroll_max_x ) {
- curr_x = scroll_min_x;
- curr_y += 1;
- }
- break;
- }
- setcursor();
-}
-#endif
-
-/*
-** The puts family
-*/
-void cio_puts_at( unsigned int x, unsigned int y, const char *str ) {
- unsigned int ch;
-
- while( (ch = *str++) != '\0' && x <= max_x ) {
- cio_putchar_at( x, y, ch );
- x += 1;
- }
-}
-
-#ifndef SA_DEBUG
-void cio_puts( const char *str ) {
- unsigned int ch;
-
- while( (ch = *str++) != '\0' ) {
- cio_putchar( ch );
- }
-}
-#endif
-
-/*
-** Write a "sized" buffer (like cio_puts(), but no NUL)
-*/
-void cio_write( const char *buf, int length ) {
- for( int i = 0; i < length; ++i ) {
- cio_putchar( buf[i] );
- }
-}
-
-void cio_clearscroll( void ) {
- unsigned int nchars = scroll_max_x - scroll_min_x + 1;
- unsigned int l;
- unsigned int c;
-
- for( l = scroll_min_y; l <= scroll_max_y; l += 1 ) {
- unsigned short *to = VIDEO_ADDR( scroll_min_x, l );
-
- for( c = 0; c < nchars; c += 1 ) {
- *to++ = ' ' | 0x0700;
- }
- }
-}
-
-void cio_clearscreen( void ) {
- unsigned short *to = VIDEO_ADDR( min_x, min_y );
- unsigned int nchars = ( max_y - min_y + 1 ) * ( max_x - min_x + 1 );
-
- while( nchars > 0 ) {
- *to++ = ' ' | 0x0700;
- nchars -= 1;
- }
-}
-
-
-void cio_scroll( unsigned int lines ) {
- unsigned short *from;
- unsigned short *to;
- int nchars = scroll_max_x - scroll_min_x + 1;
- int line, c;
-
- /*
- ** If # of lines is the whole scrolling region or more, just clear.
- */
- if( lines > scroll_max_y - scroll_min_y ) {
- cio_clearscroll();
- curr_x = scroll_min_x;
- curr_y = scroll_min_y;
- setcursor();
- return;
- }
-
- /*
- ** Must copy it line by line.
- */
- for( line = scroll_min_y; line <= scroll_max_y - lines; line += 1 ) {
- from = VIDEO_ADDR( scroll_min_x, line + lines );
- to = VIDEO_ADDR( scroll_min_x, line );
- for( c = 0; c < nchars; c += 1 ) {
- *to++ = *from++;
- }
- }
-
- for( ; line <= scroll_max_y; line += 1 ) {
- to = VIDEO_ADDR( scroll_min_x, line );
- for( c = 0; c < nchars; c += 1 ) {
- *to++ = ' ' | 0x0700;
- }
- }
-}
-
-static int mypad( int x, int y, int extra, int padchar ) {
- while( extra > 0 ) {
- if( x != -1 || y != -1 ) {
- cio_putchar_at( x, y, padchar );
- x += 1;
- }
- else {
- cio_putchar( padchar );
- }
- extra -= 1;
- }
- return x;
-}
-
-static int mypadstr( int x, int y, char *str, int len, int width,
- int leftadjust, int padchar ) {
- int extra;
-
- if( len < 0 ) {
- len = strlen( str );
- }
- extra = width - len;
- if( extra > 0 && !leftadjust ) {
- x = mypad( x, y, extra, padchar );
- }
- if( x != -1 || y != -1 ) {
- cio_puts_at( x, y, str );
- x += len;
- }
- else {
- cio_puts( str );
- }
- if( extra > 0 && leftadjust ) {
- x = mypad( x, y, extra, padchar );
- }
- return x;
-}
-
-static void do_printf( int x, int y, char **f ) {
- char *fmt = *f;
- int *ap;
- char buf[ 12 ];
- char ch;
- char *str;
- int leftadjust;
- int width;
- int len;
- int padchar;
-
- /*
- ** Get characters from the format string and process them
- */
-
- ap = (int *)( f + 1 );
-
- while( (ch = *fmt++) != '\0' ) {
-
- /*
- ** Is it the start of a format code?
- */
-
- if( ch == '%' ) {
-
- /*
- ** Yes, get the padding and width options (if there).
- ** Alignment must come at the beginning, then fill,
- ** then width.
- */
-
- leftadjust = 0;
- padchar = ' ';
- width = 0;
-
- ch = *fmt++;
-
- if( ch == '-' ) {
- leftadjust = 1;
- ch = *fmt++;
- }
-
- if( ch == '0' ) {
- padchar = '0';
- ch = *fmt++;
- }
-
- while( ch >= '0' && ch <= '9' ) {
- width *= 10;
- width += ch - '0';
- ch = *fmt++;
- }
-
- /*
- ** What data type do we have?
- */
- switch( ch ) {
-
- case 'c':
- // ch = *( (int *)ap )++;
- ch = *ap++;
- buf[ 0 ] = ch;
- buf[ 1 ] = '\0';
- x = mypadstr( x, y, buf, 1, width, leftadjust, padchar );
- break;
-
- case 'd':
- // len = cvtdec( buf, *( (int *)ap )++ );
- len = cvtdec( buf, *ap++ );
- x = mypadstr( x, y, buf, len, width, leftadjust, padchar );
- break;
-
- case 's':
- // str = *( (char **)ap )++;
- str = (char *) (*ap++);
- x = mypadstr( x, y, str, -1, width, leftadjust, padchar );
- break;
-
- case 'x':
- // len = cvthex( buf, *( (int *)ap )++ );
- len = cvthex( buf, *ap++ );
- x = mypadstr( x, y, buf, len, width, leftadjust, padchar );
- break;
-
- case 'o':
- // len = cvtoct( buf, *( (int *)ap )++ );
- len = cvtoct( buf, *ap++ );
- x = mypadstr( x, y, buf, len, width, leftadjust, padchar );
- break;
-
- case 'u':
- len = cvtuns( buf, *ap++ );
- x = mypadstr( x, y, buf, len, width, leftadjust, padchar );
- break;
-
- }
- } else {
-
- /*
- ** No - just print it normally.
- */
-
- if( x != -1 || y != -1 ) {
- cio_putchar_at( x, y, ch );
- switch( ch ) {
- case '\n':
- y += 1;
- /* FALL THRU */
-
- case '\r':
- x = scroll_min_x;
- break;
-
- default:
- x += 1;
- }
- }
- else {
- cio_putchar( ch );
- }
- }
- }
-}
-
-void cio_printf_at( unsigned int x, unsigned int y, char *fmt, ... ) {
- do_printf( x, y, &fmt );
-}
-
-void cio_printf( char *fmt, ... ) {
- do_printf( -1, -1, &fmt );
-}
-
-/*
-** These are the "standard" IBM AT "Set 1" keycodes.
-*/
-
-static unsigned char scan_code[ 2 ][ 128 ] = {
- { // unshifted characters
-/* 00-07 */ '\377', '\033', '1', '2', '3', '4', '5', '6',
-/* 08-0f */ '7', '8', '9', '0', '-', '=', '\b', '\t',
-/* 10-17 */ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
-/* 18-1f */ 'o', 'p', '[', ']', '\n', '\377', 'a', 's',
-/* 20-27 */ 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
-/* 28-2f */ '\'', '`', '\377', '\\', 'z', 'x', 'c', 'v',
-/* 30-37 */ 'b', 'n', 'm', ',', '.', '/', '\377', '*',
-/* 38-3f */ '\377', ' ', '\377', '\377', '\377', '\377', '\377', '\377',
-/* 40-47 */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '7',
-/* 48-4f */ '8', '9', '-', '4', '5', '6', '+', '1',
-/* 50-57 */ '2', '3', '0', '.', '\377', '\377', '\377', '\377',
-/* 58-5f */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377',
-/* 60-67 */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377',
-/* 68-6f */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377',
-/* 70-77 */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377',
-/* 78-7f */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377'
- },
-
- { // shifted characters
-/* 00-07 */ '\377', '\033', '!', '@', '#', '$', '%', '^',
-/* 08-0f */ '&', '*', '(', ')', '_', '+', '\b', '\t',
-/* 10-17 */ 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I',
-/* 18-1f */ 'O', 'P', '{', '}', '\n', '\377', 'A', 'S',
-/* 20-27 */ 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':',
-/* 28-2f */ '"', '~', '\377', '|', 'Z', 'X', 'C', 'V',
-/* 30-37 */ 'B', 'N', 'M', '<', '>', '?', '\377', '*',
-/* 38-3f */ '\377', ' ', '\377', '\377', '\377', '\377', '\377', '\377',
-/* 40-47 */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '7',
-/* 48-4f */ '8', '9', '-', '4', '5', '6', '+', '1',
-/* 50-57 */ '2', '3', '0', '.', '\377', '\377', '\377', '\377',
-/* 58-5f */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377',
-/* 60-67 */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377',
-/* 68-6f */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377',
-/* 70-77 */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377',
-/* 78-7f */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377'
- }
-};
-
-/*
-** Scan code masks
-*/
-
-// 'release' bit
-#define REL_BIT 0x80
-#define CODE_BITS 0x7f
-
-#define IS_PRESS(c) (((c) & REL_BIT) == 0)
-#define IS_RELEASE(c) (((c) & REL_BIT) != 0)
-
-/*
-** Scan codes for some special characters
-*/
-
-// escape code - followed by another code byte
-#define SCAN_ESC 0xe0
-
-// shift keys: press, release
-#define L_SHIFT_DN 0x2a
-#define R_SHIFT_DN 0x36
-#define L_SHIFT_UP 0xaa
-#define R_SHIFT_UP 0xb6
-
-// control keys
-#define L_CTRL_DN 0x1d
-#define L_CTRL_UP 0x9d
-
-/*
-** I/O communication constants
-*/
-#define KBD_DATA 0x60
-#define KBD_STATUS 0x64
-#define READY 0x1
-
-/*
-** Circular buffer for input characters. Characters are inserted at
-** next_space, and are removed at next_char. Buffer is empty if
-** these are equal.
-*/
-#define C_BUFSIZE 200
-
-static char input_buffer[ C_BUFSIZE ];
-static volatile char *next_char = input_buffer;
-static volatile char *next_space = input_buffer;
-
-static volatile char *increment( volatile char *pointer ) {
- if( ++pointer >= input_buffer + C_BUFSIZE ) {
- pointer = input_buffer;
- }
- return pointer;
-}
-
-static int input_scan_code( int code ) {
- static int shift = 0;
- static int ctrl_mask = BMASK8;
- int rval = -1;
-
- /*
- ** Do the shift processing
- */
- code &= BMASK8;
- switch( code ) {
- case L_SHIFT_DN:
- case R_SHIFT_DN:
- shift = 1;
- break;
-
- case L_SHIFT_UP:
- case R_SHIFT_UP:
- shift = 0;
- break;
-
- case L_CTRL_DN:
- ctrl_mask = BMASK5;
- break;
-
- case L_CTRL_UP:
- ctrl_mask = BMASK8;
- break;
-
- default:
- /*
- ** Process ordinary characters only on the press (to handle
- ** autorepeat). Ignore undefined scan codes.
- */
- if( IS_PRESS(code) ) {
- code = scan_code[ shift ][ (int)code ];
- if( code != '\377' ) {
- volatile char *next = increment( next_space );
-
- /*
- ** Store character only if there's room
- */
- rval = code & ctrl_mask;
- if( next != next_char ) {
- *next_space = code & ctrl_mask;
- next_space = next;
- }
- }
- }
- }
- return( rval );
-}
-
-static void keyboard_isr( int vector, int code ) {
-
- int data = inb( KBD_DATA );
- int val = input_scan_code( data );
-
- // if there is a notification function, call it
- if( val != -1 && notify )
- notify( val );
-
- outb( PIC1_CMD, PIC_EOI );
-}
-
-int cio_getchar( void ) {
- char c;
- int interrupts_enabled = r_eflags() & EFL_IF;
-
- while( next_char == next_space ) {
- if( !interrupts_enabled ) {
- /*
- ** Must read the next keystroke ourselves.
- */
- while( ( inb( KBD_STATUS ) & READY ) == 0 ) {
- ;
- }
- (void) input_scan_code( inb( KBD_DATA ) );
- }
- }
-
- c = *next_char & BMASK8;
- next_char = increment( next_char );
- if( c != EOT ) {
- cio_putchar( c );
- }
- return c;
-}
-
-int cio_gets( char *buffer, unsigned int size ) {
- char ch;
- int count = 0;
-
- while( size > 1 ) {
- ch = cio_getchar();
- if( ch == EOT ) {
- break;
- }
- *buffer++ = ch;
- count += 1;
- size -= 1;
- if( ch == '\n' ) {
- break;
- }
- }
- *buffer = '\0';
- return count;
-}
-
-int cio_input_queue( void ) {
- int n_chars = next_space - next_char;
-
- if( n_chars < 0 ) {
- n_chars += C_BUFSIZE;
- }
- return n_chars;
-}
-
-/*
-** Initialization routines
-*/
-void cio_init( void (*fcn)(int) ) {
- /*
- ** Screen dimensions
- */
- min_x = SCREEN_MIN_X;
- min_y = SCREEN_MIN_Y;
- max_x = SCREEN_MAX_X;
- max_y = SCREEN_MAX_Y;
-
- /*
- ** Scrolling region
- */
- scroll_min_x = SCREEN_MIN_X;
- scroll_min_y = SCREEN_MIN_Y;
- scroll_max_x = SCREEN_MAX_X;
- scroll_max_y = SCREEN_MAX_Y;
-
- /*
- ** Initial cursor location
- */
- curr_y = min_y;
- curr_x = min_x;
- setcursor();
-
- /*
- ** Notification function (or NULL)
- */
- notify = fcn;
-
- /*
- ** Set up the interrupt handler for the keyboard
- */
- install_isr( VEC_KBD, keyboard_isr );
-}
-
-#ifdef SA_DEBUG
-int main() {
- cio_printf( "%d\n", 123 );
- cio_printf( "%d\n", -123 );
- cio_printf( "%d\n", 0x7fffffff );
- cio_printf( "%d\n", 0x80000001 );
- cio_printf( "%d\n", 0x80000000 );
- cio_printf( "x%14dy\n", 0x80000000 );
- cio_printf( "x%-14dy\n", 0x80000000 );
- cio_printf( "x%014dy\n", 0x80000000 );
- cio_printf( "x%-014dy\n", 0x80000000 );
- cio_printf( "%s\n", "xyz" );
- cio_printf( "|%10s|\n", "xyz" );
- cio_printf( "|%-10s|\n", "xyz" );
- cio_printf( "%c\n", 'x' );
- cio_printf( "|%4c|\n", 'y' );
- cio_printf( "|%-4c|\n", 'y' );
- cio_printf( "|%04c|\n", 'y' );
- cio_printf( "|%-04c|\n", 'y' );
- cio_printf( "|%3d|\n", 5 );
- cio_printf( "|%3d|\n", 54321 );
- cio_printf( "%x\n", 0x123abc );
- cio_printf( "|%04x|\n", 20 );
- cio_printf( "|%012x|\n", 0xfedcba98 );
- cio_printf( "|%-012x|\n", 0x76543210 );
-}
-
-int curr_x, curr_y, max_x, max_y;
-#endif