📄 console.c
字号:
/*
// Paradigm C++ CONSOLE.C implementation
//
// This source file demonstrates how to hook the Paradigm C++ stream I/O
// functions and bind to code that can fully implement a console device in a
// real system.
//
// As shipped, Paradigm C++ includes only a stub for certain functions to keep
// the code size to a minimum (for example console support is not needed if you
// only intended to use formatted I/O to memory buffers such as is done with
// sprintf()). Because every target system is unique, Paradigm C++ does allow
// the user to define a set of replacement functions to define the desired
// behavior on your particular target system. While here we only hook simple
// read/write operations to implement a simple console device, you can also
// hook other file system related operations such as open and close to fully
// customize the standard libraries to the needs of your application and target
// system.
*/
#include <systypes.h>
#include <rtlhook.h>
#include <stdio.h>
#if defined(__PDREMOTE__)
/*
// Code used to implement a console within the Paradigm C++ debugger when a
// PDREMOTE/ROM target is being used.
*/
#include <embedded.h>
#include <v8250.h>
static int v_inportb( int v_addr )
{
union REGS regs ;
regs.x.dx = v_addr ;
int86( 0x3, ®s, ®s ) ;
return regs.h.al ;
}
static void v_outportb( int v_addr, int v_data )
{
union REGS regs ;
regs.x.dx = v_addr ;
regs.h.al = v_data ;
int86( 0x3, ®s, ®s ) ;
}
#endif
/*
// Function: _getch
//
// This function returns the next character received from the console.
// As implemented, it returns characters from a string and must be
// modified to reflect the hardware in your target system.
*/
static int _getch(void)
{
static char buf[] = "16\r512\r1024\r2048\r" ;
static uint16 i ;
if ( buf[ i ] == '\0' ) {
i = 0 ;
}
return buf[ i++ ] ;
}
/*
// Function: _putch
//
// This function must be written to copy the supplied character to
// to the console device.
//
// As implemented, it returns does nothing unless a PDREMOTE/ROM target
// connection is being used.
*/
static int _putch( int ch )
{
#if defined(__PDREMOTE__)
/* Wait for transmit buffer empty signal */
while ( ( v_inportb( V8250_LINSTAT ) & LS_THRE ) == 0 )
;
v_outportb( V8250_TXBUF, ch ) ;
#endif
return ch ;
}
/*
// Function: InitConsole
//
// This function is responsible for initializing the console device
// used by the Paradigm C++ run-time library. This is the place to perform any
// initialization of UARTs, displays, or other console hardware that may be
// required by your system.
*/
static void InitConsole(void)
{
/* Add your console initialization code here */
}
#pragma startup InitConsole 64
/*
// Function: _Int21DosRead
//
// Description
// ===========
// Here we hook the requests for file system reads and process them by calling
// into our console driver. Registers are setup using DOS conventions:
//
// AH - DOS function code (0x3F)
// DS:DX - Pointer to the input buffer
// CX - Size of the input buffer
// BX - File handle
//
// Simple systems having only a single input device can ignore the file handle
// but it can be used in systems having multiple input sources.
//
// Return values
// =============
// If successful, the carry flag should be cleared and AX has the number of
// characters read, 0 if EOF is detected.
*/
#pragma argsused
#pragma option -1-
void _INTERRUPT _Int21DosRead(
uint16 es, uint16 ds,
uint16 di, uint16 si,
uint16 bp, uint16 sp,
uint16 bx, uint16 dx, uint16 cx, uint16 ax,
uint16 ip, uint16 cs, uint16 psw
)
{
uint16 i ;
uint8 __far *cp = (uint8 __far *) MK_FP( ds, dx ) ;
for ( i = 0; i < cx; ) {
/* Extract a character */
char c = _getch() ;
/* Check for EOF */
if ( c == EOF ) {
break ;
}
/* Check for and process backspace characters */
if ( c == '\b' ) {
if ( i > 0 ) {
_putch( c ) ;
_putch( ' ' ) ;
_putch( c ) ;
cp-- ;
i-- ;
}
continue ;
}
/* Check for the end of the line */
if ( c == '\r' ) {
*cp++ = _putch( '\n' ) ;
i++ ;
break ;
}
/* Put the character in the buffer */
_putch( *cp++ = c ) ;
i++ ;
}
/* Clear carry flag to indicate success */
psw &= 0xfffe ;
/* Return the number of characters read in AX */
ax = i ;
}
#pragma option -1.
/*
// Function: _Int21DosWrite
//
// Description
// ===========
// Here we hook the requests for file system writes and process them by calling
// into our console driver. Registers are setup using DOS conventions:
//
// AH - DOS function code (0x40)
// DS:DX - Pointer to the output buffer
// CX - Size of the output buffer
// BX - File handle
//
// Simple systems having only a single output device can ignore the file handle
// but it can be used in systems having multiple output devices.
//
// Return values
// =============
// If successful, the carry flag should be cleared and AX has the number of
// characters written, 0 if EOF is detected.
*/
#pragma argsused
#pragma option -1-
void _INTERRUPT _Int21DosWrite(
uint16 es, uint16 ds,
uint16 di, uint16 si,
uint16 bp, uint16 sp,
uint16 bx, uint16 dx, uint16 cx, uint16 ax,
uint16 ip, uint16 cs, uint16 psw
)
{
uint16 i ;
uint8 __far *cp = (uint8 __far *) MK_FP( ds, dx ) ;
for ( i = 0; i < cx; i++ ) {
/* Check for and handle a backspace character */
if ( *cp == '\b' ) {
_putch( *cp ) ;
_putch( ' ' ) ;
}
_putch( *cp++ ) ;
}
/* Clear carry flag to indicate success */
psw &= 0xfffe ;
/* Return the number of characters written in AX */
ax = i ;
}
#pragma option -1.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -