1 |
/* |
/* |
2 |
* Copyright (C) 2004-2005 Anders Gavare. All rights reserved. |
* Copyright (C) 2004-2007 Anders Gavare. All rights reserved. |
3 |
* |
* |
4 |
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
5 |
* modification, are permitted provided that the following conditions are met: |
* modification, are permitted provided that the following conditions are met: |
25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: dev_px.c,v 1.29 2005/10/26 14:37:04 debug Exp $ |
* $Id: dev_px.c,v 1.38 2007/06/15 19:57:33 debug Exp $ |
29 |
* |
* |
30 |
* TURBOchannel Pixelstamp graphics device. |
* COMMENT: TURBOchannel Pixelstamp graphics card |
31 |
* |
* |
32 |
* PMAG-CA = PX |
* PMAG-CA = PX |
33 |
* PMAG-DA = PXG |
* PMAG-DA = PXG |
98 |
/* #define PX_DEBUG */ |
/* #define PX_DEBUG */ |
99 |
|
|
100 |
|
|
101 |
/* |
DEVICE_TICK(px) |
|
* dev_px_tick(): |
|
|
*/ |
|
|
void dev_px_tick(struct cpu *cpu, void *extra) |
|
102 |
{ |
{ |
103 |
#if 0 |
#if 0 |
104 |
struct px_data *d = extra; |
struct px_data *d = extra; |
105 |
|
|
106 |
if (d->intr & STIC_INT_P_EN) /* or _WE ? */ |
if (d->intr & STIC_INT_P_EN) /* or _WE ? */ |
107 |
cpu_interrupt(cpu, d->irq_nr); |
INTERRUPT_ASSERT(d->irq); |
108 |
#endif |
#endif |
109 |
} |
} |
110 |
|
|
140 |
void dev_px_dma(struct cpu *cpu, uint32_t sys_addr, struct px_data *d) |
void dev_px_dma(struct cpu *cpu, uint32_t sys_addr, struct px_data *d) |
141 |
{ |
{ |
142 |
unsigned char dma_buf[32768]; |
unsigned char dma_buf[32768]; |
143 |
int dma_len = sizeof(dma_buf); |
size_t dma_len = sizeof(dma_buf); |
144 |
int bytesperpixel; |
int bytesperpixel; |
145 |
uint32_t cmdword; |
uint32_t cmdword; |
146 |
|
|
228 |
debug(",HS_EQUALS"); |
debug(",HS_EQUALS"); |
229 |
|
|
230 |
{ |
{ |
231 |
int i; |
size_t i; |
232 |
for (i=0; i<dma_len; i++) |
for (i=0; i<dma_len; i++) |
233 |
debug(" %02x", dma_buf[i]); |
debug(" %02x", dma_buf[i]); |
234 |
} |
} |
239 |
/* NetBSD and Ultrix copyspans */ |
/* NetBSD and Ultrix copyspans */ |
240 |
if (cmdword == 0x405) { |
if (cmdword == 0x405) { |
241 |
uint32_t nspans, lw; |
uint32_t nspans, lw; |
242 |
int spannr, ofs; |
uint32_t spannr, ofs; |
243 |
uint32_t span_len, span_src, span_dst; |
uint32_t span_len, span_src, span_dst; |
244 |
/* unsigned char pixels[PX_XSIZE * 3]; */ |
/* unsigned char pixels[PX_XSIZE * 3]; */ |
245 |
|
|
325 |
|
|
326 |
d->vfb_data->update_x1 = 0; d->vfb_data->update_x2 = |
d->vfb_data->update_x1 = 0; d->vfb_data->update_x2 = |
327 |
PX_XSIZE-1; |
PX_XSIZE-1; |
328 |
if (span_dst < d->vfb_data->update_y1) |
if ((int32_t)span_dst < d->vfb_data->update_y1) |
329 |
d->vfb_data->update_y1 = span_dst; |
d->vfb_data->update_y1 = span_dst; |
330 |
if (span_dst > d->vfb_data->update_y2) |
if ((int32_t)span_dst > d->vfb_data->update_y2) |
331 |
d->vfb_data->update_y2 = span_dst; |
d->vfb_data->update_y2 = span_dst; |
332 |
if (span_src < d->vfb_data->update_y1) |
if ((int32_t)span_src < d->vfb_data->update_y1) |
333 |
d->vfb_data->update_y1 = span_src; |
d->vfb_data->update_y1 = span_src; |
334 |
if (span_src > d->vfb_data->update_y2) |
if ((int32_t)span_src > d->vfb_data->update_y2) |
335 |
d->vfb_data->update_y2 = span_src; |
d->vfb_data->update_y2 = span_src; |
336 |
} |
} |
337 |
} |
} |
338 |
|
|
339 |
/* NetBSD and Ultrix erasecols/eraserows */ |
/* NetBSD and Ultrix erasecols/eraserows */ |
340 |
if (cmdword == 0x411) { |
if (cmdword == 0x411) { |
341 |
uint32_t v1, v2, lw, attr; |
uint32_t v1, v2, attr; |
342 |
|
int32_t lw; |
343 |
int x,y,x2,y2; |
int x,y,x2,y2; |
344 |
int fb_y; |
int fb_y; |
345 |
int bg_r, bg_g, bg_b; |
int bg_r, bg_g, bg_b; |
555 |
} |
} |
556 |
|
|
557 |
|
|
558 |
/* |
DEVICE_ACCESS(px) |
|
* dev_px_access(): |
|
|
*/ |
|
|
int dev_px_access(struct cpu *cpu, struct memory *mem, uint64_t relative_addr, |
|
|
unsigned char *data, size_t len, int writeflag, void *extra) |
|
559 |
{ |
{ |
560 |
uint64_t idata = 0, odata = 0; |
uint64_t idata = 0, odata = 0; |
561 |
struct px_data *d = extra; |
struct px_data *d = extra; |
562 |
int i; |
size_t i; |
563 |
|
|
564 |
if (writeflag == MEM_WRITE) |
if (writeflag == MEM_WRITE) |
565 |
idata = memory_readmax64(cpu, data, len); |
idata = memory_readmax64(cpu, data, len); |
629 |
/* TODO: Most of these aren't implemented yet. */ |
/* TODO: Most of these aren't implemented yet. */ |
630 |
|
|
631 |
switch (relative_addr) { |
switch (relative_addr) { |
632 |
|
|
633 |
case 0x180008: /* hsync */ |
case 0x180008: /* hsync */ |
634 |
if (writeflag==MEM_READ) { |
if (writeflag==MEM_READ) { |
635 |
debug("[ px: read from hsync: 0x%08llx ]\n", |
debug("[ px: read from hsync: 0x%08llx ]\n", |
639 |
(long long)idata); |
(long long)idata); |
640 |
} |
} |
641 |
break; |
break; |
642 |
|
|
643 |
case 0x18000c: /* hsync2 */ |
case 0x18000c: /* hsync2 */ |
644 |
if (writeflag==MEM_READ) { |
if (writeflag==MEM_READ) { |
645 |
debug("[ px: read from hsync2: 0x%08llx ]\n", |
debug("[ px: read from hsync2: 0x%08llx ]\n", |
649 |
(long long)idata); |
(long long)idata); |
650 |
} |
} |
651 |
break; |
break; |
652 |
|
|
653 |
case 0x180010: /* hblank */ |
case 0x180010: /* hblank */ |
654 |
if (writeflag==MEM_READ) { |
if (writeflag==MEM_READ) { |
655 |
debug("[ px: read from hblank: 0x%08llx ]\n", |
debug("[ px: read from hblank: 0x%08llx ]\n", |
659 |
(long long)idata); |
(long long)idata); |
660 |
} |
} |
661 |
break; |
break; |
662 |
|
|
663 |
case 0x180014: /* vsync */ |
case 0x180014: /* vsync */ |
664 |
if (writeflag==MEM_READ) { |
if (writeflag==MEM_READ) { |
665 |
debug("[ px: read from vsync: 0x%08llx ]\n", |
debug("[ px: read from vsync: 0x%08llx ]\n", |
669 |
(long long)idata); |
(long long)idata); |
670 |
} |
} |
671 |
break; |
break; |
672 |
|
|
673 |
case 0x180018: /* vblank */ |
case 0x180018: /* vblank */ |
674 |
if (writeflag==MEM_READ) { |
if (writeflag==MEM_READ) { |
675 |
debug("[ px: read from vblank: 0x%08llx ]\n", |
debug("[ px: read from vblank: 0x%08llx ]\n", |
679 |
(long long)idata); |
(long long)idata); |
680 |
} |
} |
681 |
break; |
break; |
682 |
|
|
683 |
case 0x180020: /* ipdvint */ |
case 0x180020: /* ipdvint */ |
684 |
if (writeflag==MEM_READ) { |
if (writeflag==MEM_READ) { |
685 |
odata = d->intr; |
odata = d->intr; |
701 |
(long long)idata); |
(long long)idata); |
702 |
} |
} |
703 |
break; |
break; |
704 |
|
|
705 |
case 0x180028: /* sticsr */ |
case 0x180028: /* sticsr */ |
706 |
if (writeflag==MEM_READ) { |
if (writeflag==MEM_READ) { |
707 |
debug("[ px: read from sticsr: 0x%08llx ]\n", |
debug("[ px: read from sticsr: 0x%08llx ]\n", |
711 |
(long long)idata); |
(long long)idata); |
712 |
} |
} |
713 |
break; |
break; |
714 |
|
|
715 |
case 0x180038: /* buscsr */ |
case 0x180038: /* buscsr */ |
716 |
if (writeflag==MEM_READ) { |
if (writeflag==MEM_READ) { |
717 |
debug("[ px: read from buscsr: 0x%08llx ]\n", |
debug("[ px: read from buscsr: 0x%08llx ]\n", |
721 |
(long long)idata); |
(long long)idata); |
722 |
} |
} |
723 |
break; |
break; |
724 |
|
|
725 |
case 0x18003c: /* modcl */ |
case 0x18003c: /* modcl */ |
726 |
if (writeflag==MEM_READ) { |
if (writeflag==MEM_READ) { |
727 |
odata = (d->type << 12) + (d->xconfig << 11) + |
odata = (d->type << 12) + (d->xconfig << 11) + |
733 |
(long long)idata); |
(long long)idata); |
734 |
} |
} |
735 |
break; |
break; |
736 |
|
|
737 |
default: |
default: |
738 |
if (writeflag==MEM_READ) { |
if (writeflag==MEM_READ) { |
739 |
debug("[ px: read from addr 0x%x: 0x%llx ]\n", |
debug("[ px: read from addr 0x%x: 0x%llx ]\n", |
751 |
} |
} |
752 |
|
|
753 |
|
|
|
/* |
|
|
* dev_px_init(): |
|
|
*/ |
|
754 |
void dev_px_init(struct machine *machine, struct memory *mem, |
void dev_px_init(struct machine *machine, struct memory *mem, |
755 |
uint64_t baseaddr, int px_type, int irq_nr) |
uint64_t baseaddr, int px_type, char *irq_path) |
756 |
{ |
{ |
757 |
struct px_data *d; |
struct px_data *d; |
758 |
|
|
759 |
d = malloc(sizeof(struct px_data)); |
CHECK_ALLOCATION(d = malloc(sizeof(struct px_data))); |
|
if (d == NULL) { |
|
|
fprintf(stderr, "out of memory\n"); |
|
|
exit(1); |
|
|
} |
|
760 |
memset(d, 0, sizeof(struct px_data)); |
memset(d, 0, sizeof(struct px_data)); |
761 |
|
|
762 |
d->type = px_type; |
d->type = px_type; |
763 |
d->irq_nr = irq_nr; |
|
764 |
|
INTERRUPT_CONNECT(irq_path, d->irq); |
765 |
|
|
766 |
d->xconfig = d->yconfig = 0; /* 4x1 */ |
d->xconfig = d->yconfig = 0; /* 4x1 */ |
767 |
|
|
805 |
switch (d->type) { |
switch (d->type) { |
806 |
case DEV_PX_TYPE_PX: |
case DEV_PX_TYPE_PX: |
807 |
dev_bt459_init(machine, mem, baseaddr + 0x200000, 0, |
dev_bt459_init(machine, mem, baseaddr + 0x200000, 0, |
808 |
d->vfb_data, 8, irq_nr, BT459_PX); |
d->vfb_data, 8, irq_path, BT459_PX); |
809 |
break; |
break; |
810 |
case DEV_PX_TYPE_PXG: |
case DEV_PX_TYPE_PXG: |
811 |
case DEV_PX_TYPE_PXGPLUS: |
case DEV_PX_TYPE_PXGPLUS: |
812 |
case DEV_PX_TYPE_PXGPLUSTURBO: |
case DEV_PX_TYPE_PXGPLUSTURBO: |
813 |
dev_bt459_init(machine, mem, baseaddr + 0x300000, 0, |
dev_bt459_init(machine, mem, baseaddr + 0x300000, 0, |
814 |
d->vfb_data, d->bitdepth, irq_nr, BT459_PX); |
d->vfb_data, d->bitdepth, irq_path, BT459_PX); |
815 |
break; |
break; |
816 |
default: |
default: |
817 |
fatal("dev_px_init(): unimplemented px_type\n"); |
fatal("dev_px_init(): unimplemented px_type\n"); |
818 |
} |
} |
819 |
|
|
820 |
memory_device_register(mem, "px", baseaddr, DEV_PX_LENGTH, |
memory_device_register(mem, "px", baseaddr, DEV_PX_LENGTH, |
821 |
dev_px_access, d, MEM_DEFAULT, NULL); |
dev_px_access, d, DM_DEFAULT, NULL); |
822 |
machine_add_tickfunction(machine, dev_px_tick, d, 14); |
machine_add_tickfunction(machine, dev_px_tick, d, 14); |
823 |
} |
} |
824 |
|
|