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

📄 plc.c

📁 单片PLC,AT2581实现梯形图功能,可作为参考
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 *  Released under the GNU GPL.  See http://www.gnu.org/licenses/gpl.txt
 *
 *  This program is part of TinyPLC
 *
 *  TinyPLC is free software; you can redistribute it and/or modify it
 *  under the terms of the GNU General Public License as published by the
 *  Free Software Foundatation; version 2 of the License.
 *
 *  TinyPLC is distributed in the hope that it will be useful, but WITHOUT
 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 *  for more details.
 */
/*
 *  My thanks to my employer, Athena Controls (www.athenacontrols.com)
 *  for allowing me to open source this project.
 */
/*
 *  TinyPLC kernel
 *  Processor:   Atmel MEGA1281 or Atmel MEGA2561
 *  Compiler:    Codevision AVR C compiler, 1.24.8e
 *
 *  TinyPLC editor/compiler
 *  Processor:   PC-clone, VESA video (mode 0x105, 1024x768x256)
 *  Compiler:    DeSmet C, version 2.51 (PCC version 1.2)
 *
 *  Revision history:
 *  Programmer        Date       Comments
 *  ----------------  ---------  ---------------------------------------------
 *  William Couture   3/19/2006  Original code
 *  William Couture   9/13/2006  Modify for GPL release
 */

#define BROKEN_ADD_OR_BRANCH
/* #define SIMPLE_ADDROW */
#define SHOW_NODES

#define _PLC_C_
#include "plc.h"

#include "charset.h"
#include "bigchar.h"

char buff_512[1024];  /* OK, so I lied... */
int vesalist[512];
WORD vesa_mode;
int have_vesamode;
int have_vgamode;
int vesalistsize;

#define FREQUENCY 115200L   /* frequency IN to UART */

#define COMM_RETRY_MAX 3

#define QUEUE_SIZE 4096   /* chars in IN/OUT buf, keep this a power of 2 */
BYTE in_queue[QUEUE_SIZE];
WORD in_queue_head;
WORD in_queue_tail;
BYTE out_queue[QUEUE_SIZE];
WORD out_queue_head;
WORD out_queue_tail;

/* 8250 registers */

#define REC           0  /* UART receive reg */

#define XMIT          0  /* UART transmit reg */

#define INT_EN        1  /* UART int. enable reg */

#define INT_ID        2  /* UART int. ident. reg */

#define LINE_CONTROL  3  /* UART line control reg */

#define MODEM_CONTROL 4  /* UART modem control reg */

#define LINE_STATUS   5  /* UART line status reg */

#define MODEM_STATUS  6  /* UART modem status reg */

#define BAUD_LSB      0  /* UART baud divisor reg */

#define BAUD_MSB      1  /* UART baud divisor reg */
#define FCR_REG       2  /* FCR reg for 16550+ */

BYTE old_uart_setup[8];


#define NONE          0  /* Handshake param none */

#define HDW           1  /* Handshake param hardware */

#define XON           2  /* Handshake param software */



/* Interrupt enable register  */

#define RX_INT    0x01  /* Receive interrupt mask */

#define TBE_INT   0x02  /* Transmit buffer empty mask */

#define ERR_INT   0x04  /* Error interrupt mask */

#define RS_INT    0x08  /* Line interrupt mask */



/* Interrupt id register */

#define OUT2      0x08  /* Out 2 line */

#define DTR       0x01  /* DTR high */

#define RTS       0x02  /* RTS high */

#define CTS       0x10

#define DSR       0x20

#define XMTRDY    0x20

#define TXR          0  /*  Transmit register (WRITE) */


WORD commbase = 0x03f8;  /* default to COMM 1 */
WORD irqnum = 4;         /* default to COMM 1 */
DWORD baudrate = 9600;

WORD comm_int_seg, comm_int_ofs;  /* save area */

BYTE tempstr[128];

WORD videopage;


#define MENUSPACING (TEXTHEIGHT + 8)

#define MENULINE(n) (144 + n * MENUSPACING)
#define ENDLINE(n) (144 + TEXTHEIGHT + n * MENUSPACING)
#define MENUCOL1 0
#define ENDCOL1  (5 * TEXTWIDTH)
#define MENUCOL2 (TEXTWIDTH * 8)
#define ENDCOL2 (TEXTWIDTH * 13)

int havemouse, mouser, mousec;  /* Need SIGNED! */
int mousecolor = LTBLUE;
BYTE mouse_cursor[9] = { MOUSE_CURSOR, 0 };
BYTE mouse_overlay[9];
#define MOUSE_SAVE_ROWS TEXTHEIGHT
#define MOUSE_SAVE_COLS 8 * TEXTWIDTH
BYTE mouse_cursor_save[MOUSE_SAVE_ROWS][MOUSE_SAVE_COLS];
WORD mouse_object = NULL_OBJ;

WORD curpos_r, curpos_c;

BYTE null_str[] = { 0 };
BYTE three_char_inp[] = { START_NO_IN, CHAR_BOX, CHAR_BOX, CHAR_BOX, END_NO_IN, 0 };
BYTE two_char_inp[] = { START_NO_IN, CHAR_BOX, CHAR_BOX, END_NO_IN, VERT_BAR, 0 };
BYTE three_char_out[] = { START_NO_OUT, CHAR_BOX, CHAR_BOX, CHAR_BOX, END_NO_OUT, 0 };
BYTE two_char_out[] = { START_NO_OUT, CHAR_BOX, CHAR_BOX, END_NO_OUT, VERT_BAR, 0 };
BYTE no_input[] = { VERT_BAR, VERT_BAR, START_NO_IN, END_NO_IN, VERT_BAR, 0 };
BYTE nc_input[] = { VERT_BAR, VERT_BAR, START_NC_IN, END_NC_IN, VERT_BAR, 0 };
BYTE no_output[] = { VERT_BAR, VERT_BAR, START_NO_OUT, END_NO_OUT, VERT_BAR, 0 };
BYTE nc_output[] = { VERT_BAR, VERT_BAR, START_NC_OUT, END_NC_OUT, VERT_BAR, 0 };
BYTE lat_output[] = { START_NO_OUT, CHAR_BOX, CHAR_BOX, CHAR_BOX, END_NO_OUT, 0 };
BYTE or_branch[] = { BRANCH_BAR, START_BRANCH, END_BRANCH, BRANCH_BAR, BRANCH_BAR, 0 };
BYTE expand_branch[] = { BRANCH_BAR, START_BRANCH, END_BRANCH, EXPAND_BRANCH, BRANCH_BAR, 0 };
BYTE ladder_left[] = { LEFT_EDGE, 0 };
BYTE ladder_right[] = { RIGHT_EDGE, 0 };
BYTE rung_element[] = { VERT_BAR, VERT_BAR, VERT_BAR, VERT_BAR, VERT_BAR, VERT_BAR, VERT_BAR, VERT_BAR, 0 };
BYTE blank_element[] = "     ";
                     /* 12345 */
BYTE or_null[] = { VERT_BAR, 0 };
BYTE or_link[] = { OR_VERT_T, 0 };
BYTE or_vertical[] = { OR_VERT_BAR, 0 };
BYTE or_start[] = { OR_LEFT, 0 };
BYTE or_start_t[] = { OR_LEFT_T, 0 };
BYTE or_end[] = { OR_RIGHT, 0 };
BYTE or_end_t[] = { OR_RIGHT_T, 0 };
BYTE scroll_uparrow[] = { SCROLL_UPARROW, 0 };
BYTE scroll_downarrow[] = { SCROLL_DOWNARROW, 0 };
BYTE scroll_bar[] = { SCROLL_BAR, 0 };
BYTE scroll_box[] = { SCROLL_BOX, 0 };


void filesave(), fileload(), newladder(), download();
void onestep(), linestep(), run(), stop();
#ifdef SIMPLE_ADDROW
   void addrow(), delrow();
#else
   void appendrow();
#endif
void pickup(), quit();
void scrollladder();

void inp_init(), ninp_init(), out_init(), nout_init(), lout_init(), uout_init();
void add_init(), sub_init(), mul_init(), div_init(), mod_init();
void and_init(), or_init(), xor_init(), not_init(), neg_init();
void equ_init(), neq_init(), grt_init(), geq_init(), les_init(), leq_init();
void mov_init(), jmp_init(), osr_init(), ctt_init(), ctf_init();
void tmt_init(), tmf_init(), rtmt_init(), rtmf_init(), reset_init(), lbl_init();
void inv_init();
void inp_del(), ninp_del(), out_del(), nout_del(), lout_del(), uout_del();
void add_del(), sub_del(), mul_del(), div_del(), mod_del();
void and_del(), or_del(), xor_del(), not_del(), neg_del();
void equ_del(), neq_del(), grt_del(), geq_del(), les_del(), leq_del();
void mov_del(), jmp_del(), osr_del(), ctt_del(), ctf_del();
void tmt_del(), tmf_del(), rtmt_del(), rtmf_del(), reset_del(), lbl_del();
void inv_del();
void inp_draw(), ninp_draw(), out_draw(), nout_draw(), lout_draw(), uout_draw();
void add_draw(), sub_draw(), mul_draw(), div_draw(), mod_draw();
void and_draw(), or_draw(), xor_draw(), not_draw(), neg_draw();
void equ_draw(), neq_draw(), grt_draw(), geq_draw(), les_draw(), leq_draw();
void mov_draw(), jmp_draw(), osr_draw(), ctt_draw(), ctf_draw();
void tmt_draw(), tmf_draw(), rtmt_draw(), rtmf_draw(), reset_draw(), lbl_draw();
void inv_draw();
WORD inp_comp(), ninp_comp(), out_comp(), nout_comp(), lout_comp(), uout_comp();
WORD add_comp(), sub_comp(), mul_comp(), div_comp(), mod_comp();
WORD and_comp(), or_comp(), xor_comp(), not_comp(), neg_comp();
WORD equ_comp(), neq_comp(), grt_comp(), geq_comp(), les_comp(), leq_comp();
WORD mov_comp(), jmp_comp(), osr_comp(), ctt_comp(), ctf_comp();
WORD tmt_comp(), tmf_comp(), rtmt_comp(), rtmf_comp(), reset_comp(), lbl_comp();
WORD inv_comp();
void nullfn();

struct obj objs[NUMBER_OF_OBJECTS] =  /* indexed by enum objtypes */
{
   { blank_element, no_input,       inp_init,  inp_del,  inp_draw,  inp_comp  },
   { blank_element, nc_input,       ninp_init, ninp_del, ninp_draw, ninp_comp },
   { blank_element, no_output,      out_init,  out_del,  out_draw,  out_comp  },
   { blank_element, nc_output,      nout_init, nout_del, nout_draw, nout_comp },
   { " LAT ",       lat_output,     lout_init, lout_del, lout_draw, lout_comp },
   { " UNL ",       lat_output,     uout_init, uout_del, uout_draw, uout_comp },
   { " ADD ",       three_char_out, add_init,  add_del,  add_draw,  add_comp  },
   { " SUB ",       three_char_out, sub_init,  sub_del,  sub_draw,  sub_comp  },
   { " MUL ",       three_char_out, mul_init,  mul_del,  mul_draw,  mul_comp  },
   { " DIV ",       three_char_out, div_init,  div_del,  div_draw,  div_comp  },
   { " MOD ",       three_char_out, mod_init,  mod_del,  mod_draw,  mod_comp  },
   { " AND ",       three_char_out, and_init,  and_del,  and_draw,  and_comp  },
   { " OR ",        two_char_out,   or_init,   or_del,   or_draw,   or_comp   },
   { " XOR ",       three_char_out, xor_init,  xor_del,  xor_draw,  xor_comp  },
   { " NOT ",       three_char_out, not_init,  not_del,  not_draw,  not_comp  },
   { " NEG ",       three_char_out, neg_init,  neg_del,  neg_draw,  neg_comp  },
   { " EQ ",        two_char_inp,   equ_init,  equ_del,  equ_draw,  equ_comp  },
   { " NE ",        two_char_inp,   neq_init,  neq_del,  neq_draw,  neq_comp  },
   { " GT ",        two_char_inp,   grt_init,  grt_del,  grt_draw,  grt_comp  },
   { " GE ",        two_char_inp,   geq_init,  geq_del,  geq_draw,  geq_comp  },
   { " LT ",        two_char_inp,   les_init,  les_del,  les_draw,  les_comp  },
   { " LE ",        two_char_inp,   leq_init,  leq_del,  leq_draw,  leq_comp  },
   { " MOV ",       three_char_out, mov_init,  mov_del,  mov_draw,  mov_comp  },
   { " JMP ",       three_char_out, jmp_init,  jmp_del,  jmp_draw,  jmp_comp  },
   { " OSR ",       three_char_inp, osr_init,  osr_del,  osr_draw,  osr_comp  },
   { " CTT ",       three_char_inp, ctt_init,  ctt_del,  ctt_draw,  ctt_comp  },
   { " CTF ",       three_char_inp, ctf_init,  ctf_del,  ctf_draw,  ctf_comp  },
   { " TMT ",       three_char_inp, tmt_init,  tmt_del,  tmt_draw,  tmt_comp  },
   { " TMF ",       three_char_inp, tmf_init,  tmf_del,  tmf_draw,  tmf_comp  },
   { " RTT ",       three_char_inp, rtmt_init, rtmt_del, rtmt_draw, rtmt_comp },
   { " RTF ",       three_char_inp, rtmf_init, rtmf_del, rtmf_draw, rtmf_comp },
   { " RST ",       three_char_inp, reset_init,reset_del,reset_draw,reset_comp},
   { " INV ",       three_char_inp, inv_init,  inv_del,  inv_draw,  inv_comp },
   { " LBL ",       three_char_inp, lbl_init,  lbl_del,  lbl_draw,  lbl_comp  },
   { "Save",        null_str,       nullfn,    nullfn,    nullfn,   nullfn    },
   { "Load",        null_str,       nullfn,    nullfn,    nullfn,   nullfn    },
   { "New",         null_str,       nullfn,    nullfn,    nullfn,   nullfn    },
   { "Download"     null_str,       nullfn,    nullfn,    nullfn,   nullfn    },
   { "AddRow",      null_str,       nullfn,    nullfn,    nullfn,   nullfn    },
   { "DelRow",      null_str,       nullfn,    nullfn,    nullfn,   nullfn    },
   { "OneStep"      null_str,       nullfn,    nullfn,    nullfn,   nullfn    },
   { "LineStep",    null_str,       nullfn,    nullfn,    nullfn,   nullfn    },
   { "Run",         null_str,       nullfn,    nullfn,    nullfn,   nullfn    },
   { "Stop",        null_str,       nullfn,    nullfn,    nullfn,   nullfn    },
   { blank_element, or_branch,      nullfn,    nullfn,    nullfn,   nullfn    },
   { blank_element, expand_branch,  nullfn,    nullfn,    nullfn,   nullfn    },
   { "(c) Bill",    null_str,       nullfn,    nullfn,    nullfn,   nullfn    },
   { " Couture",    null_str,       nullfn,    nullfn,    nullfn,   nullfn    },
   { "    2006",    null_str,       nullfn,    nullfn,    nullfn,   nullfn    },
   { "V0.01A",      null_str,       nullfn,    nullfn,    nullfn,   nullfn    },
   { "Exit",        null_str,       nullfn,    nullfn,    nullfn,   nullfn    },
   { null_str,      null_str,       nullfn,    nullfn,    nullfn,   nullfn    }, /* ladder object */
   { null_str,      null_str,       nullfn,    nullfn,    nullfn,   nullfn    }, /* default mouse_object */
   { null_str,      null_str,       nullfn,    nullfn,    nullfn,   nullfn    }  /* scroll object */
};

struct element_info menu[] =
{
   {   0,     TEXTHEIGHT, MENUCOL1, MENUCOL1 + 4 * TEXTWIDTH, SAVE_OBJ, filesave, NULL },
   {   0,     TEXTHEIGHT, MENUCOL2, MENUCOL2 + 4 * TEXTWIDTH, LOAD_OBJ, fileload, NULL },
   {  32,  32+TEXTHEIGHT, MENUCOL1, MENUCOL1 + 3 * TEXTWIDTH, NEW_OBJ,  newladder, NULL },
   {  32,  32+TEXTHEIGHT, MENUCOL2, MENUCOL2 + 7 * TEXTWIDTH, DOWNLOAD_OBJ, download, NULL },
#ifdef SIMPLE_ADDROW
   {  56,  56+TEXTHEIGHT, MENUCOL1, MENUCOL1 + 6 * TEXTWIDTH, ADDROW_OBJ, addrow, NULL },
   {  56,  56+TEXTHEIGHT, MENUCOL2, MENUCOL2 + 6 * TEXTWIDTH, DELROW_OBJ, delrow, NULL },
#else
   {  56,  56+TEXTHEIGHT, MENUCOL1, MENUCOL1 + 6 * TEXTWIDTH, ADDROW_OBJ, pickup, appendrow },
   {  56,  56+TEXTHEIGHT, MENUCOL2, MENUCOL2 + 6 * TEXTWIDTH, DELROW_OBJ, pickup, NULL },
#endif
   {  88,  88+TEXTHEIGHT, MENUCOL1, MENUCOL1 + 7 * TEXTWIDTH, ONESTEP_OBJ,onestep, NULL },
   {  88,  88+TEXTHEIGHT, MENUCOL2, MENUCOL2 + 7 * TEXTWIDTH, LINESTEP_OBJ,linestep, NULL },
   { 112, 112+TEXTHEIGHT, MENUCOL1, MENUCOL1 + 3 * TEXTWIDTH, RUN_OBJ,   run, NULL },
   { 112, 112+TEXTHEIGHT, MENUCOL2, MENUCOL2 + 4 * TEXTWIDTH, STOP_OBJ,  stop, NULL },
   { MENULINE(0),  ENDLINE(0),  MENUCOL1, ENDCOL1, INP_OBJ,   pickup, NULL },
   { MENULINE(0),  ENDLINE(0),  MENUCOL2, ENDCOL2, NINP_OBJ,  pickup, NULL },
   { MENULINE(1),  ENDLINE(1),  MENUCOL1, ENDCOL1, OUT_OBJ,   pickup, NULL },
   { MENULINE(1),  ENDLINE(1),  MENUCOL2, ENDCOL2, NOUT_OBJ,  pickup, NULL },
   { MENULINE(2),  ENDLINE(2),  MENUCOL1, ENDCOL1, LOUT_OBJ,  pickup, NULL },
   { MENULINE(2),  ENDLINE(2),  MENUCOL2, ENDCOL2, UOUT_OBJ,  pickup, NULL },
   { MENULINE(3),  ENDLINE(3),  MENUCOL1, ENDCOL1, ADD_OBJ,   pickup, NULL },
   { MENULINE(3),  ENDLINE(3),  MENUCOL2, ENDCOL2, SUB_OBJ,   pickup, NULL },
   { MENULINE(4),  ENDLINE(4),  MENUCOL1, ENDCOL1, MUL_OBJ,   pickup, NULL },
   { MENULINE(4),  ENDLINE(4),  MENUCOL2, ENDCOL2, DIV_OBJ,   pickup, NULL },
   { MENULINE(5),  ENDLINE(5),  MENUCOL1, ENDCOL1, MOD_OBJ,   pickup, NULL },
   { MENULINE(5),  ENDLINE(5),  MENUCOL2, ENDCOL2, NEG_OBJ,   pickup, NULL },
   { MENULINE(6),  ENDLINE(6),  MENUCOL1, ENDCOL1, AND_OBJ,   pickup, NULL },
   { MENULINE(6),  ENDLINE(6),  MENUCOL2, ENDCOL2, OR_OBJ     pickup, NULL },
   { MENULINE(7),  ENDLINE(7),  MENUCOL1, ENDCOL1, XOR_OBJ,   pickup, NULL },
   { MENULINE(7),  ENDLINE(7),  MENUCOL2, ENDCOL2, NOT_OBJ,   pickup, NULL },
   { MENULINE(8),  ENDLINE(8),  MENUCOL1, ENDCOL1, EQU_OBJ,   pickup, NULL },
   { MENULINE(8),  ENDLINE(8),  MENUCOL2, ENDCOL2, NEQ_OBJ,   pickup, NULL },
   { MENULINE(9),  ENDLINE(9),  MENUCOL1, ENDCOL1, GRT_OBJ,   pickup, NULL },
   { MENULINE(9),  ENDLINE(9),  MENUCOL2, ENDCOL2, GEQ_OBJ,   pickup, NULL },
   { MENULINE(10), ENDLINE(10), MENUCOL1, ENDCOL1, LES_OBJ,   pickup, NULL },
   { MENULINE(10), ENDLINE(10), MENUCOL2, ENDCOL2, LEQ_OBJ    pickup, NULL },
   { MENULINE(11), ENDLINE(11), MENUCOL1, ENDCOL1, MOV_OBJ,   pickup, NULL },
   { MENULINE(11), ENDLINE(11), MENUCOL2, ENDCOL2, OSR_OBJ,   pickup, NULL },
   { MENULINE(12), ENDLINE(12), MENUCOL1, ENDCOL1, JMP_OBJ,   pickup, NULL },
   { MENULINE(12), ENDLINE(12), MENUCOL2, ENDCOL2, LBL_OBJ,   pickup, NULL },
   { MENULINE(13), ENDLINE(13), MENUCOL1, ENDCOL1, CTT_OBJ,   pickup, NULL },
   { MENULINE(13), ENDLINE(13), MENUCOL2, ENDCOL2, CTF_OBJ,   pickup, NULL },
   { MENULINE(14), ENDLINE(14), MENUCOL1, ENDCOL1, TMT_OBJ,   pickup, NULL },
   { MENULINE(14), ENDLINE(14), MENUCOL2, ENDCOL2, TMF_OBJ,   pickup, NULL },
   { MENULINE(15), ENDLINE(15), MENUCOL1, ENDCOL1, RTMT_OBJ,  pickup, NULL },
   { MENULINE(15), ENDLINE(15), MENUCOL2, ENDCOL2, RTMF_OBJ,  pickup, NULL },
   { MENULINE(16), ENDLINE(16), MENUCOL1, ENDCOL1, RESET_OBJ, pickup, NULL },
   { MENULINE(16), ENDLINE(16), MENUCOL2, ENDCOL2, INVERT_OBJ,pickup, NULL },
   { MENULINE(17), ENDLINE(17), MENUCOL1, ENDCOL1, ORBRANCH_OBJ, pickup, NULL },
   { MENULINE(17), ENDLINE(17), MENUCOL2, ENDCOL2, EXPAND_OBJ,pickup, NULL },
   { MENULINE(20), ENDLINE(20), MENUCOL1, ENDCOL1, COPYR1_OBJ,NULL, NULL },
   { MENULINE(20), ENDLINE(20), MENUCOL2, ENDCOL2, COPYR2_OBJ,NULL, NULL },
   { MENULINE(21), ENDLINE(21), MENUCOL1, ENDCOL1, COPYR3_OBJ,NULL, NULL },
   { MENULINE(22), ENDLINE(22), MENUCOL1, ENDCOL1, VERSION_OBJ,NULL, NULL },
   { MENULINE(25), ENDLINE(25), MENUCOL1, ENDCOL1, EXIT_OBJ,  quit, NULL },
   { SCROLL_TOP,   SCROLL_BOTTOM,SCROLL_LEFTCOL, SCROLL_RIGHTCOL, SCROLL_OBJ, scrollladder, NULL }
};
#define NUM_MENU_ELEMENTS 52
WORD screen_index = NUM_MENU_ELEMENTS;
struct element_info *screen_list[SCREEN_MAX];

WORD dirty = FALSE;
WORD exitflag = FALSE;
WORD quickexit = FALSE;
/* WORD quickexit = TRUE; */  /* default for testing */

void ladder_node_add();
void ladder_node_del();
struct ladder_rung rungs[MAX_RUNGS];
WORD used_rungs[MAX_RUNGS];
WORD rung_list[MAX_RUNGS+1];
WORD ladder_size = 1;

#define FILEVERSION_LEN 16
/* BYTE fileversion[FILEVERSION_LEN] = "Athena 0.00A"; */
                                  /* 0123456789ab */
BYTE fileversion[FILEVERSION_LEN] = "TinyPLC 0.01A";
                                  /* 0123456789abc */

DWORD modbus_dataregs[PLC_MEMORY_LOCS];
BYTE program[MAX_PROGRAM];
WORD program_len;
WORD label_addresses[NUM_LABELS];

WORD scroll_baserow;

WORD is_littleendian = TRUE;

WORD peekw(), get_timer();

main(argc,argv)
   int argc;
   char *argv[];
   {
   WORD i, j;

   get_vesa_mode();
   havemouse = init_mouse();
   if (!vesa_mode)
      {
      printf("Error:  suitable VESA mode not found!\n");
      exit(1);
      }
   if (!havemouse)
      {
      printf("No mouse available!\n");
      exit(1);
      }

   for (i = 1; i < argc; i++)
      {
      if (argv[i][0] == '-')
         {
         switch(toupper(argv[i][1]))
            {
            case 'B':  /* Baudrate */
               if (!argv[i][2])

⌨️ 快捷键说明

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