|
1 import qemu |
|
2 |
|
3 class syborg_fb(qemu.devclass): |
|
4 REG_ID = 0 |
|
5 REG_BASE = 1 |
|
6 REG_HEIGHT = 2 |
|
7 REG_WIDTH = 3 |
|
8 REG_ORIENTATION = 4 |
|
9 REG_BLANK = 5 |
|
10 REG_INT_MASK = 6 |
|
11 REG_INT_CAUSE = 7 |
|
12 REG_BPP = 8 |
|
13 REG_COLOR_ORDER = 9 |
|
14 REG_BYTE_ORDER = 10 |
|
15 REG_PIXEL_ORDER = 11 |
|
16 REG_ROW_PITCH = 12 |
|
17 REG_ENABLED = 13 |
|
18 REG_PALETTE = 0x100 |
|
19 |
|
20 INT_VSYNC = (1 << 0) |
|
21 INT_BASE_UPDATE = (1 << 1) |
|
22 |
|
23 def update_irq(self): |
|
24 self.set_irq_level(0, (self.int_status & self.int_enable) != 0) |
|
25 |
|
26 def do_update(self): |
|
27 old_status = self.int_status |
|
28 if self.need_int: |
|
29 self.int_status |= self.INT_BASE_UPDATE |
|
30 self.need_int = False |
|
31 if self.render.blank == 0: |
|
32 self.int_status |= self.INT_VSYNC |
|
33 if self.int_status != old_status: |
|
34 self.update_irq() |
|
35 return self.enabled |
|
36 |
|
37 def create(self): |
|
38 self.enabled = False |
|
39 self.int_status = 0 |
|
40 self.int_enable = 0 |
|
41 self.need_int = True |
|
42 |
|
43 width = self.properties["width"] |
|
44 height = self.properties["height"] |
|
45 self.render = qemu.render(self.name, width, height) |
|
46 self.render.update = self.do_update |
|
47 |
|
48 def read_reg(self, offset): |
|
49 offset >>= 2 |
|
50 if offset == self.REG_ID: |
|
51 return 0xc51d0006 |
|
52 elif offset == self.REG_BASE: |
|
53 return self.render.base; |
|
54 elif offset == self.REG_WIDTH: |
|
55 return self.render.width; |
|
56 elif offset == self.REG_HEIGHT: |
|
57 return self.render.height; |
|
58 elif offset == self.REG_ORIENTATION: |
|
59 return self.render.orientation; |
|
60 elif offset == self.REG_BLANK: |
|
61 return self.render.blank; |
|
62 elif offset == self.REG_INT_MASK: |
|
63 return self.int_enable; |
|
64 elif offset == self.REG_INT_CAUSE: |
|
65 return self.int_status; |
|
66 elif offset == self.REG_BPP: |
|
67 return self.render.bpp; |
|
68 elif offset == self.REG_COLOR_ORDER: |
|
69 return self.render.color_order; |
|
70 elif offset == self.REG_BYTE_ORDER: |
|
71 return self.render.byte_order; |
|
72 elif offset == self.REG_PIXEL_ORDER: |
|
73 return self.render.pixel_order; |
|
74 elif offset == self.REG_ROW_PITCH: |
|
75 return self.render.row_pitch; |
|
76 elif offset == self.REG_ENABLED: |
|
77 return 1 if self.enabled else 0; |
|
78 elif (offset >= self.REG_PALETTE) and (offset < self.REG_PALETTE + 256): |
|
79 return self.render.palette[offset - self.REG_PALETTE]; |
|
80 return 0 |
|
81 |
|
82 def write_reg(self, offset, value): |
|
83 offset >>= 2 |
|
84 if offset == self.REG_BASE: |
|
85 self.render.base = value; |
|
86 self.need_int = True |
|
87 elif offset == self.REG_WIDTH: |
|
88 self.render.width = value; |
|
89 elif offset == self.REG_HEIGHT: |
|
90 self.render.height = value; |
|
91 elif offset == self.REG_ORIENTATION: |
|
92 self.render.orientation = value; |
|
93 elif offset == self.REG_BLANK: |
|
94 self.render.blank = value; |
|
95 elif offset == self.REG_INT_CAUSE: |
|
96 self.int_status &= ~value; |
|
97 self.update_irq() |
|
98 elif offset == self.REG_INT_MASK: |
|
99 self.int_enable = value & 3; |
|
100 self.update_irq() |
|
101 elif offset == self.REG_BPP: |
|
102 self.render.bpp = value; |
|
103 elif offset == self.REG_COLOR_ORDER: |
|
104 self.render.color_order = value; |
|
105 elif offset == self.REG_BYTE_ORDER: |
|
106 self.render.byte_order = value; |
|
107 elif offset == self.REG_PIXEL_ORDER: |
|
108 self.render.pixel_order = value; |
|
109 elif offset == self.REG_ROW_PITCH: |
|
110 self.render.row_pitch = value; |
|
111 elif offset == self.REG_ENABLED: |
|
112 self.enabled = value != 0; |
|
113 elif (offset >= self.REG_PALETTE) and (offset < self.REG_PALETTE + 256): |
|
114 self.render.palette[offset - self.REG_PALETTE] = value; |
|
115 |
|
116 def save(self, f): |
|
117 f.put_u32(1 if self.need_int else 0) |
|
118 f.put_u32(self.int_status) |
|
119 f.put_u32(self.int_enable) |
|
120 f.put_u32(1 if self.enabled else 0) |
|
121 self.render.put(f) |
|
122 |
|
123 def load(self, f): |
|
124 self.need_int = (f.get_u32() != 0) |
|
125 self.int_status = f.get_u32(); |
|
126 self.int_enable = f.get_u32(); |
|
127 self.enabled = (f.get_u32() != 0) |
|
128 self.render.get(f) |
|
129 |
|
130 # Device class properties |
|
131 regions = [qemu.ioregion(0x1000, readl=read_reg, writel=write_reg)] |
|
132 irqs = 1 |
|
133 name = "syborg,framebuffer" |
|
134 properties = {"width":0, "height":0} |
|
135 |
|
136 qemu.register_device(syborg_fb) |