www.pudn.com > r&s1.10°æ±¾£«Îĵµ.rar > trace.c
/* =============================================================================== | Copyright (C) 2004 RuanHaiShen, All rights reserved. | SUMMARY: | Tracing system. | | DESCRIPTION: | See http://www.01s.org for documentation, latest information, license | and contact details. | email:ruanhaishen@01s.org =============================================================================*/ /*===========================================================================*/ #include#include #include #include #include "arch/arch.h" #include "inc/queue.h" #include "inc/kernel.h" #include "inc/memory.h" #include "inc/ipc.h" #include "inc/kapi.h" #define DISP_BASE 0xB800 /* Base segment of display (0xB800=VGA, 0xB000=Mono) */ #define DISP_MAX_X 80 /* Maximum number of columns */ #define DISP_MAX_Y 25 /* Maximum number of rows */ #define RS_DISP_MIN_Y 2 #define RS_DISP_MAX_Y 25 #define DISP_FGND_BLACK 0x00 #define DISP_FGND_BLUE 0x01 #define DISP_FGND_GREEN 0x02 #define DISP_FGND_CYAN 0x03 #define DISP_FGND_RED 0x04 #define DISP_FGND_PURPLE 0x05 #define DISP_FGND_BROWN 0x06 #define DISP_FGND_LIGHT_GRAY 0x07 #define DISP_FGND_DARK_GRAY 0x08 #define DISP_FGND_LIGHT_BLUE 0x09 #define DISP_FGND_LIGHT_GREEN 0x0A #define DISP_FGND_LIGHT_CYAN 0x0B #define DISP_FGND_LIGHT_RED 0x0C #define DISP_FGND_LIGHT_PURPLE 0x0D #define DISP_FGND_YELLOW 0x0E #define DISP_FGND_WHITE 0x0F #define DISP_BGND_BLACK 0x00 #define DISP_BGND_BLUE 0x10 #define DISP_BGND_GREEN 0x20 #define DISP_BGND_CYAN 0x30 #define DISP_BGND_RED 0x40 #define DISP_BGND_PURPLE 0x50 #define DISP_BGND_BROWN 0x60 #define DISP_BGND_LIGHT_GRAY 0x70 #define DISP_BLINK 0x80 #define ICC_8254_CWR 0x43 /* 8254 PIT control word register address. */ #define ICC_8254_CTR0 0x40 /* 8254 PIT timer 0 register address. */ #define ICC_8254_CTR1 0x41 /* 8254 PIT timer 1 register address. */ #define ICC_8254_CTR2 0x42 /* 8254 PIT timer 2 register address. */ #define ICC_8254_CTR0_MODE3 0x36 /* 8254 PIT binary mode 3 for counter 0 control word. */ #define ICC_8254_CTR2_MODE0 0xB0 /* 8254 PIT binary mode 0 for counter 2 control word. */ #define ICC_8254_CTR2_LATCH 0x80 /* 8254 PIT latch command control word */ #define VECT_TICK 0x08 /* Vector number for 82C54 timer tick */ #define VECT_DOS_CHAIN 0x81 /* Vector number used to chain DOS */ static jmp_buf _jump_flag; static bool _exit_flag; unsigned char _dos_tick_counter; bool key_get(int *c) { if (kbhit()) { *c = getch(); return true; } else { *c = 0x00; return false; } } static void cursor_movenext(unsigned char* px, unsigned char* py) { (*px)++; if (*px > DISP_MAX_X) { *px = 0; (*py)++; } } static void cursor_nextrow(unsigned char* px, unsigned char* py) { (*px) = 0; (*py)++; if (*py > RS_DISP_MAX_Y) { *py = RS_DISP_MIN_Y; } } static void x86_vga_write_char(unsigned char x, unsigned char y, const char c, char style) { unsigned short offset; char far* pv; offset = DISP_MAX_X * 2 * y + x * 2; pv = (char far *)MK_FP(DISP_BASE, offset); *pv++ = c; *pv = style; } void x86_vga_write(unsigned char *s, int count) { unsigned char abyte; static unsigned char xpos = 0; static unsigned char ypos = 0; while (count--) { abyte = *s++; if (abyte != '\n') { x86_vga_write_char(xpos, ypos, abyte, DISP_FGND_WHITE); cursor_movenext(&xpos, &ypos); } else { cursor_nextrow(&xpos, &ypos); } } } static void clear_screen(char color) { char far *pv; int i; pv = (unsigned char far *)MK_FP(DISP_BASE, 0x0000); for (i = 0; i < (DISP_MAX_X * DISP_MAX_Y); i++) { *pv++ = ' '; *pv++ = color; } } static void* intr_vect_get(int vect) { unsigned short *pvect; int off; int seg; pvect = (unsigned short *)MK_FP(0x0000, vect * 4); CRITICAL_ENTER; off = *pvect++; seg = *pvect; CRITICAL_EXIT; return (MK_FP(seg, off)); } static void intr_vect_set(int vect, void* isr) { unsigned short *pvect; pvect = (unsigned short *)MK_FP(0x0000, vect * 4); CRITICAL_ENTER; *pvect++ = (unsigned short)FP_OFF(isr); *pvect = (unsigned short)FP_SEG(isr); CRITICAL_EXIT; } static void tick_rate_set (int freq) { int count; if (freq == 18) { count = 0; } else if (freq > 0) { count = (int)(((long)2386360L / freq + 1) >> 1); } else { count = 0; } CRITICAL_ENTER; outp(ICC_8254_CWR, ICC_8254_CTR0_MODE3); outp(ICC_8254_CTR0, count & 0xFF); outp(ICC_8254_CTR0, (count >> 8) & 0xFF); CRITICAL_EXIT; } static void dos_save_return(void) { void* isr_old; _exit_flag = false; _dos_tick_counter = 1; isr_old = intr_vect_get(VECT_TICK); intr_vect_set(VECT_DOS_CHAIN, isr_old); intr_vect_set(VECT_TICK, __timer_intr_s); tick_rate_set(TICKS_PER_SEC); setjmp(_jump_flag); if (_exit_flag) { CRITICAL_ENTER; tick_rate_set(18); /* restore tick*/ CRITICAL_EXIT; isr_old = intr_vect_get(VECT_DOS_CHAIN); intr_vect_set(VECT_TICK, isr_old); clear_screen(DISP_FGND_WHITE + DISP_BGND_BLACK); /* clear the display*/ exit(0); /* return to DOS*/ } } static void return_to_dos(void) { _exit_flag = true; longjmp(_jump_flag, 1); } void hardware_init(void) { disable_irq(); dos_save_return(); clear_screen(DISP_FGND_WHITE); } void halt(void) { return_to_dos(); } /*===========================================================================*/