⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 trace.c

📁 realtime RTOS NEW
💻 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 <conio.h>
#include <stdlib.h>
#include <dos.h>
#include <setjmp.h>

#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 char _exit_flag;

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 __p_* 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 __p_* 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 __p_* isr_old;

    _exit_flag = 0;

    isr_old = intr_vect_get(VECT_TICK);
    intr_vect_set(VECT_DOS_CHAIN, isr_old);

    intr_vect_set(VECT_TICK, __timer_irs);
    tick_rate_set(TICKS_PER_SECOND); 

    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 = 1;
    longjmp(_jump_flag, 1);
}

void hardware_init(void)
{
    DISABLE_IRQ;
    dos_save_return();
    clear_screen(DISP_FGND_WHITE); 
}

void halt(void)
{
    return_to_dos();
}

/*===========================================================================*/


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -