void main() { void interrupt ( * old_dos9h ) () ; /* points at DOS keyboard interrupt service routine */ void interrupt ( * old_dos62 ) () ; /* previous int 62h handler */ void interrupt ( * old_dos63 ) () ; /* previous int 63h handler */ int id , /* ID of init process */ dosint , /* Interrupt flag upon entry */ count ; /* init process's argc */ char * argument[10] ; /* pointer to a maximum of 10 arguments */ Init_malloc (); /* Activate the safe memory management routines */ /* Init_malloc() uses malloc() which requires */ /* interrupts to be enabled */ /* Initialization */ dosint = Mod_int ( INT_DISABLE ) ; /* Disable all interrupts */ readyq = Q_create () ; /* Create a queue for ready processes */ keyboard_buff_ptr = Q_create () ; /* Create a queue for the keyboard */ old_dos9h = getvect ( 0x9 ) ; /* Preserve dos ISR's */ old_dos62 = getvect ( 0x62 ) ; old_dos63 = getvect ( 0x63 ) ; setvect ( 0x9 , Key_handler ); /* redirect Keyboard ISR from DOS to keyhand */ setvect ( 0x62, System_service ) ; /* Set kernel ISR */ setvect ( 0x63 , Yield_process ) ; /* Set defer ISR */ Init_screen () ; /* main loop */ Cprintf ("\nThis is the main procedure\n"); Cprintf ("Now I will init as a child processes\n") ; count = 3 ; argument [0] = "Init" ; argument [1] = "init 1st parameter" ; argument [2] = "init 2nd parameter" ; id = Proc_start ( Init , count , argument ) ; Cprintf ("Process init has been created with ID = %2d\n" , id ) ; Cprintf ("Now, main() is going to call scheduler() \n") ; Scheduler() ; /* Clean-up */ Cprintf("\nNo more processes , I will finish up and exit OS\n"); Q_destroy ( readyq ) ; Q_destroy ( keyboard_buff_ptr ) ; Free_malloc () ; /* dactivate the safe memory management routines */ setvect ( 0x9 , old_dos9h ) ; /* Return to DOS keyboard driver */ setvect ( 0x62, old_dos62 ) ; setvect ( 0x63, old_dos63 ) ; Mod_int ( dosint ) ; /* restore interrupt flag */ _AX = 0x100 ; /* restore hardware cursor */ _CX = 0xD0E ; geninterrupt ( 0x10 ) ; } /* end of main() */
/* * Serial_open * * Serial_open configures the specified serial port (USART) for operation according the specified baud rate and configuration. * It uses Queue functions to allocate a QCB to manage transmit and receive buffers. It initializes the interface between the * ISRs (RXC and UDRE) and the queues for the port by initializing the QCB "handles" to be used by the ISRs. The RXCx interrupt is enabled. * Serial_open returns 0 for success and -1 if an error occurs (e.g., bad port ID, baud rate, frame parameters or invalid buffer sizes). * * @param int port - specifies USART 0, 1, 2 or 3. For right now, 0 is the only one active. * @param long speed - baud rate * @param constant that specifies framing parameters (data bits, parity, stop bits) * @return returns 0 for success and -1 if an error occurs */ int Serial_open(int port, long speed, int config) { if (port < 0 || port > 3) { return -1; } //Creates a Rqueue forRX and TX ports[port].rx_qid = Q_create(ports[port].rx_bufsize, ports[port].rx_buffer); ports[port].tx_qid = Q_create(ports[port].tx_bufsize, ports[port].tx_buffer); //Sets U2X0 to 1 for lowest error rate regs[port]->ucsra |= (1<<U2X0); //Changed made here long reg_set = -1; switch(speed) { case 2400: reg_set = 832; break; case 4800: reg_set = 416; break; case 9600: reg_set = 207; break; case 14400: reg_set = 138; break; case 19200: reg_set = 103; break; case 28800: reg_set = 68; break; case 38400L: reg_set = 51; break; case 57600L: reg_set = 34; break; case 76800L: reg_set = 25; break; case 115200L: reg_set = 16; break; case 230400L: reg_set = 8; break; case 250000L: reg_set = 7; break; } //Protects from interrupts ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { regs[port]->ubrr = reg_set; //Sets the baud rate regs[port]->ucsrc = config; //Sets the data frame structure regs[port]->ucsrb = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0); //Enables RX, TX, and RX interrupt } sei(); //Enables global interrupts return 0; }