📄 iodisp.c
字号:
/*-----------------------------------------------------------------------
| iodisp.c - Display data captured with I/O Monitor |
| (must compile with -Zp to pack structures) |
| (Borland C++: Large Model |
| No Debug info in OBJ |
| No Standard Stack Frame |
-----------------------------------------------------------------------*/
#include <bios.h>
#include <dos.h>
#include <stdio.h>
#include <string.h>
#define USER_INT 0x61
#define PORT_OUTPUT 0x8000 // MSB of address: out - 1; in - 0
#define PORT_BYTE 0x4000 // Address bit 15: word - 1; byte - 0
#define PORT_INVALID -1 // Initial data (marked as empty)
#define PORT_REPEAT -2 // Repeat data (io_data = repeat count)
#define PORT_ADDRESS 0x3fff
struct io_record
{
unsigned short int io_port;
unsigned short int io_data; // repeat or number
};
int main(int argc, char * argv[])
{
unsigned int port, i, buf_size, buf_total, buf_wrap;
unsigned long io_total, repeat_count, io_count;
unsigned far * vector_ptr;
struct io_record far *buf_ptr, *buf_start, *buf_end;
union REGS inregs, outregs;
vector_ptr = (unsigned far *) ((USER_INT << 2) + 2); // CS of user isr
if(*vector_ptr == 0) //if user int not installed
{
printf ("\nIOMON not installed."
"\n\nUsage:\tIODISP /c\n\t/c - clear buffer after read\n");
return 1;
}
int86(USER_INT, &inregs, &outregs); // Generate user interrupt
FP_SEG(buf_start) = outregs.x.dx; // Get buffer start pointer
FP_OFF(buf_start) = outregs.x.bx;
FP_SEG(buf_ptr) = outregs.x.dx; // Get buffer current pointer
FP_OFF(buf_ptr) = outregs.x.cx;
buf_size = outregs.h.al; // Buffer size in KB
buf_size <<= 10; // convert to bytes
buf_total = buf_size / sizeof(struct io_record);
buf_end = buf_start + buf_total;
io_total = buf_total;
buf_wrap = outregs.h.ah;
io_total *= buf_wrap; // Buffer wrap count
io_total += (outregs.x.cx - outregs.x.bx) / sizeof(struct io_record);
printf ("%ld I/O records stored in a %dKB buffer\n",
io_total, outregs.h.al);
#ifdef DEBUG
/* Debug purpose only */
printf ("AX: %04X BX: %04X CX: %04X DX: %04X\n",
outregs.x.ax, outregs.x.bx, outregs.x.cx, outregs.x.dx);
for(i = 0; i < 64; i++)
printf ("%04X : %04X\t", buf_ptr[i].io_port, buf_ptr[i].io_data);
#endif
if(buf_wrap) buf_ptr++; // Curren record is invalid
else buf_ptr = buf_start; // Start from beginning
for(i = 1, io_count = 0; i < buf_total; ) // Last record is invalid
{
if(buf_ptr >= buf_end) buf_ptr = buf_start; // Wrap to beginning
port = buf_ptr->io_port;
if((int) port == PORT_INVALID) break; // No more data
else
{
printf("\n%c %4XH ", (port & PORT_OUTPUT) ? 'O' : 'I', port & PORT_ADDRESS);
printf((port & PORT_BYTE) ? "%02X" : "%04X", buf_ptr->io_data);
buf_ptr++; // Next data
io_count++;
i++;
for(repeat_count = 0; i < buf_total; buf_ptr++, i++) // Add repeat count if any
{
if(buf_ptr >= buf_end) buf_ptr = buf_start; // Wrap to beginning
if ((int) buf_ptr->io_port != PORT_REPEAT) break;
repeat_count += buf_ptr->io_data; // Increase repeat count
}
if(repeat_count) printf(" [%ld]", repeat_count + 1);
io_count += repeat_count;
}
}
printf ("\nTotal I/O operations captured: %ld\n", io_count);
if(argc > 1 && !stricmp(argv[1], "/c")) // Clear record after display
{
memset(buf_start, 0xff, buf_size);
buf_ptr = buf_end; // Go to end of buffer
buf_ptr->io_port = outregs.x.bx; // io_buf_ptr = buf_start
buf_ptr->io_data = outregs.x.bx; // io_repeat_ptr = buf_start
buf_ptr++;
* ((char *) buf_ptr) = 0; // io_buf_wrap = 0
printf ("\nI/O records purged\n");
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -