| plan 9 kernel history: overview | file list | diff list |
1990/0902/gnot/screen.c (diff list | history)
| 1990/0902/sys/src/9/gnot/screen.c:1,405 – 1990/0912/sys/src/9/gnot/screen.c:1,406 (short | long | prev | next) | ||
| 1990/03091 | #include "u.h" #include "lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "io.h" | |
| 1990/0330 | #include "ureg.h" | |
| 1990/0808 | #include "errno.h" | |
| 1990/03091 | ||
| 1990/0912 | #include <libg.h> | |
| 1990/0902 | #include <gnot.h> | |
| 1990/03091 | #define MINX 8 | |
| 1990/0902 | extern GFont defont0; extern GFont defont1; GFont *defont; | |
| 1990/03091 | struct{ Point pos; int bwid; }out; | |
| 1990/0329 | void duartinit(void); | |
| 1990/0808 | int duartacr; | |
| 1990/0830 | int duartimr; | |
| 1990/0329 | ||
| 1990/0902 |
| |
| 1990/0912 | GBitmap gscreen = | |
| 1990/03091 | { | |
| 1990/0320 | (ulong*)((4*1024*1024-256*1024)|KZERO), /* BUG */ | |
| 1990/03091 | 0, 64, 0, 0, 0, 1024, 1024, 0 }; void screeninit(void) { | |
| 1990/0329 | duartinit(); | |
| 1990/05313 | /* * Read HEX switch to set ldepth */ if(*(uchar*)MOUSE & (1<<4)){ | |
| 1990/0912 | gscreen.ldepth = 1; | |
| 1990/05313 | defont = &defont1; }else defont = &defont0; | |
| 1990/0902 |
| |
| 1990/0912 | gbitblt(&gscreen, Pt(0, 0), &gscreen, gscreen.r, 0); | |
| 1990/03091 | out.pos.x = MINX; out.pos.y = 0; out.bwid = defont0.info[' '].width; } void screenputc(int c) { char buf[2]; int nx; if(c == '\n'){ out.pos.x = MINX; out.pos.y += defont0.height; | |
| 1990/0329 |
| |
| 1990/0902 |
| |
| 1990/0329 |
| |
| 1990/0912 | if(out.pos.y > gscreen.r.max.y-defont0.height) out.pos.y = gscreen.r.min.y; gbitblt(&gscreen, Pt(0, out.pos.y), &gscreen, Rect(0, out.pos.y, gscreen.r.max.x, out.pos.y+2*defont0.height), 0); | |
| 1990/03091 | }else if(c == '\t'){ | |
| 1990/08101 | out.pos.x += (8-((out.pos.x-MINX)/out.bwid&7))*out.bwid; | |
| 1990/0329 |
| |
| 1990/0912 | if(out.pos.x >= gscreen.r.max.x) | |
| 1990/03091 | screenputc('\n'); }else if(c == '\b'){ if(out.pos.x >= out.bwid+MINX){ out.pos.x -= out.bwid; screenputc(' '); out.pos.x -= out.bwid; } }else{ | |
| 1990/0329 |
| |
| 1990/0912 | if(out.pos.x >= gscreen.r.max.x-out.bwid) | |
| 1990/03091 | screenputc('\n'); buf[0] = c&0x7F; buf[1] = 0; | |
| 1990/0902 |
| |
| 1990/0912 | out.pos = gstring(&gscreen, out.pos, defont, buf, S); | |
| 1990/03091 | } } /* * Register set for half the duart. There are really two sets. */ struct Duart{ uchar mr1_2; /* Mode Register Channels 1 & 2 */ uchar sr_csr; /* Status Register/Clock Select Register */ uchar cmnd; /* Command Register */ uchar data; /* RX Holding / TX Holding Register */ uchar ipc_acr; /* Input Port Change/Aux. Control Register */ | |
| 1990/0329 | #define ivr ivr /* Interrupt Vector Register */ | |
| 1990/03091 | uchar is_imr; /* Interrupt Status/Interrupt Mask Register */ | |
| 1990/0329 | #define ip_opcr is_imr /* Input Port/Output Port Configuration Register */ | |
| 1990/03091 | uchar ctur; /* Counter/Timer Upper Register */ | |
| 1990/0329 | #define scc_sopbc ctur /* Start Counter Command/Set Output Port Bits Command */ | |
| 1990/03091 | uchar ctlr; /* Counter/Timer Lower Register */ | |
| 1990/0329 | #define scc_ropbc ctlr /* Stop Counter Command/Reset Output Port Bits Command */ | |
| 1990/03091 | }; enum{ CHAR_ERR =0x00, /* MR1x - Mode Register 1 */ | |
| 1990/0329 | PAR_ENB =0x00, | |
| 1990/03091 | EVEN_PAR =0x00, ODD_PAR =0x04, NO_PAR =0x10, CBITS8 =0x03, CBITS7 =0x02, CBITS6 =0x01, CBITS5 =0x00, NORM_OP =0x00, /* MR2x - Mode Register 2 */ TWOSTOPB =0x0F, ONESTOPB =0x07, ENB_RX =0x01, /* CRx - Command Register */ DIS_RX =0x02, ENB_TX =0x04, DIS_TX =0x08, RESET_MR =0x10, RESET_RCV =0x20, RESET_TRANS =0x30, RESET_ERR =0x40, RESET_BCH =0x50, STRT_BRK =0x60, STOP_BRK =0x70, RCV_RDY =0x01, /* SRx - Channel Status Register */ FIFOFULL =0x02, XMT_RDY =0x04, XMT_EMT =0x08, OVR_ERR =0x10, PAR_ERR =0x20, FRM_ERR =0x40, RCVD_BRK =0x80, | |
| 1990/0808 | BD38400 =0xCC|0x0000, BD19200 =0xCC|0x0100, BD9600 =0xBB|0x0000, BD4800 =0x99|0x0000, BD2400 =0x88|0x0000, BD1200 =0x66|0x0000, BD300 =0x44|0x0000, | |
| 1990/03091 | IM_IPC =0x80, /* IMRx/ISRx - Interrupt Mask/Interrupt Status */ IM_DBB =0x40, IM_RRDYB =0x20, IM_XRDYB =0x10, IM_CRDY =0x08, IM_DBA =0x04, IM_RRDYA =0x02, IM_XRDYA =0x01, }; uchar keymap[]={ /*80*/ 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x8e, 0x58, /*90*/ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x58, 0x58, 0x58, 0x58, /*A0*/ 0x58, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xae, 0xaf, /*B0*/ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0x80, 0xb7, 0xb8, 0xb9, 0x00, 0xbb, 0x1e, 0xbd, 0x60, 0x1f, | |
| 1990/0825 | /*C0*/ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0x58, 0xc6, 0x0a, | |
| 1990/03091 | 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /*D0*/ 0x09, 0x08, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x7f, 0x58, | |
| 1990/0825 | /*E0*/ 0x58, 0x58, 0xe2, 0x1b, 0x0d, 0xe5, 0x58, 0x0a, | |
| 1990/03091 | 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, | |
| 1990/0825 | /*F0*/ 0x09, 0x08, 0xb2, 0x1b, 0x0d, 0xf5, 0x81, 0x58, | |
| 1990/03091 | 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x7f, 0xb2, }; void | |
| 1990/0329 | duartinit(void) { Duart *duart; duart = DUARTREG; /* * Keyboard */ duart[0].cmnd = RESET_RCV|DIS_TX|DIS_RX; duart[0].cmnd = RESET_TRANS; duart[0].cmnd = RESET_ERR; duart[0].cmnd = RESET_MR; duart[0].mr1_2 = CHAR_ERR|PAR_ENB|EVEN_PAR|CBITS8; duart[0].mr1_2 = NORM_OP|ONESTOPB; duart[0].sr_csr = BD4800; /* | |
| 1990/0629 | * RS232 | |
| 1990/0329 | */ duart[1].cmnd = RESET_RCV|DIS_TX|DIS_RX; duart[1].cmnd = RESET_TRANS; duart[1].cmnd = RESET_ERR; duart[1].cmnd = RESET_MR; duart[1].mr1_2 = CHAR_ERR|NO_PAR|CBITS8; duart[1].mr1_2 = NORM_OP|ONESTOPB; | |
| 1990/0629 | duart[1].sr_csr = BD9600; | |
| 1990/0329 | /* * Output port */ | |
| 1990/0808 | duart[0].ipc_acr = duartacr = 0xB7; /* allow change of state interrupt */ | |
| 1990/0329 | duart[1].ip_opcr = 0x00; duart[1].scc_ropbc = 0xFF; /* make sure the port is reset first */ duart[1].scc_sopbc = 0x04; /* dtr = 1, pp = 01 */ | |
| 1990/0830 | duart[0].is_imr = duartimr = IM_IPC|IM_RRDYB|IM_XRDYB|IM_RRDYA|IM_XRDYA; | |
| 1990/0329 | duart[0].cmnd = ENB_TX|ENB_RX; /* enable TX and RX last */ duart[1].cmnd = ENB_TX|ENB_RX; /* * Initialize keyboard */ while (!(duart[0].sr_csr & (XMT_EMT|XMT_RDY))) ; duart[0].data = 0x02; | |
| 1990/0808 | } | |
| 1990/0830 | int duartinputport(void) { Duart *duart = DUARTREG; return duart[1].ip_opcr; } | |
| 1990/0808 | void duartbaud(int b) { int x; | |
| 1990/0830 | Duart *duart = DUARTREG; | |
| 1990/0808 | switch(b){ case 38400: x = BD38400; break; case 19200: x = BD19200; break; case 9600: x = BD9600; break; case 4800: x = BD4800; break; case 2400: x = BD2400; break; case 1200: x = BD1200; break; case 300: x = BD300; break; default: error(0, Ebadarg); } if(x & 0x0100) duart[0].ipc_acr = duartacr |= 0x80; else duart[0].ipc_acr = duartacr &= ~0x80; duart[1].sr_csr = x; | |
| 1990/0329 | } | |
| 1990/0830 | void duartdtr(int val) { Duart *duart = DUARTREG; if (val) duart[1].scc_ropbc=0x01; else duart[1].scc_sopbc=0x01; } void duartbreak(int ms) { static QLock brk; Duart *duart = DUARTREG; if (ms<=0 || ms >20000) error(0, Ebadarg); qlock(&brk); duart[0].is_imr = duartimr &= ~IM_XRDYB; duart[1].cmnd = STRT_BRK|ENB_TX; tsleep(&u->p->sleep, return0, 0, ms); duart[1].cmnd = STOP_BRK|ENB_TX; duart[0].is_imr = duartimr |= IM_XRDYB; qunlock(&brk); } | |
| 1990/0330 | enum{ Kptime=200 /* about once per ms */ }; | |
| 1990/0329 | void | |
| 1990/0330 | duartstarttimer(void) | |
| 1990/03091 | { | |
| 1990/0330 | Duart *duart; char x; duart = DUARTREG; duart[0].ctur = (Kptime)>>8; duart[0].ctlr = (Kptime)&255; | |
| 1990/0830 | duart[0].is_imr = duartimr |= IM_CRDY; | |
| 1990/0330 | x = duart[1].scc_sopbc; } void duartstoptimer(void) { Duart *duart; char x; duart = DUARTREG; x = duart[1].scc_ropbc; | |
| 1990/0830 | duart[0].is_imr = duartimr &= ~IM_CRDY; | |
| 1990/0330 | } void | |
| 1990/0629 | duartrs232intr(void) { int c; Duart *duart; duart = DUARTREG; c = getrs232o(); if(c == -1) duart[1].cmnd = DIS_TX; else duart[1].data = c; } void duartstartrs232o(void) { DUARTREG[1].cmnd = ENB_TX; duartrs232intr(); } void | |
| 1990/0330 | duartintr(Ureg *ur) { | |
| 1990/03091 | int cause, status, c; Duart *duart; duart = DUARTREG; cause = duart->is_imr; /* * I can guess your interrupt. */ | |
| 1990/0330 | /* * Is it 0? */ if(cause & IM_CRDY){ | |
| 1990/0709 | /* kproftimer(ur->pc);/**/ | |
| 1990/0330 | c = duart[1].scc_ropbc; duart[0].ctur = (Kptime)>>8; duart[0].ctlr = (Kptime)&255; c = duart[1].scc_sopbc; return; } | |
| 1990/03091 | /* * Is it 1? */ if(cause & IM_RRDYA){ /* keyboard input */ status = duart->sr_csr; c = duart->data; if(status & (FRM_ERR|OVR_ERR|PAR_ERR)) duart->cmnd = RESET_ERR; | |
| 1990/0321 | if(status & PAR_ERR) /* control word: caps lock (0x4) or repeat (0x10) */ kbdrepeat((c&0x10) == 0); else{ if(c == 0x7F) c = 0xFF; /* VIEW key (bizarre) */ if(c & 0x80) c = keymap[c&0x7F]; kbdchar(c); } | |
| 1990/03091 | } /* * Is it 2? */ | |
| 1990/0629 | if(cause & IM_RRDYB){ /* rs232 input */ status = duart[1].sr_csr; | |
| 1990/03091 | c = duart[1].data; | |
| 1990/0629 | if(status & (FRM_ERR|OVR_ERR|PAR_ERR)) duart[1].cmnd = RESET_ERR; else rs232ichar(c); } | |
| 1990/0329 | /* | |
| 1990/05313 | * Is it 3? | |
| 1990/0329 | */ | |
| 1990/0629 | if(cause & IM_XRDYB) /* rs232 output */ duartrs232intr(); | |
| 1990/0329 | /* | |
| 1990/05313 | * Is it 4? */ if(cause & IM_XRDYA) duart[0].cmnd = DIS_TX; /* * Is it 5? | |
| 1990/0329 | */ if(cause & IM_IPC) mousebuttons((~duart[0].ipc_acr) & 7); | |
| 1990/03091 | } | |