]> git.sesse.net Git - pistorm/blob - platforms/amiga/rtg/rtg.c
Add dumb framebuffer RTG
[pistorm] / platforms / amiga / rtg / rtg.c
1 #include <stdint.h>
2 #include <endian.h>
3 #include <stdio.h>
4 #include "rtg.h"
5 #include "../../../config_file/config_file.h"
6
7 static uint16_t palette[256];
8 static uint8_t rtg_mem[64 * SIZE_MEGA]; // FIXME
9
10 static uint8_t rtg_u8[4];
11 static uint16_t rtg_x[3], rtg_y[3];
12 static uint16_t rtg_format;
13 static uint32_t rtg_address[2];
14 static uint32_t rtg_rgb[2];
15
16 static uint8_t rtg_enabled;
17
18 uint16_t rtg_display_width, rtg_display_height;
19 uint16_t rtg_display_format;
20 uint16_t rtg_pitch, rtg_total_rows;
21 uint16_t rtg_offset_x, rtg_offset_y;
22
23 uint32_t framebuffer_addr;
24
25 static void handle_rtg_command(uint32_t cmd);
26
27 static const char *op_type_names[OP_TYPE_NUM] = {
28     "BYTE",
29     "WORD",
30     "LONGWORD",
31     "MEM",
32 };
33
34 static const char *rtg_format_names[RTGFMT_NUM] = {
35     "8BPP CLUT",
36     "16BPP RGB (565)",
37     "32BPP RGB (RGBA)",
38     "15BPP RGB (555)",
39 };
40
41 unsigned int rtg_read(uint32_t address, uint8_t mode) {
42     //printf("%s read from RTG: %.8X\n", op_type_names[mode], address);
43     if (address >= PIGFX_REG_SIZE) {
44         if (rtg_mem) {
45             switch (mode) {
46                 case OP_TYPE_BYTE:
47                     return (rtg_mem[address - PIGFX_REG_SIZE]);
48                     break;
49                 case OP_TYPE_WORD:
50                     return *(( uint16_t *) (&rtg_mem[address - PIGFX_REG_SIZE]));
51                     break;
52                 case OP_TYPE_LONGWORD:
53                     return *(( uint32_t *) (&rtg_mem[address - PIGFX_REG_SIZE]));
54                     break;
55                 default:
56                     return 0;
57             }
58         }
59     }
60
61     return 0;
62 }
63
64 void rtg_write(uint32_t address, uint32_t value, uint8_t mode) {
65     //printf("%s write to RTG: %.8X (%.8X)\n", op_type_names[mode], address, value);
66     if (address >= PIGFX_REG_SIZE) {
67         if (rtg_mem) {
68             switch (mode) {
69                 case OP_TYPE_BYTE:
70                     rtg_mem[address - PIGFX_REG_SIZE] = value;
71                     break;
72                 case OP_TYPE_WORD:
73                     *(( uint16_t *) (&rtg_mem[address - PIGFX_REG_SIZE])) = value;
74                     break;
75                 case OP_TYPE_LONGWORD:
76                     *(( uint32_t *) (&rtg_mem[address - PIGFX_REG_SIZE])) = value;
77                     break;
78                 default:
79                     return;
80             }
81         }
82     }
83     else {
84         switch (mode) {
85             case OP_TYPE_BYTE:
86                 switch (address) {
87                     case RTG_U81:
88                     case RTG_U82:
89                     case RTG_U83:
90                     case RTG_U84:
91                         rtg_u8[address - RTG_U81] = value;
92                 }
93                 break;
94             case OP_TYPE_WORD:
95                 switch (address) {
96                     case RTG_X1:
97                         rtg_x[0] = value;
98                         break;
99                     case RTG_X2:
100                         rtg_x[1] = value;
101                         break;
102                     case RTG_X3:
103                         rtg_x[2] = value;
104                         break;
105                     case RTG_Y1:
106                         rtg_y[0] = value;
107                         break;
108                     case RTG_Y2:
109                         rtg_y[1] = value;
110                         break;
111                     case RTG_Y3:
112                         rtg_y[2] = value;
113                         break;
114                     case RTG_FORMAT:
115                         rtg_format = value;
116                         break;
117                     case RTG_COMMAND:
118                         handle_rtg_command(value);
119                         break;
120                 }
121                 break;
122             case OP_TYPE_LONGWORD:
123                 switch (address) {
124                     case RTG_ADDR1:
125                         rtg_address[0] = value;
126                         break;
127                     case RTG_ADDR2:
128                         rtg_address[1] = value;
129                         break;
130                     case RTG_RGB1:
131                         rtg_rgb[0] = value;
132                         break;
133                     case RTG_RGB2:
134                         rtg_rgb[1] = value;
135                         break;
136                 }
137                 break;
138         }
139     }
140
141     return;
142 }
143
144 static void handle_rtg_command(uint32_t cmd) {
145     //printf("Handling RTG command %d (%.8X)\n", cmd, cmd);
146     switch (cmd) {
147         case RTGCMD_SETGC:
148             rtg_display_format = rtg_format;
149             rtg_display_width = rtg_x[0];
150             rtg_display_height = rtg_y[0];
151             if (rtg_u8[0]) {
152                 rtg_pitch = rtg_x[1];
153                 rtg_total_rows = rtg_y[1];
154             }
155             else {
156                 rtg_pitch = rtg_x[1];
157                 rtg_total_rows = rtg_y[1];
158             }
159             //printf("Set RTG mode:\n");
160             //printf("%dx%d pixels\n", rtg_display_width, rtg_display_height);
161             //printf("Pixel format: %s\n", rtg_format_names[rtg_display_format]);
162             break;
163         case RTGCMD_SETPAN:
164             //printf("Command: SetPan.\n");
165             framebuffer_addr = rtg_address[0];
166             rtg_offset_x = rtg_x[1];
167             rtg_offset_y = rtg_y[1];
168             rtg_pitch = (rtg_x[0] << rtg_display_format);
169             //printf("Set panning to $%.8X\n", framebuffer_addr);
170             //printf("Offset X/Y: %d/%d\n", rtg_offset_x, rtg_offset_y);
171             //printf("Pitch: %d (%d bytes)\n", rtg_x[0], rtg_pitch);
172             break;
173         case RTGCMD_SETCLUT: {
174             //printf("Command: SetCLUT.\n");
175             //printf("Set palette entry %d to %d, %d, %d\n", rtg_u8[0], rtg_u8[1], rtg_u8[2], rtg_u8[3]);
176             int r = (int)((float)rtg_u8[1] / 255.0f * 31.0f);
177             int g = (int)((float)rtg_u8[2] / 255.0f * 63.0f);
178             int b = (int)((float)rtg_u8[3] / 255.0f * 31.0f);
179             palette[rtg_u8[0]] = ((r & 0x1F) << 11) | ((g & 0x3F) << 6) | ((b & 0x1F) << 6);
180             break;
181         }
182         case RTGCMD_SETDISPLAY:
183             //printf("Command: SetDisplay.\n");
184             if (rtg_enabled != rtg_u8[1]) {
185                 //printf("RTG Display %s\n", (rtg_u8[1]) ? "enabled" : "disabled");
186                 rtg_enabled = rtg_u8[1];
187                 //if (rtg_enabled)
188                     //printf("%dx%d pixels\n", rtg_display_width, rtg_display_height);
189             }
190             break;
191         case RTGCMD_ENABLE:
192         case RTGCMD_SETSWITCH:
193             // Implementing this command only matters if the Pi is to pass through the analog (or digital)
194             // native video, otherwise this does nothing.
195             break;
196     }
197 }