?? skyeye_mach_ps7500.c
字號:
/* skyeye_mach_ps7500.c - define machine ps7500 for skyeye Copyright (C) 2003 Skyeye Develop Group for help please send mail to <skyeye-developer@lists.gro.clinux.org> This program 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 Foundation; either version 2 of the License, or (at your option) any later version. This program 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. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//* * 3/2005 init this file. * add machine ps7500's function. Most taken from original armio.c. * include: ps7500_mach_init, ps7500_io_do_cycle * ps7500_io_read_word, ps7500_io_write_word * Most taken from skyeye_mach_ep7312.c * */#include "armdefs.h"#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include "ps7500.h"/* 2007-01-18 added by Anthony Lee : for new uart device frame */#include "skyeye_uart.h"extern int skyeye_net_maxfd;extern int skyeye_net_on;#define TC_DIVISOR (32) /* Set your BogoMips here :) */#define FLYBACK_DIVISOR (1000000)#define SOMETIMES_DIVISOR (100)#define NET_ADDR_START 0x03010C00#define NET_ADDR_END (NET_ADDR_START + 0x00000400)#define IOMD_ADDR_START 0x03200000#define IOMD_ADDR_END (IOMD_ADDR_START + 0x00001000)#define VIDEO_ADDR 0x03400000//zzc:2005-1-1#ifdef __CYGWIN__#include <sys/time.h>#endif#define PC (state->Reg[15])#define DEBUG 1#if DEBUG#define DBG_PRINT(a...) fprintf(stderr,##a)#else#define DBG_PRINT(a...)#endif/*Internal IO Register*/typedef struct ps7500_io { ARMword flyback; ARMword prescale; ARMword sometimes; ARMbyte irq[5], irqmask[5]; ARMbyte fiq[1], fiqmask[1]; ARMbyte iocr_write; ARMbyte iocr_read; ARMword tcd_reload[2]; /* Timer load register */ ARMword tcd[2]; /* Timer data */ int tc_prescale; /* Timer prescale */ ARMword vidstart, vidend, vidinit; ARMbyte vidcr; ARMword lcd_is_enable; ARMword lcd_addr_begin; ARMword lcd_addr_end; ARMword ts_int; ARMword ts_is_enable; ARMword ts_addr_begin; ARMbyte net_int[5]; ARMword net_flag; ARMbyte kb_stat; ARMbyte kb_data; ARMbyte kb_queued[4096]; ARMword kb_count; ARMbyte kb_delay; ARMbyte lcd_started; } ps7500_io_t;static ps7500_io_t ps7500_io;#define io ps7500_io// Macros for setting/clearing interrupt bits// I used an array since there were more than 32 interrupt sources// and so it didn't fit in a ARMword. Thus, the network interrupt// source must be less than 32.#define SET_BIT(v, x) (v)[(x) / 8] |= (1 << ((x) % 8))#define CLR_BIT(v, x) (v)[(x) / 8] &= ~(1 << ((x) % 8))#define SET_IRQ(x) SET_BIT(io.irq, x); ps7500_update_int(state)#define CLR_IRQ(x) CLR_BIT(io.irq, x); ps7500_update_int(state)#define SET_IRQMASK(x) SET_BIT(io.irqmask); ps7500_update_int(state)#define CLR_IRQMASK(x) CLR_BIT(io.irqmask); ps7500_update_int(state)#define SET_FIQ(x) SET_BIT(io.fiq, x); ps7500_update_int(state)#define CLR_FIQ(x) CLR_BIT(io.fiq, x); ps7500_update_int(state)#define SET_FIQMASK(x) SET_BIT(io.fiqmask, x); ps7500_update_int(state)#define CLR_FIQMASK(x) CLR_BIT(io.fiqmask, x); ps7500_update_int(state)// Indexes into IRQ array. This must match IRQ numbers in ps7500.h#define IRQA 0 #define IRQB 1#define IRQDMA 2#define IRQC 3#define IRQD 4#define FIQ 0extern ARMul_State * state;ARMbyte ps7500_getcode(ARMbyte);static void ps7500_update_int(ARMul_State *state){ int i; //if (io.irq[IRQB] & io.net_int[IRQB]) { // printf("Network interrupt set\n"); // for (i=0; i < 5; i++) { // printf("IRQ[%d] %02x IRQMASK[%d] %02x\n", // i, io.irq[i], i, io.irqmask[i]); // } //} state->NfiqSig = (io.fiq[FIQ] & io.fiqmask[FIQ]) ? LOW : HIGH; state->NirqSig = ((io.irq[IRQA] & io.irqmask[IRQA]) || (io.irq[IRQB] & io.irqmask[IRQB]) || (io.irq[IRQC] & io.irqmask[IRQC]) || (io.irq[IRQD] & io.irqmask[IRQD]) || (io.irq[IRQDMA] & io.irqmask[IRQDMA])) ? LOW : HIGH; }/* * added some functions for device simulation by ksh * */static voidps7500_set_intr (u32 interrupt){ //io.irq |= (1 << interrupt); SET_IRQ(interrupt);}static intps7500_pending_intr (u32 interrupt){ return io.irq[interrupt];}static voidps7500_update_intr (void *mach){ struct machine_config *mc = (struct machine_config *) mach; ARMul_State *state = (ARMul_State *) mc->state; state->NfiqSig = (io.fiq[FIQ] & io.fiqmask[FIQ]) ? LOW : HIGH; state->NirqSig = ((io.irq[IRQA] & io.irqmask[IRQA]) || (io.irq[IRQB] & io.irqmask[IRQB]) || (io.irq[IRQC] & io.irqmask[IRQC]) || (io.irq[IRQD] & io.irqmask[IRQD]) || (io.irq[IRQDMA] & io.irqmask[IRQDMA])) ? LOW : HIGH;}static void ps7500_io_reset(ARMul_State *state){ int i; for (i=0; i < 4; i++) io.irqmask[i] = io.irq[i] = 0; io.fiqmask[FIQ] = io.fiq[FIQ] = 0; io.irq[IRQA] = 0x80; // SWI bit always true io.tcd[0] = io.tcd[1] = 0xffff; io.tcd_reload[0] = io.tcd_reload[1] = 0xffff; io.tc_prescale = TC_DIVISOR; io.lcd_addr_begin =0x10000000; io.lcd_addr_end =0x10004000; SET_BIT(io.net_int, IRQ_INT5); // Network interrupt bit printf("netint %02x\n", io.net_int[IRQB]); io.sometimes = SOMETIMES_DIVISOR; io.lcd_started = 0; //state->Exception = TRUE;}ps7500_kb_queue(ARMul_State *state, ARMbyte c){ io.kb_queued[io.kb_count++] = c; if ((io.kb_stat & (KB_TXB | KB_RXF)) == 0) ps7500_kb_next(state);}ps7500_kb_next(ARMul_State *state){ int i; int p; if (io.kb_count) { io.kb_data = io.kb_queued[0]; p = 0; for (i=0; i < 8; i++) if (io.kb_data & (1 << i)) p++; if (p % 2) io.kb_stat &= ~KB_RXP; else io.kb_stat |= KB_RXP; io.kb_stat |= KB_RXF; SET_IRQ(IRQ_KEYBOARDRX); io.kb_count--; if (io.kb_count) for (i=0; i < io.kb_count; i++) io.kb_queued[i] = io.kb_queued[i+1]; }}void ps7500_uart_cycle(ARMul_State *state){ /* 2007-01-18 modified by Anthony Lee : for new uart device frame */ struct timeval tv; unsigned char buf, c; tv.tv_sec = 0; tv.tv_usec = 0; if(skyeye_uart_read(-1, &buf, 1, &tv, NULL) > 0) { printf("read something %02x\n", buf); c = ps7500_getcode(buf); ps7500_kb_queue(state, c); ps7500_kb_queue(state, 0xf0); ps7500_kb_queue(state, c); }}void ps7500_io_do_cycle(ARMul_State *state){ int t; // Timers io.tc_prescale--; if (io.tc_prescale < 0) { io.tc_prescale = TC_DIVISOR; // 64 Mhz -> 2 Mhz for (t=0; t < 2; t++) { if (io.tcd[t] == 0) { io.tcd[t] = io.tcd_reload[t]; //DBG_PRINT("Timer %d interrupt\n", t); SET_IRQ(t ? IRQ_TIMER1 : IRQ_TIMER0); } else { io.tcd[t]--; } } } io.iocr_write |= 0x80; // Flyback bit always true // VSYNC pulse interrupt if (io.flyback == 0) { io.flyback = FLYBACK_DIVISOR; //DBG_PRINT("Flyback interrupt\n"); SET_IRQ(IRQ_VSYNCPULSE); } else { io.flyback--; } // Make sure SWI interrupt bit stays set if ((io.irq[IRQA] & 0x80) == 0) { io.irq[IRQA] |= 0x80; ps7500_update_int(state); } // Keyboard if (io.kb_delay != 0) { io.kb_delay--; if (io.kb_delay == 0) { io.kb_stat &= ~KB_TXB; io.kb_stat |= KB_TXE; SET_IRQ(IRQ_KEYBOARDTX); ps7500_kb_next(state); } } if (io.sometimes == 0) { ps7500_uart_cycle(state); io.sometimes = SOMETIMES_DIVISOR; } else { io.sometimes--; } }ARMword ps7500_io_read_byte(ARMul_State *state, ARMword addr){ ARMword data = 0; ARMword offset; if ((addr >= IOMD_ADDR_START) && (addr < IOMD_ADDR_END)) { offset = addr - IOMD_ADDR_START; switch (offset) { case IOMD_CONTROL: data = io.iocr_write | io.iocr_read; //DBG_PRINT("@0x%08x: IOCR(0x%08x) -> %02x\n", // PC - 8, addr, data); break; case IOMD_IRQMASKA: data = io.irqmask[IRQA]; //DBG_PRINT("@0x%08x: IRQMASKA(0x%08x) -> %02x\n", // PC - 8, addr, data); break; case IOMD_IRQSTATA: data = io.irq[IRQA]; //DBG_PRINT("@0x%08x: IRQSTATA(0x%08x) -> %02x\n", // PC - 8, addr, data); break; case IOMD_IRQREQA: data = io.irq[IRQA] & io.irqmask[IRQA]; //DBG_PRINT("@0x%08x: IRQREQA(0x%08x) -> %02x\n", // PC - 8, addr, data); break; case IOMD_IRQMASKB: data = io.irqmask[IRQB]; //DBG_PRINT("@0x%08x: IRQMASKB(0x%08x) -> %02x\n", // PC - 8, addr, data); break; case IOMD_IRQSTATB: data = io.irq[IRQB]; //DBG_PRINT("@0x%08x: IRQSTATB(0x%08x) -> %02x\n", // PC - 8, addr, data); break; case IOMD_IRQREQB: data = io.irq[IRQB] & io.irqmask[IRQB]; //DBG_PRINT("@0x%08x: IRQREQB(0x%08x) -> %02x\n", // PC - 8, addr, data); break; case IOMD_IRQMASKC: data = io.irqmask[IRQC]; //DBG_PRINT("@0x%08x: IRQMASKC(0x%08x) -> %02x\n", // PC - 8, addr, data); break; case IOMD_IRQSTATC: data = io.irq[IRQC]; //DBG_PRINT("@0x%08x: IRQSTATC(0x%08x) -> %02x\n", // PC - 8, addr, data); break; case IOMD_IRQREQC: data = io.irq[IRQC] & io.irqmask[IRQC]; //DBG_PRINT("@0x%08x: IRQREQC(0x%08x) -> %02x\n", // PC - 8, addr, data); break; case IOMD_IRQMASKD: data = io.irqmask[IRQD]; //DBG_PRINT("@0x%08x: IRQMASKD(0x%08x) -> %02x\n", // PC - 8, addr, data); break; case IOMD_IRQSTATD:
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -