X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=sim%2Fucsim%2Fs51.src%2Fserial.cc;h=e36fb422b05d924451a3f461a045e1ab97a12759;hb=34d14506fd0c12ee5434fec0f9dec27753e1aab5;hp=3b5436d0c70176487f9ea3e5fd27256ab0f01045;hpb=0e1bba0730e55b3d40c1c644d94befc99c87270d;p=fw%2Fsdcc diff --git a/sim/ucsim/s51.src/serial.cc b/sim/ucsim/s51.src/serial.cc index 3b5436d0..e36fb422 100644 --- a/sim/ucsim/s51.src/serial.cc +++ b/sim/ucsim/s51.src/serial.cc @@ -2,7 +2,7 @@ * Simulator of microcontrollers (serial.cc) * * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. - * + * * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu * */ @@ -30,12 +30,17 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include #include #include +#ifdef HAVE_TERMIOS_H #include +#endif +#ifdef HAVE_UNISTD_H #include +#endif #include #include #include #include +#include // prj #include "globals.h" @@ -44,36 +49,47 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "serialcl.h" #include "regs51.h" #include "uc51cl.h" +#include "cmdutil.h" cl_serial::cl_serial(class cl_uc *auc): cl_hw(auc, HW_UART, 0, "uart") -{} +{ + serial_in= serial_out= NIL; +} cl_serial::~cl_serial(void) { + if (serial_in != serial_out && serial_in) + { +#ifdef HAVE_TERMIOS_H + if (isatty(fileno(serial_in))) + tcsetattr(fileno(serial_in), TCSANOW, &saved_attributes_in); +#endif + fclose(serial_in); + } if (serial_out) { +#ifdef HAVE_TERMIOS_H if (isatty(fileno(serial_out))) - tcsetattr(fileno(serial_out), TCSANOW, &saved_attributes_out); + tcsetattr(fileno(serial_out), TCSANOW, &saved_attributes_out); +#endif fclose(serial_out); } - if (serial_in) - { - if (isatty(fileno(serial_in))) - tcsetattr(fileno(serial_in), TCSANOW, &saved_attributes_in); - fclose(serial_in); - } + delete serial_in_file_option; + delete serial_out_file_option; } int cl_serial::init(void) { - class cl_mem *sfr; +#ifdef HAVE_TERMIOS_H int i; struct termios tattr; +#endif - sfr= uc->mem(MEM_SFR); + set_name("mcs51_uart"); + sfr= uc->address_space(MEM_SFR_ID); if (sfr) { //sbuf= sfr->register_hw(SBUF, this, 0); @@ -84,57 +100,81 @@ cl_serial::init(void) register_cell(sfr, SCON, &scon, wtd_restore_write); } - serial_in = (FILE*)application->args->get_parg(0, "Ser_in"); - serial_out= (FILE*)application->args->get_parg(0, "Ser_out"); - if (serial_in) + serial_in_file_option= new cl_optref(this); + serial_in_file_option->init(); + serial_in_file_option->use("serial_in_file"); + serial_out_file_option= new cl_optref(this); + serial_out_file_option->init(); + serial_out_file_option->use("serial_out_file"); + + //char *fni, *fno; + /*if ((fni= serial_in_file_option->get_value((char*)0))) + serial_in= fopen(fni, "r"); + if ((fno= serial_out_file_option->get_value((char*)0))) + serial_out= fopen(fno, "w");*/ + + //serial_in = (FILE*)application->args->get_parg(0, "Ser_in"); + //serial_out= (FILE*)application->args->get_parg(0, "Ser_out"); + serial_in = (FILE*)serial_in_file_option->get_value((void*)0); + serial_out= (FILE*)serial_out_file_option->get_value((void*)0); + + if (serial_in != serial_out && serial_in) { // making `serial' unbuffered if (setvbuf(serial_in, NULL, _IONBF, 0)) - perror("Unbuffer serial input channel"); + perror("Unbuffer serial input channel"); +#ifdef _WIN32 + if (CH_SERIAL != get_handle_type((HANDLE)_get_osfhandle(fileno(serial_in)))) +#elif defined HAVE_TERMIOS_H // setting O_NONBLOCK if ((i= fcntl(fileno(serial_in), F_GETFL, 0)) < 0) - perror("Get flags of serial input"); + perror("Get flags of serial input"); i|= O_NONBLOCK; if (fcntl(fileno(serial_in), F_SETFL, i) < 0) - perror("Set flags of serial input"); + perror("Set flags of serial input"); // switching terminal to noncanonical mode if (isatty(fileno(serial_in))) - { - tcgetattr(fileno(serial_in), &saved_attributes_in); - tcgetattr(fileno(serial_in), &tattr); - tattr.c_lflag&= ~(ICANON|ECHO); - tattr.c_cc[VMIN] = 1; - tattr.c_cc[VTIME]= 0; - tcsetattr(fileno(serial_in), TCSAFLUSH, &tattr); - } + { + tcgetattr(fileno(serial_in), &saved_attributes_in); + tcgetattr(fileno(serial_in), &tattr); + tattr.c_lflag&= ~(ICANON|ECHO); + tattr.c_cc[VMIN] = 1; + tattr.c_cc[VTIME]= 0; + tcsetattr(fileno(serial_in), TCSAFLUSH, &tattr); + } else - fprintf(stderr, "Warning: serial input interface connected to a " - "non-terminal file.\n"); +#endif + fprintf(stderr, "Warning: serial input interface connected to a " + "non-terminal file.\n"); } if (serial_out) { // making `serial' unbuffered if (setvbuf(serial_out, NULL, _IONBF, 0)) - perror("Unbuffer serial output channel"); + perror("Unbuffer serial output channel"); +#ifdef _WIN32 + if (CH_SERIAL != get_handle_type((HANDLE)_get_osfhandle(fileno(serial_out)))) +#elif defined HAVE_TERMIOS_H // setting O_NONBLOCK if ((i= fcntl(fileno(serial_out), F_GETFL, 0)) < 0) - perror("Get flags of serial output"); + perror("Get flags of serial output"); i|= O_NONBLOCK; if (fcntl(fileno(serial_out), F_SETFL, i) < 0) - perror("Set flags of serial output"); + perror("Set flags of serial output"); // switching terminal to noncanonical mode if (isatty(fileno(serial_out))) - { - tcgetattr(fileno(serial_out), &saved_attributes_out); - tcgetattr(fileno(serial_out), &tattr); - tattr.c_lflag&= ~(ICANON|ECHO); - tattr.c_cc[VMIN] = 1; - tattr.c_cc[VTIME]= 0; - tcsetattr(fileno(serial_out), TCSAFLUSH, &tattr); - } + { + tcgetattr(fileno(serial_out), &saved_attributes_out); + tcgetattr(fileno(serial_out), &tattr); + tattr.c_lflag&= ~(ICANON|ECHO); + tattr.c_cc[VMIN] = 1; + tattr.c_cc[VTIME]= 0; + tcsetattr(fileno(serial_out), TCSAFLUSH, &tattr); + } else - fprintf(stderr, "Warning: serial output interface connected to a " - "non-terminal file.\n"); +#endif + fprintf(stderr, "Warning: serial output interface connected to a " + "non-terminal file.\n"); } class cl_hw *t2= uc->get_hw(HW_TIMER, 2, 0); @@ -156,7 +196,7 @@ cl_serial::new_hw_added(class cl_hw *new_hw) new_hw->id == 2) { there_is_t2= DD_TRUE; - t_mem d= uc->mem(MEM_SFR)->get(T2CON); + t_mem d= sfr->get(T2CON); t2_baud= d & (bmRCLK | bmTCLK); } } @@ -165,13 +205,13 @@ void cl_serial::added_to_uc(void) { uc->it_sources->add(new cl_it_src(bmES , SCON, bmTI , 0x0023, false, - "serial transmit", 6)); + "serial transmit", 6)); uc->it_sources->add(new cl_it_src(bmES , SCON, bmRI , 0x0023, false, - "serial receive", 6)); + "serial receive", 6)); } t_mem -cl_serial::read(class cl_cell *cell) +cl_serial::read(class cl_memory_cell *cell) { if (cell == sbuf) return(s_in); @@ -180,7 +220,7 @@ cl_serial::read(class cl_cell *cell) } void -cl_serial::write(class cl_cell *cell, t_mem *val) +cl_serial::write(class cl_memory_cell *cell, t_mem *val) { if (cell == sbuf) { @@ -196,49 +236,48 @@ cl_serial::write(class cl_cell *cell, t_mem *val) _bmREN= *val & bmREN; _bits= 8; switch (_mode) - { - case 0: - _bits= 8; - _divby= 12; - break; - case 1: - _bits= 10; - _divby= _bmSMOD?16:32; - break; - case 2: - _bits= 11; - _divby= _bmSMOD?16:32; - break; - case 3: - _bits= 11; - _divby= _bmSMOD?16:32; - break; - } + { + case 0: + _bits= 8; + _divby= 12; + break; + case 1: + _bits= 10; + _divby= _bmSMOD?16:32; + break; + case 2: + _bits= 11; + _divby= _bmSMOD?16:32; + break; + case 3: + _bits= 11; + _divby= _bmSMOD?16:32; + break; + } } else if (cell == pcon) { _bmSMOD= *val & bmSMOD; /*switch (_mode) - { - case 1: - _divby= _bmSMOD?16:32; - break; - case 2: - _divby= _bmSMOD?16:32; - break; - case 3: - _divby= _bmSMOD?16:32; - break; - }*/ + { + case 1: + _divby= _bmSMOD?16:32; + break; + case 2: + _divby= _bmSMOD?16:32; + break; + case 3: + _divby= _bmSMOD?16:32; + break; + }*/ if (_mode) - _divby= _bmSMOD?16:32; + _divby= _bmSMOD?16:32; } } /*void -cl_serial::mem_cell_changed(class cl_mem *mem, t_addr addr) +cl_serial::mem_cell_changed(class cl_m *mem, t_addr addr) { - class cl_mem *sfr= uc->mem(MEM_SFR); t_mem d; d= sbuf->get(); @@ -279,19 +318,19 @@ cl_serial::serial_bit_cnt(void) if (s_sending) { while (*tr_src >= _divby) - { - (*tr_src)-= _divby; - s_tr_bit++; - //printf("serial bit sent %d\n",uc->ticks->ticks); - } + { + (*tr_src)-= _divby; + s_tr_bit++; + //printf("serial bit sent %d\n",uc->ticks->ticks); + } } if (s_receiving) { while (*rec_src >= _divby) - { - (*rec_src)-= _divby; - s_rec_bit++; - } + { + (*rec_src)-= _divby; + s_rec_bit++; + } } return(0); } @@ -308,10 +347,10 @@ cl_serial::tick(int cycles) s_sending= DD_FALSE; scon->set_bit1(bmTI); if (serial_out) - { - putc(s_out, serial_out); - fflush(serial_out); - } + { + putc(s_out, serial_out); + fflush(serial_out); + } s_tr_bit-= _bits; //printf("serial out %d bit rems %d\n",s_tr_bit,uc->ticks->ticks); } @@ -319,31 +358,33 @@ cl_serial::tick(int cycles) serial_in && !s_receiving) { - fd_set set; static struct timeval timeout= {0,0}; - FD_ZERO(&set); - FD_SET(fileno(serial_in), &set); - int i= select(fileno(serial_in)+1, &set, NULL, NULL, &timeout); - if (i > 0 && - FD_ISSET(fileno(serial_in), &set)) - { - s_receiving= DD_TRUE; - s_rec_bit= 0; - s_rec_tick= /*uc51->*/s_rec_t1= 0; - } +#ifdef _WIN32 + HANDLE handle = (HANDLE)_get_osfhandle(fileno(serial_in)); + assert(INVALID_HANDLE_VALUE != handle); + + if (input_avail(handle)) +#else + if (input_avail(fileno(serial_in))) +#endif + { + s_receiving= DD_TRUE; + s_rec_bit= 0; + s_rec_tick= /*uc51->*/s_rec_t1= 0; + } } if (s_receiving && (s_rec_bit >= _bits)) { if (::read(fileno(serial_in), &c, 1) == 1) - { - s_in= c; - sbuf->set(s_in); - received(c); - } + { + s_in= c; + sbuf->set(s_in); + received(c); + } s_receiving= DD_FALSE; s_rec_bit-= _bits; } - + int l; s_tr_tick+= (l= cycles * uc->clock_per_cycle()); s_rec_tick+= l; @@ -377,41 +418,41 @@ cl_serial::happen(class cl_hw *where, enum hw_event he, void *params) if (where->cathegory == HW_TIMER) { if (where->id == 1) - { - //printf("serial: timer overflowed %ld\n", uc->ticks->ticks); - s_rec_t1++; - s_tr_t1++; - } + { + //printf("serial: timer overflowed %ld\n", uc->ticks->ticks); + s_rec_t1++; + s_tr_t1++; + } if (where->id == 2 /*&& there_is_t2*/) - { - switch (he) - { - case EV_T2_MODE_CHANGED: - { - if (!t2_baud) - s_rec_t1= s_tr_t1= 0; - t_mem *d= (t_mem *)params; - t2_baud= *d & (bmRCLK | bmTCLK); - break; - } - case EV_OVERFLOW: - //printf("T2 baud ov r%d t%d\n",s_rec_t1,s_tr_t1); - s_rec_t1++; - s_tr_t1++; - break; - default: break; - } - } + { + switch (he) + { + case EV_T2_MODE_CHANGED: + { + if (!t2_baud) + s_rec_t1= s_tr_t1= 0; + t_mem *d= (t_mem *)params; + t2_baud= *d & (bmRCLK | bmTCLK); + break; + } + case EV_OVERFLOW: + //printf("T2 baud ov r%d t%d\n",s_rec_t1,s_tr_t1); + s_rec_t1++; + s_tr_t1++; + break; + default: break; + } + } } } void -cl_serial::print_info(class cl_console *con) +cl_serial::print_info(class cl_console_base *con) { - char *modes[]= { "Shift, fixed clock", - "8 bit UART timer clocked", - "9 bit UART fixed clock", - "9 bit UART timer clocked" }; + const char *modes[]= { "Shift, fixed clock", + "8 bit UART timer clocked", + "9 bit UART fixed clock", + "9 bit UART timer clocked" }; int sc= scon->get(); con->dd_printf("%s[%d]", id_string, id); @@ -420,8 +461,8 @@ cl_serial::print_info(class cl_console *con) if (mode == 1 || mode == 2) con->dd_printf(" (timer%d)", (t2_baud)?2:1); con->dd_printf(" MultiProc=%s", - (mode&2)?((sc&bmSM2)?"ON":"OFF"):"none"); - con->dd_printf(" irq=%s", (uc->get_mem(MEM_SFR, IE)&bmES)?"en":"dis"); + (mode&2)?((sc&bmSM2)?"ON":"OFF"):"none"); + con->dd_printf(" irq=%s", (sfr->get(IE)&bmES)?"en":"dis"); con->dd_printf(" prio=%d", uc->it_priority(bmPS)); con->dd_printf("\n"); @@ -436,10 +477,10 @@ cl_serial::print_info(class cl_console *con) con->dd_printf(" irq=%c", (sc&bmTI)?'1':'0'); con->dd_printf("\n"); /*con->dd_printf("s_rec_t1=%d s_rec_bit=%d s_rec_tick=%d\n", - s_rec_t1, s_rec_bit, s_rec_tick); + s_rec_t1, s_rec_bit, s_rec_tick); con->dd_printf("s_tr_t1=%d s_tr_bit=%d s_tr_tick=%d\n", - s_tr_t1, s_tr_bit, s_tr_tick); - con->dd_printf("divby=%d bits=%d\n", _divby, _bits);*/ + s_tr_t1, s_tr_bit, s_tr_tick); + con->dd_printf("divby=%d bits=%d\n", _divby, _bits);*/ }