/** * <Ring 1> This routine handles DEV_READ and DEV_WRITE message. * * @param p Message ptr. *****************************************************************************/ PRIVATE void hd_rdwt(MESSAGE * p) { int drive = DRV_OF_DEV(p->DEVICE); u64 pos = p->POSITION; assert((pos >> SECTOR_SIZE_SHIFT) < (1 << 31)); /** * We only allow to R/W from a SECTOR boundary: */ assert((pos & 0x1FF) == 0); u32 sect_nr = (u32)(pos >> SECTOR_SIZE_SHIFT); /* pos / SECTOR_SIZE */ int logidx = (p->DEVICE - MINOR_hd1a) % NR_SUB_PER_DRIVE; sect_nr += p->DEVICE < MAX_PRIM ? hd_info[drive].primary[p->DEVICE].base : hd_info[drive].logical[logidx].base; struct hd_cmd cmd; cmd.features = 0; cmd.count = (p->CNT + SECTOR_SIZE - 1) / SECTOR_SIZE; cmd.lba_low = sect_nr & 0xFF; cmd.lba_mid = (sect_nr >> 8) & 0xFF; cmd.lba_high = (sect_nr >> 16) & 0xFF; cmd.device = MAKE_DEVICE_REG(1, drive, (sect_nr >> 24) & 0xF); cmd.command = (p->type == DEV_READ) ? ATA_READ : ATA_WRITE; hd_cmd_out(&cmd); int bytes_left = p->CNT; void * la = (void*)va2la(p->PROC_NR, p->BUF); while (bytes_left) { int bytes = min(SECTOR_SIZE, bytes_left); if (p->type == DEV_READ) { interrupt_wait(); port_read(REG_DATA, hdbuf, SECTOR_SIZE); verify_area((u32)la, bytes); phys_copy(la, (void*)va2la(TASK_HD, hdbuf), bytes); } else { if (!waitfor(STATUS_DRQ, STATUS_DRQ, HD_TIMEOUT)) panic("hd writing error."); port_write(REG_DATA, la, bytes); interrupt_wait(); } bytes_left -= SECTOR_SIZE; la += SECTOR_SIZE; } }
// 处理请求队列里面所有请求 void do_hd_request(void) { int i,r = 0; unsigned int block,dev; unsigned int sec,head,cyl; unsigned int nsect; INIT_REQUEST; dev = MINOR(CURRENT->dev); block = CURRENT->sector; if (dev >= 5*NR_HD || block+2 > hd[dev].nr_sects) { end_request(0); goto repeat; } block += hd[dev].start_sect; dev /= 5; __asm__("divl %4":"=a" (block),"=d" (sec):"0" (block),"1" (0), "r" (hd_info[dev].sect)); __asm__("divl %4":"=a" (cyl),"=d" (head):"0" (block),"1" (0), "r" (hd_info[dev].head)); sec++; nsect = CURRENT->nr_sectors; if (reset) { reset = 0; recalibrate = 1; reset_hd(CURRENT_DEV); return; } if (recalibrate) { recalibrate = 0; hd_out(dev,hd_info[CURRENT_DEV].sect,0,0,0, WIN_RESTORE,&recal_intr); return; } if (CURRENT->cmd == WRITE) { hd_out(dev,nsect,sec,head,cyl,WIN_WRITE,&write_intr); for(i=0 ; i<3000 && !(r=inb_p(HD_STATUS)&DRQ_STAT) ; i++) /* nothing */ ; if (!r) { bad_rw_intr(); goto repeat; } port_write(HD_DATA,CURRENT->buffer,256); } else if (CURRENT->cmd == READ) { // 设置回调函数 read_intr 直接返回 hd_out(dev,nsect,sec,head,cyl,WIN_READ,&read_intr); } else panic("unknown hd-command"); }
static void write_intr(void) { if (win_result()) { bad_rw_intr(); return; } if (--CURRENT->nr_sectors) { CURRENT->sector++; CURRENT->buffer += 512; port_write(HD_DATA,CURRENT->buffer,256); return; } end_request(1); do_hd_request(); }
/* Инициализация прикладного объекта */ void sys_init() { port_attr_t port_attr; /* Настройка ножки светодиода */ PIN_SET( port_attr.dir, GREEN_LED, PIN_HI ); /* Направление на вывод */ PIN_CLEAR( port_attr.sel, GREEN_LED); /* Функция ввода/вывода */ PIN_CLEAR( port_attr.ie, GREEN_LED); /* Запрет прерываний */ port_set_attr( LED_PORT, GREEN_LED, &port_attr ); port_write( LED_PORT, GREEN_LED, PIN_LO ); atimer_set( ASYNC_TIMER , atimer_counter() + WAIT_PERIOD ); return; }
void main(void) { int i; port_mode(&port0, PullNone); // Only PortA or PortB is available now port_init(&port0, PortA, 0xFF, PIN_OUTPUT); while(1){ for (i=0;i<LED_PATTERN_NUM;i++) { port_write(&port0, led_pattern[i]); wait_ms(200); } } }
//读状态 u8 lcd1602_busy(void) { u8 result; port_write(0xff); RS_CLR; RW_SET; EN_CLR; EN_CLR; EN_SET; asm("nop"); // asm("nop"); //delay_ms(5); port_in(); while(port_read() & 0x80); //EN_CLR; return port_read(); }
static void write_intr(void) { if (win_result()) { bad_rw_intr(); return; } if (--this_request->nsector) { port_write(HD_DATA, this_request->bh->b_data + 512, 256); return; } this_request->bh->b_uptodate = 1; this_request->bh->b_dirt = 0; wake_up(&wait_for_request); unlock_buffer(this_request->bh); this_request->hd = -1; this_request = this_request->next; do_request(); }
PRIVAATE void hd_rdwt(MESSAGE *p) { int drive = DRV_OF_DEV(p->DEVICE); u64_t pos = p->POSITION; u32_t sect_nr = (u32_t)(pos >> SECTOR_SIZE_SHIFT); int logidx = (p->DEVICE - MINOR_HD1a) % NR_SUB_PER_DRIVE; sect_nr += p->DEVICE < MAX_PRIM ? hd_info[drive].primary[p->DEVICE].base : hd_info[drive].logical[logidx].base; struct hd_cmd cmd; cmd.features = 0; cmd.count = (p->CNT + SECTOR_SIZE - 1) / SECTOR_SIZE; cmd.lba_low = sect_nr & 0xff; cmd.lba_mid = (sect_nr >> 8) & 0xff; cmd.lba_high = (sect_nr >> 16) & 0xff; cmd.device = MAKE_DEVICE_REG(1, drive, (sect_nr >> 24) & 0xf); cmd.command = (p->type == DEV_READ) ? ATA_READ : ATA_WRITE; hd_cmd_out(&cmd); int bytes_left = p->CNT; void *la = (void*)va2la(p->PROC_NR, p->BUF); while (bytes_left) { int bytes = min(SECTOR_SIZE, bytes_left); if (p->type == DEV_READ) { interrupt_wait(); port_read(REG_DATA, hdbuf, SECTOR_SIZE); phys_copy(la, (void*)va2la(TASK_HD, hdbuf), bytes); } else { if (!waitfor(STATUS_DRQ, STATUS_DRQ, HD_TIMEOUT)) { kprintf("[KERNEL ERROR]hd writing error.\n"); break; } port_write(REG_DATA, la, bytes); interrupt_wait(); } bytes_left -= SECTOR_SIZE; la += SECTOR_SIZE; } }
static void write_intr(void) { if (win_result()) { bad_rw_intr(); do_hd_request(); return; } if (--CURRENT_REQ->nr_sectors) { CURRENT_REQ->start_sector++; CURRENT_REQ->buffer += 512; do_hd = &write_intr; port_write(HD_DATA, CURRENT_REQ->buffer, 256); return; } end_request(1); /* this time request done */ do_hd_request(); /* do other hd request */ }
static void in2000_fifo_out(void) /* uses FIFOCNTR */ { unsigned count, infcnt, txcnt; infcnt = inb(INFCNT)& 0xfe; /* FIFO counter */ do { txcnt = in2000_txcnt(); /*DEB(printk("FIw:%d %02x %d\n", in2000_datalen, infcnt, txcnt));*/ count = (infcnt << 3) - 32; /* don't fill completely */ if ( count > in2000_datalen ) count = in2000_datalen; /* limit to actual data on hand */ count >>= 1; /* Words, not bytes */ #ifdef FAST_FIFO_IO if ( count ) { port_write(INFIFO, in2000_dataptr, count); in2000_datalen -= (count<<1); } #else while ( count-- ) { outw(*in2000_dataptr++, INFIFO); in2000_datalen -= 2; } #endif } while((in2000_datalen > 0) && ((infcnt = (inb(INFCNT)) & 0xfe) >= 0x20) ); /* If scatter-gather, go on to next segment */ if( !in2000_datalen && ++in2000_current_segment < in2000_nsegment) { in2000_scatter++; in2000_datalen = in2000_scatter->length; in2000_dataptr = (unsigned short*)in2000_scatter->address; } if ( in2000_datalen <= 0 ) { ficmsk = 0; count = 32; /* Always says to use this much flush */ while ( count-- ) outw(0, INFIFO); outb(2, ININTR); /* Mask FIFO Interrupts when done */ } }
PRIVATE void hd_rdwt(MESSAGE* p_msg) { int drive = DRV_OF_DEV(p_msg -> DEVICE); u64 pos = p_msg -> POSITION; assert((pos & 0x1FF) == 0); /* 只允许从扇区边界开始读 */ u32 sect_nr = (u32)(pos >> SECTOR_SIZE_SHIFT); int logidx = (p_msg -> DEVICE - MINOR_hd1a) % NR_SUB_PER_DRIVE; sect_nr += p_msg -> DEVICE < MAX_PRIM ? hd_info[drive].primary[p_msg -> DEVICE].base : hd_info[drive].logical[logidx].base; HD_CMD cmd; cmd.features = 0; cmd.count = (p_msg -> CNT + SECTOR_SIZE - 1) / SECTOR_SIZE; cmd.lba_low = sect_nr & 0xFF; cmd.lba_mid = (sect_nr >> 8) & 0xFF; cmd.lba_high = (sect_nr >> 16) & 0xFF; cmd.device = MAKE_DEVICE_REG(1, drive, (sect_nr >> 24) & 0xF); cmd.command = (p_msg -> type == DEV_READ) ? ATA_READ : ATA_WRITE; hd_cmd_out(&cmd); int bytes_left = p_msg -> CNT; void* la = (void*)va2la(p_msg -> PROC_NR, p_msg -> BUF); while (bytes_left > 0) { int bytes = min(bytes_left, SECTOR_SIZE); if (p_msg -> type == DEV_READ) { /* 一次中断一个扇区 */ interrupt_wait(); port_read(REG_DATA, hdbuf, SECTOR_SIZE); memcpy(la, (void*)va2la(TASK_HD, hdbuf), bytes); } else { if (!waitfor(STATUS_DRQ, STATUS_DRQ, HD_TIMEOUT)) panic("HD writing error"); port_write(REG_DATA, la, bytes); interrupt_wait(); } la += bytes; bytes_left -= bytes; } }
/* *static write_hd_sector(u8 *hd_buff , int driver , u32 abs_sec); *@param0 缓冲区 *@param1 主设备号 *@param2 绝对扇区号 *成功返回0失败返回-1 */ static int write_hd_sector(void *hd_buff , int driver , u32 abs_sec){ HD_CMD cmd; u8 status; int result; int i; cmd.feature = 0; cmd.sec_counter = 1; cmd.lba_low = (abs_sec) & 0xFF; //因为使用的是LBA模式。所以只需要输入绝对扇区号。注意DEVICE最低四位是扇区号最高四位 cmd.lba_mid = (abs_sec >> 8) & 0xFF; cmd.lba_hig = (abs_sec >> 16) & 0xFF; cmd.device = SET_REG_DEVICE(1 , driver , (abs_sec) >> 24); //SET_REG_DEVICE(LBA , DRV , LBA_HIGHEST) cmd.command = ATA_WRITE; result = send_hd_cmd(&cmd); if(result == 0){ for(i=0; i<1000; i++){ status = in_byte(REG_STATUS); if(status != (u8)STATUS_BSY){ port_write(hd_buff , SEC_SIZE / 4 , REG_DATA); wait(SIG_READY); // printf("Write success!"); return 0; } } //end for printf("Write error!"); return -1; }else{ printf("Write Error!"); //失败返回信息。成功则不返回信息。 return -1; } } //end function
//写指令。不判忙 void lcd1602_write_com_nobusy(u8 com) { // //while(lcd1602_busy()); // port_out(); // port_write(com); // RS_CLR; // RW_CLR; // EN_CLR; // EN_CLR; // EN_SET; RS_CLR; RW_CLR; EN_CLR; asm("nop"); // asm("nop"); port_out(); port_write(com); asm("nop"); // asm("nop"); EN_SET; asm("nop"); // asm("nop"); EN_CLR; }
PUBLIC void kernelHdWrite(u32 device, u64 position, u32 count, char* buf) { // disp_int((void*) kernelHdWrite); // hd_status = hd_status & 0xf7; // disp_str("after hd_status="); // disp_int(hd_status); // disp_str("\n"); // out_byte(REG_STATUS, hd_status); // hd_status = in_byte(REG_STATUS); // int drive = DRV_OF_DEV(device); // // // if((position & 0x1FF) != 0) // { // disp_str("we only allow to R/W from a SECTOR boundary\n"); // } // // u32 sect_nr = (u32)(position >> SECTOR_SIZE_SHIFT); // int logidx = (device - MINOR_hd1a) % NR_SUB_PER_DRIVE; // sect_nr += device < MAX_PRIM ? // hd_info[drive].primary[device].base : // hd_info[drive].logical[logidx].base; // // struct hd_cmd cmd; // cmd.features = 0; // cmd.count = (count + SECTOR_SIZE - 1) / SECTOR_SIZE; // disp_str("count: "); // disp_int(cmd.count); // cmd.lba_low = sect_nr & 0xFF; // disp_str("\nlba_low: "); // disp_int(cmd.lba_low); // cmd.lba_mid = (sect_nr >> 8) & 0xFF; // disp_str("\nlba_mid: "); // disp_int(cmd.lba_mid); // cmd.lba_high = (sect_nr >> 16) & 0xFF; // disp_str("\nlba_high: "); // disp_int(cmd.lba_high); // cmd.device = MAKE_DEVICE_REG(1, drive, (sect_nr >> 24) & 0xF); // disp_str("\ndevice: "); // disp_int(cmd.device); // cmd.command = ATA_WRITE; // disp_str("\ncommand: "); // disp_int(cmd.command); // disp_str("\n"); // hd_cmd_out(&cmd); // asm("sti"); // // disp_str("cmd out"); // int bytes_left = count; // while(bytes_left > 0){ // int bytes = (SECTOR_SIZE < bytes_left) ? SECTOR_SIZE : bytes_left; // // if(!waitfor(STATUS_DRQ, STATUS_DRQ, HD_TIMEOUT)) // disp_str("hd writing error.\n"); // // port_write(REG_DATA, buf, bytes); // hdIdentifyBlockEip = p_proc_running - proc_table; // disp_int(hdIdentifyBlockEip); // disp_str("before block!\n"); // asm("cli"); // kernelBlock(); // asm("sti"); // disp_str("after block!\n"); // bytes_left -= bytes; // buf += bytes; // } int drive = DRV_OF_DEV(device); u64 pos = position; u32 sect_nr = (u32)(pos >> SECTOR_SIZE_SHIFT); int logidx = (device - MINOR_hd1a) % NR_SUB_PER_DRIVE; sect_nr += device < MAX_PRIM ? hd_info[drive].primary[device].base : hd_info[drive].logical[logidx].base; struct hd_cmd cmd; cmd.features = 0; cmd.count = (count + SECTOR_SIZE - 1) / SECTOR_SIZE; cmd.lba_low = sect_nr & 0xFF; cmd.lba_mid = (sect_nr >> 8) & 0xFF; cmd.lba_high = (sect_nr >> 16) & 0xFF; cmd.device = MAKE_DEVICE_REG(1, drive, (sect_nr >> 24) & 0xF); cmd.command = ATA_WRITE; hd_cmd_out(&cmd); int bytes_left = count; while(bytes_left > 0){ int bytes = (SECTOR_SIZE < bytes_left) ? SECTOR_SIZE : bytes_left; if(!waitfor(STATUS_DRQ, STATUS_DRQ, HD_TIMEOUT)) disp_str("hd writing error.\n"); port_write(REG_DATA, buf, bytes); hdIdentifyBlockEip = p_proc_running - proc_table; kernelBlock(); bytes_left -= bytes; buf += bytes; } }
int main(int argc, char** argv) { int i, ret; struct sockaddr_in cliaddr; // used by accept() int clilen; int conn_fd; // fd for a new connection with client int file_fd; // fd for file that we open for reading char buf[512]; int buf_len; // Parse args. if (argc != 2) { fprintf(stderr, "usage: %s [port]\n", argv[0]); exit(1); } // Initialize server init_server((unsigned short) atoi(argv[1])); // Get file descripter table size and initize request table maxfd = getdtablesize(); requestP = (request*) malloc(sizeof(request) * maxfd); if (requestP == NULL) { ERR_EXIT("out of memory allocating all requests"); } for (i = 0; i < maxfd; i++) { init_request(&requestP[i]); } requestP[svr.listen_fd].conn_fd = svr.listen_fd; strcpy(requestP[svr.listen_fd].host, svr.hostname); // Loop for handling connections fprintf(stderr, "\nstarting on %.80s, port %d, fd %d, maxconn %d...\n", svr.hostname, svr.port, svr.listen_fd, maxfd); // my own variable fd_set rset, allset; FD_ZERO(&allset); FD_SET(svr.listen_fd, &allset); int monitor_fd = svr.listen_fd; int socket_fd; Porter* porter = port_init(); int id, amount, price; while (1) { // TODO: Add IO multiplexing rset = allset; select(monitor_fd + 1, &rset, NULL, NULL, NULL); // new client connection if (FD_ISSET(svr.listen_fd, &rset)) { clilen = sizeof(cliaddr); conn_fd = accept(svr.listen_fd, (struct sockaddr*)&cliaddr, (socklen_t*)&clilen); if (conn_fd < 0) { if (errno == EINTR || errno == EAGAIN) continue; // try again if (errno == ENFILE) { (void) fprintf(stderr, "out of file descriptor table ... (maxconn %d)\n", maxfd); continue; } ERR_EXIT("accept"); } requestP[conn_fd].conn_fd = conn_fd; strcpy(requestP[conn_fd].host, inet_ntoa(cliaddr.sin_addr)); fprintf(stderr, "getting a new request... fd %d from %s\n", conn_fd, requestP[conn_fd].host); // add new descriptor to set FD_SET(conn_fd, &allset); // extend the select() range if (conn_fd > monitor_fd) { monitor_fd = conn_fd; } } // check all client if data is ready for (i = svr.listen_fd+1; i <= monitor_fd; ++i) { socket_fd = requestP[i].conn_fd; if (FD_ISSET(socket_fd, &rset)) { ret = handle_read(&requestP[i]); // parse data from client to requestP[conn_fd].buf if (ret < 0) { fprintf(stderr, "bad request from %s\n", requestP[i].host); continue; } #ifdef READ_SERVER id = atoi(requestP[i].buf); // sprintf(buf, "%s : %s\n",accept_read_header,requestP[i].buf); if (id <= 0 || id > 20) { sprintf(buf, "Operation failed.\n"); } else if (port_read(porter, id, &amount, &price) == -1) { sprintf(buf, "This item is locked.\n"); } else { sprintf(buf, "item%d $%d remain: %d\n", id, price, amount); } write(requestP[i].conn_fd, buf, strlen(buf)); #else if (requestP[i].wait_for_write != 1) { // wait_for_write is 1 means this socket is bidding to an item for changing id = atoi(requestP[i].buf); if (id <= 0 || id > 20) { sprintf(buf, "Operation failed.\n"); write(requestP[i].conn_fd, buf, strlen(buf)); } else if (port_write(porter, id) != 1) { sprintf(buf, "This item is locked.\n"); write(requestP[i].conn_fd, buf, strlen(buf)); } else { // This item is not locked by other process int j; for (j = svr.listen_fd+1; j <= monitor_fd; ++j) { if (j != i && requestP[j].wait_for_write == 1 && requestP[j].item == id) { sprintf(buf, "This item is locked.\n"); write(requestP[i].conn_fd, buf, strlen(buf)); break; } } if (j > monitor_fd) { // This item is not locked by other file descriptor sprintf(buf, "This item is modifiable.\n"); write(requestP[i].conn_fd, buf, strlen(buf)); requestP[i].wait_for_write = 1; requestP[i].item = id; continue; } } } else { // This socket is waiting for command such as buy, sell, price if (port_operate(porter, requestP[i].buf, buf, requestP[i].item) == 0) write(requestP[i].conn_fd, buf, strlen(buf)); port_unlock(porter, requestP[i].item); } #endif close(requestP[i].conn_fd); // clear socket descriptor from the set FD_CLR(socket_fd, &allset); free_request(&requestP[i]); } } } free(requestP); port_close(porter); return 0; }
alwaysinline void sSMP::op_buswrite(uint16 addr, uint8 data) { if((addr & 0xfff0) == 0x00f0) { //addr >= 0x00f0 && addr >= 0x00ff if(status.mmio_disabled == true) return; switch(addr) { case 0xf0: { //TEST if(regs.p.p) break; //writes only valid when P flag is clear //multiplier table may not be 100% accurate, some settings crash //the processor due to S-SMP <> S-DSP bus access misalignment //static uint8 clock_speed_tbl[16] = //{ 3, 5, 9, 17, 4, 6, 10, 18, 6, 8, 12, 20, 10, 12, 16, 24 }; //status.clock_speed = 24 * clock_speed_tbl[data >> 4] / 3; status.mmio_disabled = !!(data & 0x04); status.ram_writable = !!(data & 0x02); //if((data >> 4) != 0) { //dprintf("* S-SMP critical warning: $00f0 (TEST) clock speed control modified!"); //dprintf("* S-SMP may crash on hardware as a result!"); //} } break; case 0xf1: { //CONTROL status.iplrom_enabled = !!(data & 0x80); if(data & 0x30) { //one-time clearing of APU port read registers, //emulated by simulating CPU writes of 0x00 scheduler.sync_smpcpu(); if(data & 0x20) { cpu.port_write(2, 0x00); cpu.port_write(3, 0x00); } if(data & 0x10) { cpu.port_write(0, 0x00); cpu.port_write(1, 0x00); } } //0->1 transistion resets timers if(t2.enabled == false && (data & 0x04)) { t2.stage2_ticks = 0; t2.stage3_ticks = 0; } t2.enabled = !!(data & 0x04); if(t1.enabled == false && (data & 0x02)) { t1.stage2_ticks = 0; t1.stage3_ticks = 0; } t1.enabled = !!(data & 0x02); if(t0.enabled == false && (data & 0x01)) { t0.stage2_ticks = 0; t0.stage3_ticks = 0; } t0.enabled = !!(data & 0x01); } break; case 0xf2: { //DSPADDR status.dsp_addr = data; } break; case 0xf3: { //DSPDATA //0x80-0xff is a read-only mirror of 0x00-0x7f if(!(status.dsp_addr & 0x80)) { dsp.write(status.dsp_addr & 0x7f, data); } } break; case 0xf4: //CPUIO0 case 0xf5: //CPUIO1 case 0xf6: //CPUIO2 case 0xf7: { //CPUIO3 scheduler.sync_smpcpu(); port_write(addr & 3, data); } break; case 0xf8: { //??? status.smp_f8 = data; } break; case 0xf9: { //??? status.smp_f9 = data; } break; case 0xfa: { //T0TARGET t0.target = data; } break; case 0xfb: { //T1TARGET t1.target = data; } break; case 0xfc: { //T2TARGET t2.target = data; } break; case 0xfd: //T0OUT case 0xfe: //T1OUT case 0xff: { //T2OUT -- read-only registers } break; } } //all writes, even to MMIO registers, appear on bus if(status.ram_writable == true) { ram_write(addr, data); } }
static inline void OLED_DSPLoff(void) { // P5OUT |= OLED_on; port_write(OLED_PORT5, OLED_on, PIN_HI); }
static inline void OLED_SelectDSPL(void) { // P5OUT &= ~OLED_CS2; port_write(OLED_PORT5, OLED_CS2, PIN_LO); }
void do_hd_request(void) { int i, r = 0; unsigned int start_sector, dev, partition; unsigned int start_sec, head, cyl; unsigned int nsect; CHECK_REQUEST; partition = MINOR(CURRENT_REQ->dev); /* get partition */ start_sector = CURRENT_REQ->start_sector; nsect = CURRENT_REQ->nr_sectors; /* need to check if nsect is exceed the partition limit or not */ if (partition >= 5 * NR_HD || nsect > hd[partition].nr_sects) { end_request(0); goto repeat; /* repeat defined in blk.h */ } start_sector += hd[partition].start_sect; dev = partition / 5; /* get cyl, head, start_sec number according start_sector */ /* div result: EAX = Quotient, EDX = Remainder */ /* * start_sector / sect nrs per track = total track number(start_sector) * ... remainder sector number(start_sec) */ __asm__("divl %4" :"=a" (start_sector), "=d" (start_sec) :"0" (start_sector), "1" (0), "r" (hd_info[dev].sect)); /* totoal track number / total head nrs = cylinder number(cyl) * ... head nr(head) */ __asm__("divl %4" :"=a" (cyl), "=d" (head) :"0" (start_sector), "1" (0), "r" (hd_info[dev].head)); start_sec++; if (reset) { reset = 0; recalibrate = 1; reset_hd(CURRENT_DEV); return; } if (recalibrate) { recalibrate = 0; hd_out(dev, hd_info[CURRENT_DEV].sect, 0, 0, 0, WIN_RESTORE, recal_intr); return; } if (CURRENT_REQ->cmd == WRITE) { hd_out(dev, nsect, start_sec, head, cyl, WIN_WRITE, write_intr); /* wait DRQ_STAT signal */ for(i = 0; i < 3000 && !(r = inb_p(HD_STATUS) & DRQ_STAT); i++) /* nothing */ ; if (!r) { bad_rw_intr(); goto repeat; } /* write 512 byte (1 sector) to HD */ port_write(HD_DATA, CURRENT_REQ->buffer, 256); } else if (CURRENT_REQ->cmd == READ) { hd_out(dev, nsect, start_sec, head, cyl, WIN_READ, read_intr); } else { panic("unknown hd-command"); } }
void OLED_init(void) { port_attr_t port_attr; PIN_CLEAR(port_attr.ie, 0x01); PIN_SET(port_attr.dir, 0x01, PIN_HI); PIN_CLEAR(port_attr.sel, 0x01); port_set_attr(4, 0x01, &port_attr); port_write(4, 0x01, PIN_HI); /* P5OUT |= OLED_RST | OLED_D_C | OLED_on | OLED_CS2 ; P5DIR |= OLED_RST | OLED_D_C | OLED_on | OLED_CS2 ; P5SEL &= ~(OLED_RST | OLED_D_C | OLED_on | OLED_CS2); */ PIN_CLEAR(port5_attr.ie, OLED_D_C); PIN_CLEAR(port5_attr.ie, OLED_CS2); PIN_CLEAR(port5_attr.ie, OLED_RST); PIN_CLEAR(port5_attr.ie, OLED_on); PIN_SET(port5_attr.dir, OLED_D_C, PIN_HI); PIN_SET(port5_attr.dir, OLED_CS2, PIN_HI); PIN_SET(port5_attr.dir, OLED_RST, PIN_HI); PIN_SET(port5_attr.dir, OLED_on, PIN_HI); PIN_CLEAR(port5_attr.sel, OLED_D_C); PIN_CLEAR(port5_attr.sel, OLED_CS2); PIN_CLEAR(port5_attr.sel, OLED_RST); PIN_CLEAR(port5_attr.sel, OLED_on); port_set_attr(OLED_PORT5, OLED_D_C | OLED_CS2 | OLED_RST | OLED_on, &port5_attr); port_write(OLED_PORT5, OLED_D_C | OLED_CS2 | OLED_RST | OLED_on, PIN_HI); PIN_CLEAR(port6_attr.ie, OLED_DC_on); PIN_SET(port6_attr.dir, OLED_DC_on, PIN_HI); PIN_CLEAR(port6_attr.sel, OLED_DC_on); port_set_attr(OLED_PORT6, OLED_DC_on, &port6_attr); OLED_initSPI(); // P5SEL=MOSI|UCLK; /* P6OUT |= OLED_DC_on; P6DIR |= OLED_DC_on; P6SEL &= ~OLED_DC_on; */ port_write(OLED_PORT6, OLED_DC_on, PIN_HI); OLED_DSPLon(); // Switch OLED display power supply on OLED_reset(); // Reset it OLED_DCon(); // Switch DC/DC converter on OLED_pause(10000); // Wait for it to start OLED_SendComm(0x01A0); // Set initial brightness OLED_SendComm(0x1001); // Enable display OLED_SendComm(0x1101); // Select direction (horizontal mirroring) OLED_SendComm(0x123F); // Selec number of lines to scan (64) OLED_SendComm(0x1503); // Select display mode (16 gray) and RAM pointer increment mode OLED_SendComm(0x160B); // Set up dimmer control // SendComm(0x1702); // SendComm(0x1A00); OLED_SendComm(0x1C81); // Setup period 2 OLED_SendComm(0x1D81); // Setup period 3 OLED_SendComm(0x1E89); // Setup period 4 OLED_cls(); // Clear screen }
void main(){ e_ctimer_set(E_CTIMER_0, E_CTIMER_CLK, E_CTIMER_MAX); e_ctimer_start(E_CTIMER_0, E_CTIMER_CLK); init(); // wait for the go (which means actors are connected) while(Mailbox.pGo[me.corenum] == 0); timerValue = e_ctimer_get(E_CTIMER_0); Mailbox.pTimer0[me.corenum] = E_CTIMER_MAX - timerValue; e_ctimer_stop(E_CTIMER_0); // Timer functions 1 e_ctimer_set(E_CTIMER_1, E_CTIMER_CLK, E_CTIMER_MAX); e_ctimer_start(E_CTIMER_1, E_CTIMER_CLK); int j = 0; int signed_counter = 0; // Run until there is no input left while(j < IN_BUFFER_SIZE) { //action read_signed if(clip.count < 0){ //clip.sflag = port_read(&SIGNED); clip.sflag = Mailbox.pSignedBuffer[signed_counter++]; clip.count = 63; } // end of action read_signed else { // action limit int i = port_read(&I); if(i > 255){ #if 0 port_write(&O, 255); j++; #endif #if 1 Mailbox.pOutputBuffer[j] = 255; j++; #endif // j++; } else if(clip.sflag == 0 && i < 0){ #if 0 port_write(&O, 0); j++; #endif #if 1 Mailbox.pOutputBuffer[j] = 0; j++; #endif //j++; } else if(i < -255){ #if 0 port_write(&O, -255); j++; #endif #if 1 Mailbox.pOutputBuffer[j] = -255; j++; #endif //j++; } else{ #if 0 port_write(&O, i); j++; #endif #if 1 Mailbox.pOutputBuffer[j] = i; j++; #endif //j++; } clip.count = clip.count - 1; } } timerValue = e_ctimer_get(E_CTIMER_1); Mailbox.pTimer1[me.corenum] = E_CTIMER_MAX - timerValue; #if 1 *Mailbox.pOutputReady = 1; #endif e_ctimer_stop(E_CTIMER_1); }
void SMP::op_buswrite(uint16 addr, uint8 data) { switch(addr) { case 0xf0: //TEST if(regs.p.p) break; //writes only valid when P flag is clear status.clock_speed = (data >> 6) & 3; status.timer_speed = (data >> 4) & 3; status.timers_enable = data & 0x08; status.ram_disable = data & 0x04; status.ram_writable = data & 0x02; status.timers_disable = data & 0x01; status.timer_step = (1 << status.clock_speed) + (2 << status.timer_speed); timer0.synchronize_stage1(); timer1.synchronize_stage1(); timer2.synchronize_stage1(); break; case 0xf1: //CONTROL status.iplrom_enable = data & 0x80; if(data & 0x30) { //one-time clearing of APU port read registers, //emulated by simulating CPU writes of 0x00 synchronize_cpu_force(); if(data & 0x20) { cpu.port_write(2, 0x00); cpu.port_write(3, 0x00); } if(data & 0x10) { cpu.port_write(0, 0x00); cpu.port_write(1, 0x00); } } //0->1 transistion resets timers if(timer2.enable == false && (data & 0x04)) { timer2.stage2_ticks = 0; timer2.stage3_ticks = 0; } timer2.enable = data & 0x04; if(timer1.enable == false && (data & 0x02)) { timer1.stage2_ticks = 0; timer1.stage3_ticks = 0; } timer1.enable = data & 0x02; if(timer0.enable == false && (data & 0x01)) { timer0.stage2_ticks = 0; timer0.stage3_ticks = 0; } timer0.enable = data & 0x01; break; case 0xf2: //DSPADDR status.dsp_addr = data; break; case 0xf3: //DSPDATA if(status.dsp_addr & 0x80) break; //0x80-0xff are read-only mirrors of 0x00-0x7f dsp.write(status.dsp_addr & 0x7f, data); break; case 0xf4: //CPUIO0 case 0xf5: //CPUIO1 case 0xf6: //CPUIO2 case 0xf7: //CPUIO3 synchronize_cpu_force(); port_write(addr, data); break; case 0xf8: //RAM0 status.ram00f8 = data; break; case 0xf9: //RAM1 status.ram00f9 = data; break; case 0xfa: //T0TARGET timer0.target = data; break; case 0xfb: //T1TARGET timer1.target = data; break; case 0xfc: //T2TARGET timer2.target = data; break; case 0xfd: //T0OUT case 0xfe: //T1OUT case 0xff: //T2OUT -- read-only registers break; } ram_write(addr, data); //all writes, even to MMIO registers, appear on bus }
void port_test() { char testdata[5]; thread_id t; int res; int32 dummy; int32 dummy2; strcpy(testdata, "abcd"); dprintf("porttest: port_create()\n"); test_p1 = port_create(1, "test port #1"); test_p2 = port_create(10, "test port #2"); test_p3 = port_create(1024, "test port #3"); test_p4 = port_create(1024, "test port #4"); dprintf("porttest: port_find()\n"); dprintf("'test port #1' has id %d (should be %d)\n", port_find("test port #1"), test_p1); dprintf("porttest: port_write() on 1, 2 and 3\n"); port_write(test_p1, 1, &testdata, sizeof(testdata)); port_write(test_p2, 666, &testdata, sizeof(testdata)); port_write(test_p3, 999, &testdata, sizeof(testdata)); dprintf("porttest: port_count(test_p1) = %d\n", port_count(test_p1)); dprintf("porttest: port_write() on 1 with timeout of 1 sec (blocks 1 sec)\n"); port_write_etc(test_p1, 1, &testdata, sizeof(testdata), PORT_FLAG_TIMEOUT, 1000000); dprintf("porttest: port_write() on 2 with timeout of 1 sec (wont block)\n"); res = port_write_etc(test_p2, 777, &testdata, sizeof(testdata), PORT_FLAG_TIMEOUT, 1000000); dprintf("porttest: res=%d, %s\n", res, res == 0 ? "ok" : "BAD"); dprintf("porttest: port_read() on empty port 4 with timeout of 1 sec (blocks 1 sec)\n"); res = port_read_etc(test_p4, &dummy, &dummy2, sizeof(dummy2), PORT_FLAG_TIMEOUT, 1000000); dprintf("porttest: res=%d, %s\n", res, res == ERR_PORT_TIMED_OUT ? "ok" : "BAD"); dprintf("porttest: spawning thread for port 1\n"); t = thread_create_kernel_thread("port_test", port_test_thread_func, NULL); // resume thread thread_resume_thread(t); dprintf("porttest: write\n"); port_write(test_p1, 1, &testdata, sizeof(testdata)); // now we can write more (no blocking) dprintf("porttest: write #2\n"); port_write(test_p1, 2, &testdata, sizeof(testdata)); dprintf("porttest: write #3\n"); port_write(test_p1, 3, &testdata, sizeof(testdata)); dprintf("porttest: waiting on spawned thread\n"); thread_wait_on_thread(t, NULL); dprintf("porttest: close p1\n"); port_close(test_p2); dprintf("porttest: attempt write p1 after close\n"); res = port_write(test_p2, 4, &testdata, sizeof(testdata)); dprintf("porttest: port_write ret %d\n", res); dprintf("porttest: testing delete p2\n"); port_delete(test_p2); dprintf("porttest: end test main thread\n"); }
static inline void OLED_DeselectDSPL(void) { // P5OUT |= OLED_CS2; port_write(OLED_PORT5, OLED_CS2, PIN_HI); }
void main() { // Configure the timers e_ctimer_set(E_CTIMER_0, E_CTIMER_MAX); // Start the timer (countdown from 0xFFFFFFFF) e_ctimer_start(E_CTIMER_0, E_CTIMER_CLK); int x0, x1, x2, x3, x5; int i = 0; #if 0 int j = 0; #endif // Initialize data structures - mainly target pointers init(); // Wait for the connect actors signal while(*Mailbox.pConnectActors == 0); connect_actors(); // Reset the connect actors signal to inform the host that actors are connected *Mailbox.pConnectActors = 0; // Wait for the trigger from the host while(Mailbox.pGo[me.corenum] == 0); timerValue = e_ctimer_get(E_CTIMER_0); Mailbox.pTimer0[me.corenum] = E_CTIMER_MAX - timerValue; e_ctimer_stop(E_CTIMER_0); e_ctimer_set(E_CTIMER_1, E_CTIMER_MAX); e_ctimer_start(E_CTIMER_1, E_CTIMER_CLK); while(i < IN_BUFFER_SIZE) { // Read x0, x1, x2, x3 x0 = Mailbox.pInBuffer[i]; i++; x1 = Mailbox.pInBuffer[i]; i++; x2 = Mailbox.pInBuffer[i]; i++; x3 = Mailbox.pInBuffer[i]; i++; // Write x0 and read an input and write it directly to the output port_write(&Y, x0); port_write(&Y, Mailbox.pInBuffer[i]); i++; #if 0 Mailbox.pOutputBuffer[j] = x0; j++; Mailbox.pOutputBuffer[j] = Mailbox.pInBuffer[i - 1]; j++; #endif // Read x5 x5 = Mailbox.pInBuffer[i]; i++; // Write x2 and read an input and write it directly to the output port_write(&Y, x2); port_write(&Y, Mailbox.pInBuffer[i]); i++; #if 0 Mailbox.pOutputBuffer[j] = x2; j++; Mailbox.pOutputBuffer[j] = Mailbox.pInBuffer[i - 1]; j++; #endif // write x1 and read an input and write it directly to the output port_write(&Y, x1); port_write(&Y, Mailbox.pInBuffer[i]); i++; #if 0 Mailbox.pOutputBuffer[j] = x1; j++; Mailbox.pOutputBuffer[j] = Mailbox.pInBuffer[i - 1]; j++; #endif // Write x5 and x3 port_write(&Y, x5); port_write(&Y, x3); #if 0 Mailbox.pOutputBuffer[j] = x5; j++; Mailbox.pOutputBuffer[j] = x3; j++; #endif } // Get timer value, find the elapsed time and stop timerValue = e_ctimer_get(E_CTIMER_1); Mailbox.pTimer1[me.corenum] = E_CTIMER_MAX - timerValue; e_ctimer_stop(E_CTIMER_1); }
static inline void OLED_DSPLon(void) { // P5OUT &= ~OLED_on; port_write(OLED_PORT5, OLED_on, PIN_LO); }
static inline void OLED_Data(void) { // P5OUT |= OLED_D_C; port_write(OLED_PORT5, OLED_D_C, PIN_HI); }
void port_poke_byte(uint16_t address, uint8_t value) { port_write(address, value, true); }
void main(){ // Configure the timers e_ctimer_set(E_CTIMER_0, E_CTIMER_CLK, E_CTIMER_MAX); // Start the timer (countdown from 0xFFFFFFFF) e_ctimer_start(E_CTIMER_0, E_CTIMER_CLK); init(); int j = 0; int consumed_elements = 0; // wait for the go (which means actors are connected) while(Mailbox.pGo[me.corenum] == 0); timerValue = e_ctimer_get(E_CTIMER_0); Mailbox.pTimer0[me.corenum] = E_CTIMER_MAX - timerValue; e_ctimer_stop(E_CTIMER_0); e_ctimer_set(E_CTIMER_1, E_CTIMER_CLK, E_CTIMER_MAX); e_ctimer_start(E_CTIMER_1, E_CTIMER_CLK); while(j < IN_BUFFER_SIZE) { // action #1 if(transpose.rcount < 64){ int row = (transpose.rcount >> 3); int quad = (transpose.rcount >> 2) & 1; int i; if(quad == 0){ for(i = 0; i < 4; i++){ if(input_available(&X)){ switch(consumed_elements){ case 0: transpose.mem[transpose.select][row][0] = port_read(&X); break; case 1: transpose.mem[transpose.select][row][7] = port_read(&X); break; case 2: transpose.mem[transpose.select][row][3] = port_read(&X); break; case 3: transpose.mem[transpose.select][row][4] = port_read(&X); transpose.rcount = transpose.rcount + 4; break; default: break; } // if we consumed 4 elements, get out of for loop if(consumed_elements == 3) i = 4; consumed_elements = (consumed_elements + 1) % 4; } } } else{ for(i = 0; i < 4; i++){ if(input_available(&X)){ switch(consumed_elements){ case 0: transpose.mem[transpose.select][row][1] = port_read(&X); break; case 1: transpose.mem[transpose.select][row][6] = port_read(&X); break; case 2: transpose.mem[transpose.select][row][2] = port_read(&X); break; case 3: transpose.mem[transpose.select][row][5] = port_read(&X); transpose.rcount = transpose.rcount + 4; break; default: break; } // if we consumed 4 elements, get out of for loop if(consumed_elements == 3) i = 4; consumed_elements = (consumed_elements + 1) % 4; } } } } // end of action #1 // action #2 if(transpose.ccount > 0){ int a, b; int col = (64 - transpose.ccount) >> 3; int pair = ((64 - transpose.ccount) >> 1) & 3; int k = transpose.select ^ 1; if(pair == 0){ a = 0; b = 4; } else if(pair == 1){ a = 2; b = 6; } else if(pair == 2){ a = 1; b = 7; } else{ a = 5; b = 3; } #if 1 port_write(&Y, transpose.mem[k][a][col]); j++; port_write(&Y, transpose.mem[k][b][col]); j++; #endif #if 0 // DEBUG Mailbox.pOutputBuffer[j] = transpose.mem[k][a][col]; j++; Mailbox.pOutputBuffer[j] = transpose.mem[k][b][col]; j++; #endif transpose.ccount = transpose.ccount - 2; }
static inline void OLED_Command(void) { // P5OUT &= ~OLED_D_C; port_write(OLED_PORT5, OLED_D_C, PIN_LO); }