megadrive_test1
changeset 6:862f8a034cae
expanding the megadrive code
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 11 Feb 2017 08:56:42 +0200 |
parents | f99eab59e7dc |
children | 8253942b0a1a |
files | Makefile src/io.c src/io.h src/libc/ctype.c src/libc/printf.c src/libc/stdlib.c src/libc/string.c src/main.c src/misc.c src/misc.h src/startup.s src/vdp.c src/vdp.h |
diffstat | 13 files changed, 775 insertions(+), 11 deletions(-) [+] |
line diff
1.1 --- a/Makefile Wed Feb 01 14:40:19 2017 +0200 1.2 +++ b/Makefile Sat Feb 11 08:56:42 2017 +0200 1.3 @@ -1,4 +1,4 @@ 1.4 -csrc = $(wildcard src/*.c) 1.5 +csrc = $(wildcard src/*.c) $(wildcard src/libc/*.c) 1.6 asrc = $(wildcard src/*.s) 1.7 aSsrc = $(wildcard src/*.S) 1.8 obj = $(asrc:.s=.o) $(aSsrc:.S=.o) $(csrc:.c=.o) 1.9 @@ -9,7 +9,8 @@ 1.10 1.11 warn = -pedantic -Wall 1.12 dbg = -g 1.13 -def = -DGAMENAME=\"testgame\" -DVERSTR=\"01\" 1.14 +def = -DGAMENAME=\"testgame\" -DVERSTR=\"01\" -D__NO_CTYPE 1.15 +inc = -Isrc/libc 1.16 1.17 tool_prefix = m68k-linux-gnu- 1.18 1.19 @@ -18,16 +19,17 @@ 1.20 LD = $(tool_prefix)ld 1.21 OBJCOPY = $(tool_prefix)objcopy 1.22 1.23 -CFLAGS = -m68000 -fno-builtin $(warn) $(dbg) $(opt) $(def) 1.24 +CFLAGS = -m68000 -ffreestanding -fno-builtin $(warn) $(dbg) $(opt) $(def) $(inc) 1.25 CPPFLAGS = $(def) 1.26 ASFLAGS = -m68000 1.27 -LDFLAGS = -T megadrive.ldscript -print-gc-sections 1.28 +LDFLAGS = -T megadrive.ldscript -print-gc-sections \ 1.29 + -L/usr/lib/gcc-cross/m68k-linux-gnu/6 -lgcc 1.30 1.31 $(bin): $(elf) 1.32 $(OBJCOPY) -O binary $< $@ 1.33 1.34 $(elf): $(obj) 1.35 - $(LD) -o $@ $(LDFLAGS) $(obj) -Map link.map 1.36 + $(LD) -o $@ $(obj) -Map link.map $(LDFLAGS) 1.37 1.38 .PHONY: clean 1.39 clean:
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/src/io.c Sat Feb 11 08:56:42 2017 +0200 2.3 @@ -0,0 +1,11 @@ 2.4 +#include "io.h" 2.5 + 2.6 +int mdg_version(void) 2.7 +{ 2.8 + return IO_VERSION & IO_VER_MASK; 2.9 +} 2.10 + 2.11 +int mdg_ispal(void) 2.12 +{ 2.13 + return IO_VERSION & IO_VER_VMOD; 2.14 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/src/io.h Sat Feb 11 08:56:42 2017 +0200 3.3 @@ -0,0 +1,16 @@ 3.4 +#ifndef IO_H_ 3.5 +#define IO_H_ 3.6 + 3.7 +#define IO_VERSION (*(unsigned char*)0xa10001) 3.8 + 3.9 +#define IO_VER_MASK 0x0f 3.10 +#define IO_VER_DISK 0x20 3.11 +#define IO_VER_VMOD 0x40 3.12 +#define IO_VER_MODE_BIT 0x80 3.13 + 3.14 +#define IO_Z80_MEM_START 0xa00000 3.15 + 3.16 +int mdg_version(void); 3.17 +int mdg_ispal(void); 3.18 + 3.19 +#endif /* IO_H_ */
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/src/libc/ctype.c Sat Feb 11 08:56:42 2017 +0200 4.3 @@ -0,0 +1,60 @@ 4.4 +int isalpha(int c); 4.5 +int isdigit(int c); 4.6 +int islower(int c); 4.7 +int isupper(int c); 4.8 + 4.9 + 4.10 +int isalnum(int c) 4.11 +{ 4.12 + return isalpha(c) || isdigit(c); 4.13 +} 4.14 + 4.15 +int isalpha(int c) 4.16 +{ 4.17 + return isupper(c) || islower(c); 4.18 +} 4.19 + 4.20 +int isblank(int c) 4.21 +{ 4.22 + return c == ' ' || c == '\t'; 4.23 +} 4.24 + 4.25 +int isdigit(int c) 4.26 +{ 4.27 + return c >= '0' && c <= '9'; 4.28 +} 4.29 + 4.30 +int isupper(int c) 4.31 +{ 4.32 + return c >= 'A' && c <= 'Z'; 4.33 +} 4.34 + 4.35 +int islower(int c) 4.36 +{ 4.37 + return c >= 'a' && c <= 'z'; 4.38 +} 4.39 + 4.40 +int isgraph(int c) 4.41 +{ 4.42 + return c > ' ' && c <= '~'; 4.43 +} 4.44 + 4.45 +int isprint(int c) 4.46 +{ 4.47 + return isgraph(c) || c == ' '; 4.48 +} 4.49 + 4.50 +int isspace(int c) 4.51 +{ 4.52 + return isblank(c) || c == '\f' || c == '\n' || c == '\r' || c == '\v'; 4.53 +} 4.54 + 4.55 +int toupper(int c) 4.56 +{ 4.57 + return islower(c) ? (c + ('A' - 'a')) : c; 4.58 +} 4.59 + 4.60 +int tolower(int c) 4.61 +{ 4.62 + return isupper(c) ? (c + ('A' - 'a')) : c; 4.63 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/src/libc/printf.c Sat Feb 11 08:56:42 2017 +0200 5.3 @@ -0,0 +1,323 @@ 5.4 +#include <stdio.h> 5.5 +#include <string.h> 5.6 +#include <stdlib.h> 5.7 +#include <ctype.h> 5.8 +#include <stdarg.h> 5.9 + 5.10 +static void bwrite(char *buf, size_t buf_sz, char *str, int sz); 5.11 +static int intern_printf(char *buf, size_t sz, const char *fmt, va_list ap); 5.12 +static void itoa(int val, char *buf, int base); 5.13 +static void utoa(unsigned int val, char *buf, int base); 5.14 + 5.15 + 5.16 +int putchar(int c) 5.17 +{ 5.18 + /* TODO */ 5.19 + return c; 5.20 +} 5.21 + 5.22 +int puts(const char *s) 5.23 +{ 5.24 + while(*s) { 5.25 + putchar(*s++); 5.26 + } 5.27 + putchar('\n'); 5.28 + return 0; 5.29 +} 5.30 + 5.31 +/* -- printf and friends -- */ 5.32 + 5.33 +static char *convc = "dioxXucsfeEgGpn%"; 5.34 + 5.35 +#define IS_CONV(c) strchr(convc, c) 5.36 + 5.37 +int printf(const char *fmt, ...) 5.38 +{ 5.39 + int res; 5.40 + va_list ap; 5.41 + 5.42 + va_start(ap, fmt); 5.43 + res = intern_printf(0, 0, fmt, ap); 5.44 + va_end(ap); 5.45 + return res; 5.46 +} 5.47 + 5.48 +int vprintf(const char *fmt, va_list ap) 5.49 +{ 5.50 + return intern_printf(0, 0, fmt, ap); 5.51 +} 5.52 + 5.53 +int sprintf(char *buf, const char *fmt, ...) 5.54 +{ 5.55 + int res; 5.56 + va_list ap; 5.57 + 5.58 + va_start(ap, fmt); 5.59 + res = intern_printf(buf, 0, fmt, ap); 5.60 + va_end(ap); 5.61 + return res; 5.62 +} 5.63 + 5.64 +int vsprintf(char *buf, const char *fmt, va_list ap) 5.65 +{ 5.66 + return intern_printf(buf, 0, fmt, ap); 5.67 +} 5.68 + 5.69 +int snprintf(char *buf, size_t sz, const char *fmt, ...) 5.70 +{ 5.71 + int res; 5.72 + va_list ap; 5.73 + 5.74 + va_start(ap, fmt); 5.75 + res = intern_printf(buf, sz, fmt, ap); 5.76 + va_end(ap); 5.77 + return res; 5.78 +} 5.79 + 5.80 +int vsnprintf(char *buf, size_t sz, const char *fmt, va_list ap) 5.81 +{ 5.82 + return intern_printf(buf, sz, fmt, ap); 5.83 +} 5.84 + 5.85 + 5.86 +/* intern_printf provides all the functionality needed by all the printf 5.87 + * variants. 5.88 + * - buf: optional buffer onto which the formatted results are written. If null 5.89 + * then the output goes to the terminal through putchar calls. This is used 5.90 + * by the (v)sprintf variants which write to an array of char. 5.91 + * - sz: optional maximum size of the output, 0 means unlimited. This is used 5.92 + * by the (v)snprintf variants to avoid buffer overflows. 5.93 + * The rest are obvious, format string and variable argument list. 5.94 + */ 5.95 + 5.96 +#define BUF(x) ((x) ? (x) + cnum : (x)) 5.97 +#define SZ(x) ((x) ? (x) - cnum : (x)) 5.98 + 5.99 +static int intern_printf(char *buf, size_t sz, const char *fmt, va_list ap) 5.100 +{ 5.101 + char conv_buf[32]; 5.102 + char *str; 5.103 + int i, slen; 5.104 + const char *fstart = 0; 5.105 + 5.106 + /* state */ 5.107 + int cnum = 0; 5.108 + int base = 10; 5.109 + int alt = 0; 5.110 + int fwidth = 0; 5.111 + int padc = ' '; 5.112 + int sign = 0; 5.113 + int left_align = 0; /* not implemented yet */ 5.114 + int hex_caps = 0; 5.115 + int unsig = 0; 5.116 + 5.117 + while(*fmt) { 5.118 + if(*fmt == '%') { 5.119 + fstart = fmt++; 5.120 + continue; 5.121 + } 5.122 + 5.123 + if(fstart) { 5.124 + if(IS_CONV(*fmt)) { 5.125 + switch(*fmt) { 5.126 + case 'X': 5.127 + hex_caps = 1; 5.128 + 5.129 + case 'x': 5.130 + case 'p': 5.131 + base = 16; 5.132 + 5.133 + if(alt) { 5.134 + bwrite(BUF(buf), SZ(sz), "0x", 2); 5.135 + } 5.136 + 5.137 + case 'u': 5.138 + unsig = 1; 5.139 + 5.140 + if(0) { 5.141 + case 'o': 5.142 + base = 8; 5.143 + 5.144 + if(alt) { 5.145 + bwrite(BUF(buf), SZ(sz), "0", 1); 5.146 + } 5.147 + } 5.148 + 5.149 + case 'd': 5.150 + case 'i': 5.151 + if(unsig) { 5.152 + utoa(va_arg(ap, unsigned int), conv_buf, base); 5.153 + } else { 5.154 + itoa(va_arg(ap, int), conv_buf, base); 5.155 + } 5.156 + if(hex_caps) { 5.157 + for(i=0; conv_buf[i]; i++) { 5.158 + conv_buf[i] = toupper(conv_buf[i]); 5.159 + } 5.160 + } 5.161 + 5.162 + slen = strlen(conv_buf); 5.163 + for(i=slen; i<fwidth; i++) { 5.164 + bwrite(BUF(buf), SZ(sz), (char*)&padc, 1); 5.165 + cnum++; 5.166 + } 5.167 + 5.168 + bwrite(BUF(buf), SZ(sz), conv_buf, strlen(conv_buf)); 5.169 + cnum += slen; 5.170 + break; 5.171 + 5.172 + case 'c': 5.173 + { 5.174 + char c = va_arg(ap, int); 5.175 + bwrite(BUF(buf), SZ(sz), &c, 1); 5.176 + cnum++; 5.177 + } 5.178 + break; 5.179 + 5.180 + case 's': 5.181 + str = va_arg(ap, char*); 5.182 + slen = strlen(str); 5.183 + 5.184 + for(i=slen; i<fwidth; i++) { 5.185 + bwrite(BUF(buf), SZ(sz), (char*)&padc, 1); 5.186 + cnum++; 5.187 + } 5.188 + bwrite(BUF(buf), SZ(sz), str, slen); 5.189 + cnum += slen; 5.190 + break; 5.191 + 5.192 + case 'n': 5.193 + *va_arg(ap, int*) = cnum; 5.194 + break; 5.195 + 5.196 + default: 5.197 + break; 5.198 + } 5.199 + 5.200 + /* restore default conversion state */ 5.201 + base = 10; 5.202 + alt = 0; 5.203 + fwidth = 0; 5.204 + padc = ' '; 5.205 + hex_caps = 0; 5.206 + 5.207 + fstart = 0; 5.208 + fmt++; 5.209 + } else { 5.210 + switch(*fmt) { 5.211 + case '#': 5.212 + alt = 1; 5.213 + break; 5.214 + 5.215 + case '+': 5.216 + sign = 1; 5.217 + break; 5.218 + 5.219 + case '-': 5.220 + left_align = 1; 5.221 + break; 5.222 + 5.223 + case 'l': 5.224 + case 'L': 5.225 + break; 5.226 + 5.227 + case '0': 5.228 + padc = '0'; 5.229 + break; 5.230 + 5.231 + default: 5.232 + if(isdigit(*fmt)) { 5.233 + const char *fw = fmt; 5.234 + while(*fmt && isdigit(*fmt)) fmt++; 5.235 + 5.236 + fwidth = atoi(fw); 5.237 + continue; 5.238 + } 5.239 + } 5.240 + fmt++; 5.241 + } 5.242 + } else { 5.243 + bwrite(BUF(buf), SZ(sz), (char*)fmt++, 1); 5.244 + cnum++; 5.245 + } 5.246 + } 5.247 + 5.248 + return 0; 5.249 +} 5.250 + 5.251 + 5.252 +/* bwrite is called by intern_printf to transparently handle writing into a 5.253 + * buffer (if buf is non-null) or to the terminal (if buf is null). 5.254 + */ 5.255 +static void bwrite(char *buf, size_t buf_sz, char *str, int sz) 5.256 +{ 5.257 + if(buf) { 5.258 + if(buf_sz && buf_sz <= sz) sz = buf_sz - 1; 5.259 + memcpy(buf, str, sz); 5.260 + 5.261 + buf[sz] = 0; 5.262 + } else { 5.263 + int i; 5.264 + for(i=0; i<sz; i++) { 5.265 + putchar(*str++); 5.266 + } 5.267 + } 5.268 +} 5.269 + 5.270 + 5.271 +static void itoa(int val, char *buf, int base) 5.272 +{ 5.273 + static char rbuf[16]; 5.274 + char *ptr = rbuf; 5.275 + int neg = 0; 5.276 + 5.277 + if(val < 0) { 5.278 + neg = 1; 5.279 + val = -val; 5.280 + } 5.281 + 5.282 + if(val == 0) { 5.283 + *ptr++ = '0'; 5.284 + } 5.285 + 5.286 + while(val) { 5.287 + int digit = val % base; 5.288 + *ptr++ = digit < 10 ? (digit + '0') : (digit - 10 + 'a'); 5.289 + val /= base; 5.290 + } 5.291 + 5.292 + if(neg) { 5.293 + *ptr++ = '-'; 5.294 + } 5.295 + 5.296 + ptr--; 5.297 + 5.298 + while(ptr >= rbuf) { 5.299 + *buf++ = *ptr--; 5.300 + } 5.301 + *buf = 0; 5.302 +} 5.303 + 5.304 +static void utoa(unsigned int val, char *buf, int base) 5.305 +{ 5.306 + static char rbuf[16]; 5.307 + char *ptr = rbuf; 5.308 + 5.309 + if(val == 0) { 5.310 + *ptr++ = '0'; 5.311 + } 5.312 + 5.313 + while(val) { 5.314 + unsigned int digit = val % base; 5.315 + *ptr++ = digit < 10 ? (digit + '0') : (digit - 10 + 'a'); 5.316 + val /= base; 5.317 + } 5.318 + 5.319 + ptr--; 5.320 + 5.321 + while(ptr >= rbuf) { 5.322 + *buf++ = *ptr--; 5.323 + } 5.324 + *buf = 0; 5.325 +} 5.326 +
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/src/libc/stdlib.c Sat Feb 11 08:56:42 2017 +0200 6.3 @@ -0,0 +1,62 @@ 6.4 +#include <stdlib.h> 6.5 +#include <ctype.h> 6.6 + 6.7 +int atoi(const char *str) 6.8 +{ 6.9 + return strtol(str, 0, 10); 6.10 +} 6.11 + 6.12 +long atol(const char *str) 6.13 +{ 6.14 + return strtol(str, 0, 10); 6.15 +} 6.16 + 6.17 +long strtol(const char *str, char **endp, int base) 6.18 +{ 6.19 + long acc = 0; 6.20 + int sign = 1; 6.21 + 6.22 + while(isspace(*str)) str++; 6.23 + 6.24 + if(base == 0) { 6.25 + if(str[0] == '0') { 6.26 + if(str[1] == 'x' || str[1] == 'X') { 6.27 + base = 16; 6.28 + } else { 6.29 + base = 8; 6.30 + } 6.31 + } else { 6.32 + base = 10; 6.33 + } 6.34 + } 6.35 + 6.36 + if(*str == '+') { 6.37 + str++; 6.38 + } else if(*str == '-') { 6.39 + sign = -1; 6.40 + str++; 6.41 + } 6.42 + 6.43 + while(*str) { 6.44 + long val; 6.45 + char c = tolower(*str); 6.46 + 6.47 + if(isdigit(c)) { 6.48 + val = *str - '0'; 6.49 + } else if(c >= 'a' || c <= 'f') { 6.50 + val = 10 + c - 'a'; 6.51 + } 6.52 + if(val >= base) { 6.53 + break; 6.54 + } 6.55 + 6.56 + acc = acc * base + val; 6.57 + str++; 6.58 + } 6.59 + 6.60 + if(endp) { 6.61 + *endp = (char*)str; 6.62 + } 6.63 + 6.64 + return sign > 0 ? acc : -acc; 6.65 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/src/libc/string.c Sat Feb 11 08:56:42 2017 +0200 7.3 @@ -0,0 +1,107 @@ 7.4 +#include <string.h> 7.5 + 7.6 +void *memset(void *s, int c, size_t n) 7.7 +{ 7.8 + char *ptr = s; 7.9 + while(n--) { 7.10 + *ptr++ = c; 7.11 + } 7.12 + return s; 7.13 +} 7.14 + 7.15 +void *memcpy(void *dest, const void *src, size_t n) 7.16 +{ 7.17 + char *dptr = dest; 7.18 + const char *sptr = src; 7.19 + 7.20 + while(n--) { 7.21 + *dptr++ = *sptr++; 7.22 + } 7.23 + return dest; 7.24 +} 7.25 + 7.26 +void *memmove(void *dest, const void *src, size_t n) 7.27 +{ 7.28 + int i; 7.29 + char *dptr; 7.30 + const char *sptr; 7.31 + 7.32 + if(dest <= src) { 7.33 + /* forward copy */ 7.34 + dptr = dest; 7.35 + sptr = src; 7.36 + for(i=0; i<n; i++) { 7.37 + *dptr++ = *sptr++; 7.38 + } 7.39 + } else { 7.40 + /* backwards copy */ 7.41 + dptr = (char*)dest + n - 1; 7.42 + sptr = (char*)src + n - 1; 7.43 + for(i=0; i<n; i++) { 7.44 + *dptr-- = *sptr--; 7.45 + } 7.46 + } 7.47 + 7.48 + return dest; 7.49 +} 7.50 + 7.51 +size_t strlen(const char *s) 7.52 +{ 7.53 + size_t len = 0; 7.54 + while(*s++) len++; 7.55 + return len; 7.56 +} 7.57 + 7.58 +char *strchr(const char *s, int c) 7.59 +{ 7.60 + while(*s) { 7.61 + if(*s == c) { 7.62 + return (char*)s; 7.63 + } 7.64 + s++; 7.65 + } 7.66 + return 0; 7.67 +} 7.68 + 7.69 +char *strrchr(const char *s, int c) 7.70 +{ 7.71 + const char *ptr = s; 7.72 + 7.73 + /* find the end */ 7.74 + while(*ptr) ptr++; 7.75 + 7.76 + /* go back checking for c */ 7.77 + while(--ptr >= s) { 7.78 + if(*ptr == c) { 7.79 + return (char*)ptr; 7.80 + } 7.81 + } 7.82 + return 0; 7.83 +} 7.84 + 7.85 +char *strstr(const char *str, const char *substr) 7.86 +{ 7.87 + while(*str) { 7.88 + const char *s1 = str; 7.89 + const char *s2 = substr; 7.90 + 7.91 + while(*s1 && *s1 == *s2) { 7.92 + s1++; 7.93 + s2++; 7.94 + } 7.95 + if(!*s2) { 7.96 + return (char*)str; 7.97 + } 7.98 + str++; 7.99 + } 7.100 + return 0; 7.101 +} 7.102 + 7.103 +int strcmp(const char *s1, const char *s2) 7.104 +{ 7.105 + while(*s1 && *s1 == *s2) { 7.106 + s1++; 7.107 + s2++; 7.108 + } 7.109 + return *s1 - *s2; 7.110 +}
8.1 --- a/src/main.c Wed Feb 01 14:40:19 2017 +0200 8.2 +++ b/src/main.c Sat Feb 11 08:56:42 2017 +0200 8.3 @@ -1,12 +1,32 @@ 8.4 #include "vdp.h" 8.5 8.6 +static const unsigned char pal[][3] = { 8.7 + {0, 0, 0}, {64, 128, 255}, {255, 128, 32}, {255, 255, 255} 8.8 +}; 8.9 + 8.10 +static const unsigned char pat[8] = { 8.11 + 0, 0, 0, 0, /* 0 0 0 0 0 0 0 0 */ 8.12 + 1, 0x11, 0x11, 0x11, /* 0 1 1 1 1 1 1 1 */ 8.13 + 1, 0x11, 0x11, 0x11, /* 0 1 1 1 1 1 1 1 */ 8.14 + 1, 0x11, 0x11, 0x12, /* 0 1 1 1 1 1 1 2 */ 8.15 + 1, 0x11, 0x12, 0x22, /* 0 1 1 1 1 2 2 2 */ 8.16 + 1, 0x11, 0x22, 0x22, /* 0 1 1 1 2 2 2 2 */ 8.17 + 1, 0x11, 0x22, 0x22, /* 0 1 1 1 2 2 2 2 */ 8.18 + 1, 0x12, 0x22, 0x22 /* 0 1 1 2 2 2 2 2 */ 8.19 +}; 8.20 + 8.21 int main(void) 8.22 { 8.23 - VDP_SET_CRAM_ADDR(0); 8.24 - VDP_SET_CRAM_RGB24(64, 128, 255); 8.25 + unsigned char *tmap; 8.26 + 8.27 + vdp_init(); 8.28 + 8.29 + vdp_setpal(0, sizeof pal / sizeof *pal, (unsigned char*)pal); 8.30 VDP_SET_BGCOLOR(0, 0); 8.31 - /* enable display */ 8.32 - VDP_SET_REG(0, VDP_REG0_BASE); 8.33 - VDP_SET_REG(1, VDP_REG1_BASE | VDP_REG1_DISP_BIT); 8.34 + 8.35 + vdp_set_tilemap_slot(VDP_PLANE_A, 0); 8.36 + tmap = vdp_tilemap_ptr(VDP_PLANE_A); 8.37 + 8.38 + 8.39 return 0; 8.40 }
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/src/misc.c Sat Feb 11 08:56:42 2017 +0200 9.3 @@ -0,0 +1,17 @@ 9.4 +#include <stdio.h> 9.5 +#include <stdarg.h> 9.6 +#include "misc.h" 9.7 + 9.8 +void panic(const char *fmt, ...) 9.9 +{ 9.10 + va_list ap; 9.11 + 9.12 + printf("~~~~ panic ~~~~\n"); 9.13 + va_start(ap, fmt); 9.14 + vprintf(fmt, ap); 9.15 + va_end(ap); 9.16 + 9.17 + /*printf("registers:\n");*/ 9.18 + 9.19 + halt_cpu(); 9.20 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/src/misc.h Sat Feb 11 08:56:42 2017 +0200 10.3 @@ -0,0 +1,9 @@ 10.4 +#ifndef MISC_H_ 10.5 +#define MISC_H_ 10.6 + 10.7 +void panic(const char *fmt, ...); 10.8 + 10.9 +/* defined in startup.s */ 10.10 +void halt_cpu(void); 10.11 + 10.12 +#endif /* MISC_H_ */
11.1 --- a/src/startup.s Wed Feb 01 14:40:19 2017 +0200 11.2 +++ b/src/startup.s Sat Feb 11 08:56:42 2017 +0200 11.3 @@ -2,6 +2,7 @@ 11.4 .extern main 11.5 11.6 .global start 11.7 + .global halt_cpu 11.8 start: 11.9 | copy .data section from ROM to RAM 11.10 move.l #_data_lma, %a0 11.11 @@ -24,4 +25,5 @@ 11.12 bne.s 0b 11.13 1: 11.14 jsr main 11.15 +halt_cpu: 11.16 stop #0x2700
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/src/vdp.c Sat Feb 11 08:56:42 2017 +0200 12.3 @@ -0,0 +1,85 @@ 12.4 +#include <stdint.h> 12.5 +#include "vdp.h" 12.6 +#include "io.h" 12.7 +#include "misc.h" 12.8 + 12.9 +static void *tilemap_ptr[3]; 12.10 + 12.11 +int vdp_init(void) 12.12 +{ 12.13 + unsigned int mode1_flags = VDP_REG1_DISP_BIT; 12.14 + 12.15 + if(mdg_ispal()) { 12.16 + mode1_flags |= VDP_REG1_30CELL_BIT; 12.17 + } 12.18 + 12.19 + VDP_SET_REG(0, VDP_REG0_BASE); 12.20 + VDP_SET_REG(1, VDP_REG1_BASE | mode1_flags); 12.21 + 12.22 + return 0; 12.23 +} 12.24 + 12.25 +void vdp_set_tilemap_slot(int plane, int slot) 12.26 +{ 12.27 + switch(plane) { 12.28 + case VDP_PLANE_A: 12.29 + VDP_SET_REG(VDP_REG_PADDR_A, (slot & 7) << 3); 12.30 + tilemap_ptr[VDP_PLANE_A] = (void*)((uint32_t)slot << 13); 12.31 + break; 12.32 + 12.33 + case VDP_PLANE_WIN: 12.34 + VDP_SET_REG(VDP_REG_PADDR_WIN, (slot & 0x1f) << 1); 12.35 + tilemap_ptr[VDP_PLANE_WIN] = (void*)((uint32_t)slot << 11); 12.36 + break; 12.37 + 12.38 + case VDP_PLANE_B: 12.39 + VDP_SET_REG(VDP_REG_PADDR_B, slot & 7); 12.40 + tilemap_ptr[VDP_PLANE_B] = (void*)((uint32_t)slot << 13); 12.41 + break; 12.42 + } 12.43 +} 12.44 + 12.45 +void *vdp_tilemap_ptr(int plane) 12.46 +{ 12.47 + return tilemap_ptr[plane]; 12.48 +} 12.49 + 12.50 +void vdp_setpal_rgb24(int idx, int r, int g, int b) 12.51 +{ 12.52 + VDP_SET_CRAM_ADDR(idx); 12.53 + VDP_SET_CRAM_RGB24(r, g, b); 12.54 +} 12.55 + 12.56 +void vdp_setpal(int idx0, int count, unsigned char *pal) 12.57 +{ 12.58 + int i; 12.59 + 12.60 + VDP_SET_CRAM_ADDR(idx0); 12.61 + for(i=0; i<count; i++) { 12.62 + VDP_SET_CRAM_RGB24(pal[0], pal[1], pal[2]); 12.63 + pal += 3; 12.64 + } 12.65 +} 12.66 + 12.67 +#define SCROLLSIZE(x) \ 12.68 + do { \ 12.69 + switch(xtiles) { \ 12.70 + case 32: \ 12.71 + case 64: \ 12.72 + (x) >>= 6; \ 12.73 + break; \ 12.74 + case 128: \ 12.75 + (x) = 3; \ 12.76 + break; \ 12.77 + default: \ 12.78 + panic("invalid argument to %s: %d\n", (x), __func__); \ 12.79 + } \ 12.80 + } while(0) 12.81 + 12.82 +void vdp_set_scroll_size(int xtiles, int ytiles) 12.83 +{ 12.84 + SCROLLSIZE(xtiles); 12.85 + SCROLLSIZE(ytiles); 12.86 + 12.87 + VDP_SET_REG(VDP_REG_SCROLL_SIZE, (ytiles << 4) | xtiles); 12.88 +}
13.1 --- a/src/vdp.h Wed Feb 01 14:40:19 2017 +0200 13.2 +++ b/src/vdp.h Sat Feb 11 08:56:42 2017 +0200 13.3 @@ -10,6 +10,28 @@ 13.4 #define VDP_PORT_HVCOUNT (*(volatile uint16_t*)0xc00008) 13.5 #define VDP_PORT_PSG (*(volatile uint16_t*)0xc00010) 13.6 13.7 +/* registers */ 13.8 +#define VDP_REG_MODE1 0 13.9 +#define VDP_REG_MODE2 1 13.10 +#define VDP_REG_PADDR_A 2 13.11 +#define VDP_REG_PADDR_WIN 3 13.12 +#define VDP_REG_PADDR_B 4 13.13 +#define VDP_REG_SPRITE 5 13.14 +#define VDP_REG_BGCOLOR 7 13.15 +#define VDP_REG_HINT 10 13.16 +#define VDP_REG_MODE3 11 13.17 +#define VDP_REG_MODE4 12 13.18 +#define VDP_REG_HSCROLL 13 13.19 +#define VDP_REG_AUTOINC 15 13.20 +#define VDP_REG_SCROLL_SIZE 16 13.21 +#define VDP_REG_WINXPOS 17 13.22 +#define VDP_REG_WINYPOS 18 13.23 +#define VDP_REG_DMALEN_LOW 19 13.24 +#define VDP_REG_DMALEN_HIGH 20 13.25 +#define VDP_REG_DMA_SADDR_LOW 21 13.26 +#define VDP_REG_DMA_SADDR_MID 22 13.27 +#define VDP_REG_DMA_SADDR_HIGH 23 13.28 + 13.29 /* control register read flags */ 13.30 #define VDP_CTL_PAL_BIT 0x0001 13.31 #define VDP_CTL_HBLANK_BIT 0x0002 13.32 @@ -42,12 +64,17 @@ 13.33 #define VDP_REG1_DMA_BIT 0x10 13.34 #define VDP_REG1_VINTR_BIT 0x20 13.35 #define VDP_REG1_DISP_BIT 0x40 13.36 +#define VDP_REG1_XVRAM_BIT 0x80 13.37 13.38 #define VDP_MODE_WR_BIT 1 13.39 13.40 #define VDP_VRAM_WR 1 13.41 #define VDP_CRAM_WR 3 13.42 13.43 +#define VDP_DMA_MEM_TO_VRAM 0 13.44 +#define VDP_DMA_VRAM_FILL 2 13.45 +#define VDP_DMA_VRAM_COPY 3 13.46 + 13.47 #define VDP_ADDRSET(addr, mode) /* TODO */ 13.48 13.49 #define VDP_CRAM_ADDR32(addr) (0xc0000000 | ((uint32_t)(addr) << 16)) 13.50 @@ -55,15 +82,38 @@ 13.51 #define VDP_SET_CRAM_ADDR(addr) \ 13.52 do { VDP_PORT_CTL32 = VDP_CRAM_ADDR32(addr); } while(0) 13.53 13.54 +#define VDP_RGB(r, g, b) \ 13.55 + ((((uint16_t)(r) << 1) & 0xe) | \ 13.56 + (((uint16_t)(g) << 5) & 0xe0) | \ 13.57 + (((uint16_t)(b) << 9) & 0xe00)) 13.58 + 13.59 #define VDP_RGB24(r, g, b) \ 13.60 ((((uint16_t)(r) >> 4) & 0xe) | \ 13.61 ((uint16_t)(g) & 0xe0) | \ 13.62 (((uint16_t)(b) << 4) & 0xe00)) 13.63 13.64 +#define VDP_SET_CRAM_RGB(r, g, b) \ 13.65 + do { VDP_PORT_DATA = VDP_RGB(r, g, b); } while(0) 13.66 + 13.67 #define VDP_SET_CRAM_RGB24(r, g, b) \ 13.68 do { VDP_PORT_DATA = VDP_RGB24(r, g, b); } while(0) 13.69 13.70 #define VDP_SET_BGCOLOR(pal, col) \ 13.71 - do { VDP_SET_REG(7, ((pal) << 4) | (col)); } while(0) 13.72 + do { VDP_SET_REG(VDP_REG_BGCOLOR, ((pal) << 4) | (col)); } while(0) 13.73 + 13.74 +/* arguments to vdp_tilemap_slot */ 13.75 +#define VDP_PLANE_A 0 13.76 +#define VDP_PLANE_WIN 1 13.77 +#define VDP_PLANE_B 2 13.78 + 13.79 +int vdp_init(void); 13.80 +void vdp_set_tilemap_slot(int plane, int slot); 13.81 +void *vdp_tilemap_ptr(int plane); 13.82 +void vdp_setpal_rgb24(int idx, int r, int g, int b); 13.83 +void vdp_setpal(int idx0, int count, unsigned char *pal); 13.84 +/* TODO vdp_setpal_dma */ 13.85 + 13.86 +/* xtiles and ytiles can only be 32, 64, or 128 */ 13.87 +void vdp_set_scroll_size(int xtiles, int ytiles); 13.88 13.89 #endif /* VDP_H_ */