Advertisement
Guest User

Untitled

a guest
Dec 8th, 2014
197
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.97 KB | None | 0 0
  1. #include <sys/cdefs.h>
  2. __KERNEL_RCSID(0, "$NetBSD: lcg.c,v 1.1 2004/01/27 10:24:00 Blaz Antonic Exp $");
  3.  
  4. #include <sys/param.h>
  5. #include <sys/device.h>
  6. #include <sys/systm.h>
  7. #include <sys/callout.h>
  8. #include <sys/time.h>
  9. #include <sys/types.h>
  10. #include <sys/malloc.h>
  11. #include <sys/conf.h>
  12. #include <sys/kernel.h>
  13.  
  14. #include <machine/vsbus.h>
  15. #include <machine/sid.h>
  16. #include <machine/cpu.h>
  17.  
  18. //#define NO_EXPERIMENTAL
  19. #ifndef NO_EXPERIMENTAL
  20. #include <machine/lcgreg.h>
  21. #endif
  22.  
  23. #include <dev/cons.h>
  24.  
  25. #include <dev/dec/dzreg.h>
  26. #include <dev/dec/dzvar.h>
  27. #include <dev/dec/dzkbdvar.h>
  28.  
  29. #include <dev/wscons/wsdisplayvar.h>
  30. #include <dev/wscons/wsconsio.h>
  31. #include <dev/wscons/wscons_callbacks.h>
  32.  
  33. #include "machine/scb.h"
  34.  
  35. #include "dzkbd.h"
  36. #include "opt_wsfont.h"
  37.  
  38. /* Safety guard */
  39. #include <dev/wsfont/qvss8x15.h>
  40.  
  41. /* Screen hardware defs */
  42. #define LCG_COLS 160 /* char width of screen */
  43. #define LCG_ROWS 68 /* rows of char on screen */
  44. #define LCG_CHEIGHT 15 /* lines a char consists of */
  45. #define LCG_CWIDTH 8 /* cols a char consists of */
  46. #define LCG_ONEROW (LCG_COLS * LCG_CHEIGHT * LCG_CWIDTH)
  47. #define LCG_YSIZE 1024
  48. #define LCG_XSIZE 1280
  49.  
  50. #define LCG_TEXT_COLOR 0xff
  51.  
  52. #define LCG_FB_ADDR 0x21801000 /* Frame buffer */
  53. #define LCG_FB_SIZE (LCG_XSIZE * LCG_YSIZE)
  54. // #define LCG_FB_SIZE 0x00200000 /* 8MB in size */
  55.  
  56. #ifndef NO_EXPERIMENTAL
  57. #define LCG_REG_ADDR 0x20100000 /* LCG registers */
  58. #define LCG_REG_SIZE 0x4000 /* 16384 bytes */
  59.  
  60. #define LCG_LUT_ADDR 0x21800800 /* LUT right before onscreen FB */
  61. #define LCG_LUT_OFFSET 0x00000800
  62. #define LCG_LUT_SIZE 0x800 /* 2048 bytes */
  63. #endif
  64.  
  65. static int lcg_match(struct device *, struct cfdata *, void *);
  66. static void lcg_attach(struct device *, struct device *, void *);
  67.  
  68. struct lcg_softc {
  69. struct device ss_dev;
  70. };
  71.  
  72.  
  73. CFATTACH_DECL_NEW(lcg, sizeof(struct lcg_softc),
  74. lcg_match, lcg_attach, NULL, NULL);
  75.  
  76. static void lcg_cursor(void *, int, int, int);
  77. static int lcg_mapchar(void *, int, unsigned int *);
  78. static void lcg_putchar(void *, int, int, u_int, long);
  79. static void lcg_copycols(void *, int, int, int,int);
  80. static void lcg_erasecols(void *, int, int, int, long);
  81. static void lcg_copyrows(void *, int, int, int);
  82. static void lcg_eraserows(void *, int, int, long);
  83. static int lcg_allocattr(void *, int, int, int, long *);
  84.  
  85. const struct wsdisplay_emulops lcg_emulops = {
  86. lcg_cursor,
  87. lcg_mapchar,
  88. lcg_putchar,
  89. lcg_copycols,
  90. lcg_erasecols,
  91. lcg_copyrows,
  92. lcg_eraserows,
  93. lcg_allocattr
  94. };
  95.  
  96. const struct wsscreen_descr lcg_stdscreen = {
  97. "160x68", LCG_COLS, LCG_ROWS,
  98. &lcg_emulops,
  99. 8, LCG_CHEIGHT,
  100. WSSCREEN_UNDERLINE|WSSCREEN_REVERSE,
  101. };
  102.  
  103. const struct wsscreen_descr *_lcg_scrlist[] = {
  104. &lcg_stdscreen,
  105. };
  106.  
  107. const struct wsscreen_list lcg_screenlist = {
  108. sizeof(_lcg_scrlist) / sizeof(struct wsscreen_descr *),
  109. _lcg_scrlist,
  110. };
  111.  
  112. static char *lcgaddr;
  113.  
  114. #ifndef NO_EXPERMINETAL
  115. static char *lutaddr;
  116. static long *regaddr;
  117. #endif
  118.  
  119. extern struct wsdisplay_font qvss8x15;
  120. static u_char *qf;
  121.  
  122. #define QCHAR(c) (c < 32 ? 32 : (c > 127 ? c - 66 : c - 32))
  123. #define QFONT(c,line) qf[QCHAR(c) * 15 + line]
  124. #define LCG_ADDR(row, col, line, dot) \
  125. lcgaddr[(col * LCG_CWIDTH) + (row * LCG_CHEIGHT * LCG_XSIZE) + \
  126. line * LCG_XSIZE + dot]
  127.  
  128.  
  129. static int lcg_ioctl(void *, void *, u_long, void *, int, struct lwp *);
  130. static paddr_t lcg_mmap(void *, void *, off_t, int);
  131. static int lcg_alloc_screen(void *, const struct wsscreen_descr *,
  132. void **, int *, int *, long *);
  133. static void lcg_free_screen(void *, void *);
  134. static int lcg_show_screen(void *, void *, int,
  135. void (*) (void *, int, int), void *);
  136. static void lcg_crsr_blink(void *);
  137.  
  138. const struct wsdisplay_accessops lcg_accessops = {
  139. lcg_ioctl,
  140. lcg_mmap,
  141. lcg_alloc_screen,
  142. lcg_free_screen,
  143. lcg_show_screen,
  144. 0 /* load_font */
  145. };
  146.  
  147. struct lcg_screen {
  148. int ss_curx;
  149. int ss_cury;
  150. u_char ss_image[LCG_ROWS][LCG_COLS]; /* Image of current screen */
  151. u_char ss_attr[LCG_ROWS][LCG_COLS]; /* Reversed etc... */
  152. };
  153.  
  154. static struct lcg_screen lcg_conscreen;
  155. static struct lcg_screen *curscr;
  156.  
  157. static callout_t lcg_cursor_ch;
  158.  
  159. int
  160. lcg_match(struct device *parent, struct cfdata *match, void *aux)
  161. {
  162. struct vsbus_softc *sc = device_private(parent);
  163. struct vsbus_attach_args *va = aux;
  164. char *ch = (char *)va->va_addr;
  165.  
  166. if ((vax_boardtype != VAX_BTYP_46) && (vax_boardtype != VAX_BTYP_48))
  167. return 0;
  168.  
  169. *ch = 1;
  170. if ((*ch & 1) == 0)
  171. return 0;
  172. *ch = 0;
  173. if ((*ch & 1) != 0)
  174. return 0;
  175.  
  176. sc->sc_mask = 0x04; /* XXX - should be generated */
  177. scb_fake(0x120, 0x15);
  178. return 20;
  179. }
  180.  
  181. void
  182. lcg_attach(struct device *parent, struct device *self, void *aux)
  183. {
  184. struct vsbus_attach_args *va = aux;
  185. struct wsemuldisplaydev_attach_args aa;
  186.  
  187. #ifndef NO_EXPERIMENTAL
  188. int i, j, k;
  189. long video_conf;
  190. #endif
  191.  
  192. printf("\n");
  193. aa.console = lcgaddr != NULL;
  194. lcgaddr = (void *)vax_map_physmem(va->va_paddr, (LCG_FB_SIZE/VAX_NBPG));
  195. if (lcgaddr == 0) {
  196. printf("%s: Couldn't allocate graphics memory.\n", self->dv_xname);
  197. return;
  198. }
  199.  
  200. #ifndef NO_EXPERIMENTAL
  201.  
  202. lutaddr = (void *)vax_map_physmem(LCG_LUT_ADDR, (LCG_LUT_SIZE/VAX_NBPG));
  203. regaddr = (long*)vax_map_physmem(LCG_REG_ADDR, (LCG_REG_SIZE/VAX_NBPG));
  204.  
  205. for (i = 0; i < 256; i++)
  206. for (j = 0; j < 50; j++)
  207. for (k = 0; k < 4; k++)
  208. if (k != 3)
  209. lcgaddr[(j * LCG_XSIZE) + (i * 5) + k + (900 * LCG_XSIZE)] = i;
  210.  
  211.  
  212. for (i = 255; i >= 0; i--) {
  213. lutaddr[i * 8 + 0] = 0;
  214. lutaddr[i * 8 + 1] = i; // address
  215. lutaddr[i * 8 + 2] = 1;
  216. lutaddr[i * 8 + 3] = 0; // red
  217. lutaddr[i * 8 + 4] = 1;
  218. lutaddr[i * 8 + 5] = 0; // green
  219. lutaddr[i * 8 + 6] = 1;
  220. lutaddr[i * 8 + 7] = i; // blue
  221. }
  222.  
  223. video_conf = 0;
  224. video_conf |= (3 << 30);
  225. video_conf |= (3 << 28);
  226. video_conf |= (0 << 26);
  227. video_conf |= (0 << 25);
  228. video_conf |= (0 << 24);
  229. video_conf |= (0 << 23);
  230. video_conf |= (0 << 22);
  231. video_conf |= (0 << 16);
  232. video_conf |= (0 << 15);
  233. video_conf |= (0 << 14);
  234. video_conf |= (1 << 13);
  235. video_conf |= (1 << 12);
  236. video_conf |= (1 << 11);
  237. video_conf |= (1 << 10);
  238. video_conf |= (2 << 8);
  239. video_conf |= (1 << 6);
  240. video_conf |= (0 << 5);
  241. video_conf |= (1 << 4);
  242. video_conf |= (1 << 3);
  243. video_conf |= (0 << 2);
  244. video_conf |= (1 << 1);
  245. video_conf |= (1 << 0);
  246.  
  247. regaddr[LCG_REG_VIDEO_CONFIG/4] = video_conf;
  248.  
  249. /* vital !!! */
  250. regaddr[LCG_REG_LUT_CONSOLE_SEL/4] = 1;
  251.  
  252. regaddr[LCG_REG_LUT_COLOR_BASE_W/4] = LCG_LUT_OFFSET;
  253.  
  254. /* 787 x 100 worked */
  255. i = 0;
  256. while (i < 783) {
  257. j = 0;
  258. while (j < 100) j++;
  259. i++;
  260. }
  261. regaddr[LCG_REG_LUT_CONSOLE_SEL/4] = 0;
  262.  
  263. #if 0
  264. /* delay not needed, only here to see the result on color bar */
  265. i = 0;
  266. while (i < 35000) {
  267. j = 0;
  268. while (j < 1000) j++;
  269. i++;
  270. }
  271. #endif
  272.  
  273. #endif
  274.  
  275. curscr = &lcg_conscreen;
  276.  
  277. aa.scrdata = &lcg_screenlist;
  278. aa.accessops = &lcg_accessops;
  279. qf = qvss8x15.data;
  280.  
  281. /* enable software cursor */
  282. callout_init(&lcg_cursor_ch, 0);
  283. callout_reset(&lcg_cursor_ch, hz / 2, lcg_crsr_blink, NULL);
  284.  
  285. config_found(self, &aa, wsemuldisplaydevprint);
  286. }
  287.  
  288. static char *cursor;
  289.  
  290. static int cur_on;
  291.  
  292. static void
  293. lcg_crsr_blink(void *arg)
  294. {
  295. int dot;
  296.  
  297. if (cur_on)
  298. for (dot = 0; dot < LCG_CWIDTH; dot++)
  299. cursor[dot] ^= LCG_TEXT_COLOR;
  300.  
  301. callout_reset(&lcg_cursor_ch, hz / 2, lcg_crsr_blink, NULL);
  302. }
  303.  
  304. void
  305. lcg_cursor(void *id, int on, int row, int col)
  306. {
  307. struct lcg_screen *ss = id;
  308. int dot;
  309.  
  310. if (ss == NULL)
  311. return;
  312.  
  313. if (ss == curscr) {
  314. char ch = QFONT(ss->ss_image[ss->ss_cury][ss->ss_curx], 14);
  315.  
  316. for (dot = 0; dot < LCG_CWIDTH; dot++)
  317. LCG_ADDR(ss->ss_cury, ss->ss_curx, LCG_CHEIGHT - 1, dot) =
  318. (LCG_TEXT_COLOR * ((ch >> dot) & 1));
  319.  
  320. cursor = &LCG_ADDR(row, col, 14, 0);
  321.  
  322. cur_on = on;
  323. #if 0
  324. if ((cur_on = on))
  325. for (dot = 0; dot < LCG_CWIDTH; dot++)
  326. cursor[dot] ^= LCG_TEXT_COLOR;
  327. #endif
  328.  
  329. }
  330. ss->ss_curx = col;
  331. ss->ss_cury = row;
  332. }
  333.  
  334. int
  335. lcg_mapchar(void *id, int uni, unsigned int *index)
  336. {
  337. if (uni < 256) {
  338. *index = uni;
  339. return (5);
  340. }
  341. *index = ' ';
  342. return (0);
  343. }
  344.  
  345. static void
  346. lcg_putchar(void *id, int row, int col, u_int c, long attr)
  347. {
  348. struct lcg_screen *ss = id;
  349. int i, j;
  350.  
  351. c &= 0xff;
  352.  
  353. ss->ss_image[row][col] = c;
  354. ss->ss_attr[row][col] = attr;
  355. if (ss != curscr)
  356. return;
  357.  
  358. for (i = 0; i < LCG_CHEIGHT; i++) {
  359. unsigned char ch = QFONT(c, i);
  360. char dot;
  361.  
  362. for (j = 0; j < LCG_CWIDTH; j++) {
  363. dot = (LCG_TEXT_COLOR * ((ch >> j) & 1));
  364. if (attr & WSATTR_REVERSE)
  365. dot = (~dot) & 0xff;
  366. LCG_ADDR(row, col, i, j) = dot;
  367. }
  368. }
  369. if (attr & WSATTR_UNDERLINE) {
  370. char *p = &LCG_ADDR(row, col, i, 0);
  371. for (i = 0; i < LCG_CWIDTH; i++)
  372. p[i] = ~p[i];
  373. }
  374. }
  375.  
  376. /*
  377. * copies columns inside a row.
  378. */
  379. static void
  380. lcg_copycols(void *id, int row, int srccol, int dstcol, int ncols)
  381. {
  382. struct lcg_screen *ss = id;
  383. int i;
  384.  
  385. bcopy(&ss->ss_image[row][srccol], &ss->ss_image[row][dstcol], ncols);
  386. bcopy(&ss->ss_attr[row][srccol], &ss->ss_attr[row][dstcol], ncols);
  387. if (ss != curscr)
  388. return;
  389. for (i = 0; i < LCG_CHEIGHT; i++)
  390. memcpy(&LCG_ADDR(row, dstcol, i, 0),
  391. &LCG_ADDR(row,srccol, i, 0), ncols * LCG_CWIDTH);
  392. }
  393.  
  394. /*
  395. * Erases a bunch of chars inside one row.
  396. */
  397. static void
  398. lcg_erasecols(void *id, int row, int startcol, int ncols, long fillattr)
  399. {
  400. struct lcg_screen *ss = id;
  401. int i;
  402.  
  403. bzero(&ss->ss_image[row][startcol], ncols);
  404. bzero(&ss->ss_attr[row][startcol], ncols);
  405. if (ss != curscr)
  406. return;
  407. for (i = 0; i < LCG_CHEIGHT; i++)
  408. memset(&LCG_ADDR(row, startcol, i, 0), 0, ncols * LCG_CWIDTH);
  409. }
  410.  
  411. static void
  412. lcg_copyrows(void *id, int srcrow, int dstrow, int nrows)
  413. {
  414. struct lcg_screen *ss = id;
  415.  
  416. bcopy(&ss->ss_image[srcrow][0], &ss->ss_image[dstrow][0],
  417. nrows * LCG_COLS);
  418. bcopy(&ss->ss_attr[srcrow][0], &ss->ss_attr[dstrow][0],
  419. nrows * LCG_COLS);
  420. if (ss != curscr)
  421. return;
  422. memcpy(&lcgaddr[dstrow * LCG_ONEROW],
  423. &lcgaddr[srcrow * LCG_ONEROW], nrows * LCG_ONEROW);
  424. }
  425.  
  426. static void
  427. lcg_eraserows(void *id, int startrow, int nrows, long fillattr)
  428. {
  429. struct lcg_screen *ss = id;
  430.  
  431. bzero(&ss->ss_image[startrow][0], nrows * LCG_COLS);
  432. bzero(&ss->ss_attr[startrow][0], nrows * LCG_COLS);
  433. if (ss != curscr)
  434. return;
  435. memset(&lcgaddr[startrow * LCG_ONEROW], 0, nrows * LCG_ONEROW);
  436. }
  437.  
  438. static int
  439. lcg_allocattr(void *id, int fg, int bg, int flags, long *attrp)
  440. {
  441. *attrp = flags;
  442. return 0;
  443. }
  444.  
  445. int
  446. lcg_ioctl(void *v, void *vs, u_long cmd, void * data, int flag, struct lwp *p)
  447. {
  448. struct wsdisplay_fbinfo *fb = (void *)data;
  449.  
  450. switch (cmd) {
  451. case WSDISPLAYIO_GTYPE:
  452. *(u_int *)data = WSDISPLAY_TYPE_LCG;
  453. break;
  454.  
  455. case WSDISPLAYIO_GINFO:
  456. fb->height = LCG_YSIZE;
  457. fb->width = LCG_XSIZE;
  458. fb->depth = 1;
  459. fb->cmsize = 2;
  460. break;
  461.  
  462. #if 0
  463. case WSDISPLAYIO_SVIDEO:
  464. if (*(u_int *)data == WSDISPLAYIO_VIDEO_ON) {
  465. curcmd = curc;
  466. } else {
  467. curc = curcmd;
  468. curcmd &= ~(CUR_CMD_FOPA|CUR_CMD_ENPA);
  469. curcmd |= CUR_CMD_FOPB;
  470. }
  471. WRITECUR(CUR_CMD, curcmd);
  472. break;
  473.  
  474. case WSDISPLAYIO_GVIDEO:
  475. *(u_int *)data = (curcmd & CUR_CMD_FOPB ?
  476. WSDISPLAYIO_VIDEO_OFF : WSDISPLAYIO_VIDEO_ON);
  477. break;
  478. #endif
  479.  
  480. default:
  481. return EPASSTHROUGH;
  482. }
  483. return 0;
  484. }
  485.  
  486. static paddr_t
  487. lcg_mmap(void *v, void *vs, off_t offset, int prot)
  488. {
  489. if (offset >= LCG_FB_SIZE || offset < 0)
  490. return -1;
  491. return (LCG_FB_ADDR + offset) >> PGSHIFT;
  492. }
  493.  
  494. int
  495. lcg_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
  496. int *curxp, int *curyp, long *defattrp)
  497. {
  498. *cookiep = malloc(sizeof(struct lcg_screen), M_DEVBUF, M_WAITOK);
  499. bzero(*cookiep, sizeof(struct lcg_screen));
  500. *curxp = *curyp = *defattrp = 0;
  501. return 0;
  502. }
  503.  
  504. void
  505. lcg_free_screen(void *v, void *cookie)
  506. {
  507. }
  508.  
  509. int
  510. lcg_show_screen(void *v, void *cookie, int waitok,
  511. void (*cb)(void *, int, int), void *cbarg)
  512. {
  513. struct lcg_screen *ss = cookie;
  514. int row, col, line, dot;
  515.  
  516. if (ss == curscr)
  517. return (0);
  518.  
  519. for (row = 0; row < LCG_ROWS; row++)
  520. for (col = 0; col < LCG_COLS; col++) {
  521. for (line = 0; line < LCG_CHEIGHT; line++) {
  522. u_char s, c = ss->ss_image[row][col];
  523.  
  524. if (c < 32)
  525. c = 32;
  526. s = QFONT(c, line);
  527. if (ss->ss_attr[row][col] & WSATTR_REVERSE)
  528. s ^= 255;
  529.  
  530. for (dot = 0; dot < LCG_CWIDTH; dot++)
  531. LCG_ADDR(row, col, line, dot) =
  532. (LCG_TEXT_COLOR * ((s >> dot) & 1));
  533. }
  534. if (ss->ss_attr[row][col] & WSATTR_UNDERLINE)
  535. for (dot = 0; dot < LCG_CWIDTH; dot++)
  536. LCG_ADDR(row, col, LCG_CHEIGHT - 1, dot) ^= LCG_TEXT_COLOR;
  537. }
  538.  
  539. cur_on = 1;
  540. cursor = &lcgaddr[(ss->ss_cury * LCG_ONEROW) +
  541. ((LCG_CHEIGHT - 1) * LCG_COLS * LCG_CWIDTH) +
  542. (ss->ss_curx * LCG_CWIDTH)];
  543. curscr = ss;
  544. return (0);
  545. }
  546.  
  547. cons_decl(lcg);
  548. #if 0
  549. cdev_decl(wsdisplay);
  550. #endif
  551.  
  552. void
  553. lcgcninit(struct consdev *cndev)
  554. {
  555. /* Clear screen */
  556. memset(lcgaddr, 0, LCG_XSIZE * LCG_YSIZE);
  557.  
  558. curscr = &lcg_conscreen;
  559. wsdisplay_cnattach(&lcg_stdscreen, &lcg_conscreen, 0, 0, 0);
  560. cn_tab->cn_pri = CN_INTERNAL;
  561. qf = qvss8x15.data;
  562.  
  563. #if NDZKBD > 0
  564. dzkbd_cnattach(0); /* Connect keyboard and screen together */
  565. #endif
  566. }
  567.  
  568. int wsdisplayopen(dev_t dev, int flag, int mode, struct lwp *l);
  569.  
  570. /*
  571. * Called very early to setup the glass tty as console.
  572. * Because it's called before the VM system is inited, virtual memory
  573. * for the framebuffer can be stolen directly without disturbing anything.
  574. */
  575. void
  576. lcgcnprobe(struct consdev *cndev)
  577. {
  578. extern vaddr_t virtual_avail;
  579. extern const struct cdevsw wsdisplay_cdevsw;
  580.  
  581. if ((vax_boardtype != VAX_BTYP_46) && (vax_boardtype != VAX_BTYP_48))
  582. return; /* Only for 4000/60 and VLC */
  583.  
  584. if (vax_confdata & 8)
  585. return; /* Diagnostic console */
  586. lcgaddr = (void *)virtual_avail;
  587. virtual_avail += LCG_FB_SIZE;
  588. #ifndef NO_EXPERIMENTAL
  589. virtual_avail += LCG_LUT_SIZE;
  590. virtual_avail += LCG_REG_SIZE;
  591. #endif
  592. ioaccess((vaddr_t)lcgaddr, LCG_FB_ADDR, (LCG_FB_SIZE/VAX_NBPG));
  593. cndev->cn_pri = CN_INTERNAL;
  594. cndev->cn_dev = makedev(cdevsw_lookup_major(&wsdisplay_cdevsw), 0);
  595. //cndev->cn_dev = makedev(major(wsdisplayopen), 0);
  596. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement