Marcus Comstedt's SoftVMS ported to Pokitto.
Fork of HelloWorld by
cpu.cpp@11:88c459b0ac3a, 2018-03-31 (annotated)
- Committer:
- fmanga
- Date:
- Sat Mar 31 19:07:59 2018 +0000
- Revision:
- 11:88c459b0ac3a
Initial SoftVMS port
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
fmanga | 11:88c459b0ac3a | 1 | #ifdef WIN32 |
fmanga | 11:88c459b0ac3a | 2 | #include <windows.h> |
fmanga | 11:88c459b0ac3a | 3 | #include <io.h> |
fmanga | 11:88c459b0ac3a | 4 | #define HAVE_FCNTL_H |
fmanga | 11:88c459b0ac3a | 5 | #define HAVE_ERRNO_H |
fmanga | 11:88c459b0ac3a | 6 | #endif |
fmanga | 11:88c459b0ac3a | 7 | |
fmanga | 11:88c459b0ac3a | 8 | #ifdef __DJGPP__ |
fmanga | 11:88c459b0ac3a | 9 | #include <io.h> |
fmanga | 11:88c459b0ac3a | 10 | #include <sys/timeb.h> |
fmanga | 11:88c459b0ac3a | 11 | #define HAVE_FCNTL_H |
fmanga | 11:88c459b0ac3a | 12 | #define HAVE_ERRNO_H |
fmanga | 11:88c459b0ac3a | 13 | #define HAVE_SYS_TIME_H |
fmanga | 11:88c459b0ac3a | 14 | #endif |
fmanga | 11:88c459b0ac3a | 15 | |
fmanga | 11:88c459b0ac3a | 16 | #include <stdio.h> |
fmanga | 11:88c459b0ac3a | 17 | #include <stdlib.h> |
fmanga | 11:88c459b0ac3a | 18 | #include <string.h> |
fmanga | 11:88c459b0ac3a | 19 | #ifdef HAVE_FCNTL_H |
fmanga | 11:88c459b0ac3a | 20 | #include <fcntl.h> |
fmanga | 11:88c459b0ac3a | 21 | #endif |
fmanga | 11:88c459b0ac3a | 22 | #ifdef HAVE_ERRNO_H |
fmanga | 11:88c459b0ac3a | 23 | #include <errno.h> |
fmanga | 11:88c459b0ac3a | 24 | #endif |
fmanga | 11:88c459b0ac3a | 25 | #ifdef HAVE_UNISTD_H |
fmanga | 11:88c459b0ac3a | 26 | #include <unistd.h> |
fmanga | 11:88c459b0ac3a | 27 | #endif |
fmanga | 11:88c459b0ac3a | 28 | #ifdef HAVE_UTIME_H |
fmanga | 11:88c459b0ac3a | 29 | #include <utime.h> |
fmanga | 11:88c459b0ac3a | 30 | #endif |
fmanga | 11:88c459b0ac3a | 31 | #ifdef TIME_WITH_SYS_TIME |
fmanga | 11:88c459b0ac3a | 32 | #include <sys/time.h> |
fmanga | 11:88c459b0ac3a | 33 | #include <time.h> |
fmanga | 11:88c459b0ac3a | 34 | #else |
fmanga | 11:88c459b0ac3a | 35 | #ifdef HAVE_SYS_TIME_H |
fmanga | 11:88c459b0ac3a | 36 | #include <sys/time.h> |
fmanga | 11:88c459b0ac3a | 37 | #else |
fmanga | 11:88c459b0ac3a | 38 | #include <time.h> |
fmanga | 11:88c459b0ac3a | 39 | #endif |
fmanga | 11:88c459b0ac3a | 40 | #endif |
fmanga | 11:88c459b0ac3a | 41 | #ifdef HAVE_DEVICES_TIMER_H |
fmanga | 11:88c459b0ac3a | 42 | #include <devices/timer.h> |
fmanga | 11:88c459b0ac3a | 43 | #undef tv_secs |
fmanga | 11:88c459b0ac3a | 44 | #undef tv_micro |
fmanga | 11:88c459b0ac3a | 45 | #define tv_sec tv_secs |
fmanga | 11:88c459b0ac3a | 46 | #define tv_usec tv_micro |
fmanga | 11:88c459b0ac3a | 47 | #endif |
fmanga | 11:88c459b0ac3a | 48 | |
fmanga | 11:88c459b0ac3a | 49 | #include "prototypes.h" |
fmanga | 11:88c459b0ac3a | 50 | |
fmanga | 11:88c459b0ac3a | 51 | #define SGNEXT(n) ((n)&0x80? (n)-0x100:(n)) |
fmanga | 11:88c459b0ac3a | 52 | |
fmanga | 11:88c459b0ac3a | 53 | #ifndef BIG |
fmanga | 11:88c459b0ac3a | 54 | #define BIG |
fmanga | 11:88c459b0ac3a | 55 | #endif |
fmanga | 11:88c459b0ac3a | 56 | |
fmanga | 11:88c459b0ac3a | 57 | #ifndef O_BINARY |
fmanga | 11:88c459b0ac3a | 58 | #define O_BINARY 0 |
fmanga | 11:88c459b0ac3a | 59 | #endif |
fmanga | 11:88c459b0ac3a | 60 | |
fmanga | 11:88c459b0ac3a | 61 | // BIG extern const unsigned char flash[]; |
fmanga | 11:88c459b0ac3a | 62 | #include "flash.h" |
fmanga | 11:88c459b0ac3a | 63 | |
fmanga | 11:88c459b0ac3a | 64 | BIG unsigned char bios[0]; |
fmanga | 11:88c459b0ac3a | 65 | unsigned char ram[2][0x100]; |
fmanga | 11:88c459b0ac3a | 66 | unsigned char sfr[0x100]; |
fmanga | 11:88c459b0ac3a | 67 | unsigned char xram[3][0x80]; |
fmanga | 11:88c459b0ac3a | 68 | unsigned char wram[0x200]; |
fmanga | 11:88c459b0ac3a | 69 | const unsigned char *rom; |
fmanga | 11:88c459b0ac3a | 70 | |
fmanga | 11:88c459b0ac3a | 71 | unsigned char parity[0x100]; |
fmanga | 11:88c459b0ac3a | 72 | |
fmanga | 11:88c459b0ac3a | 73 | int pc; |
fmanga | 11:88c459b0ac3a | 74 | int lcd_updated, lcdon, imask, intreq, hasbios=0; |
fmanga | 11:88c459b0ac3a | 75 | int spd; |
fmanga | 11:88c459b0ac3a | 76 | int t0h, t0l, t0base, t0scale; |
fmanga | 11:88c459b0ac3a | 77 | int t1h, t1l; |
fmanga | 11:88c459b0ac3a | 78 | int gamesize; |
fmanga | 11:88c459b0ac3a | 79 | |
fmanga | 11:88c459b0ac3a | 80 | void keypress(int i) |
fmanga | 11:88c459b0ac3a | 81 | { |
fmanga | 11:88c459b0ac3a | 82 | sfr[0x4c]&=~(1<<i); |
fmanga | 11:88c459b0ac3a | 83 | if(sfr[0x4e]&4) |
fmanga | 11:88c459b0ac3a | 84 | sfr[0x4e]|=2; |
fmanga | 11:88c459b0ac3a | 85 | } |
fmanga | 11:88c459b0ac3a | 86 | |
fmanga | 11:88c459b0ac3a | 87 | void keyrelease(int i) |
fmanga | 11:88c459b0ac3a | 88 | { |
fmanga | 11:88c459b0ac3a | 89 | sfr[0x4c]|=(1<<i); |
fmanga | 11:88c459b0ac3a | 90 | if(sfr[0x4e]&4) |
fmanga | 11:88c459b0ac3a | 91 | sfr[0x4e]|=2; |
fmanga | 11:88c459b0ac3a | 92 | } |
fmanga | 11:88c459b0ac3a | 93 | |
fmanga | 11:88c459b0ac3a | 94 | int tobcd(int n) |
fmanga | 11:88c459b0ac3a | 95 | { |
fmanga | 11:88c459b0ac3a | 96 | return ((n/10)<<4)|(n%10); |
fmanga | 11:88c459b0ac3a | 97 | } |
fmanga | 11:88c459b0ac3a | 98 | |
fmanga | 11:88c459b0ac3a | 99 | /* |
fmanga | 11:88c459b0ac3a | 100 | int initflash(int fd) |
fmanga | 11:88c459b0ac3a | 101 | { |
fmanga | 11:88c459b0ac3a | 102 | int r=0, t=0; |
fmanga | 11:88c459b0ac3a | 103 | memset(flash, 0, sizeof(flash)); |
fmanga | 11:88c459b0ac3a | 104 | while(t<sizeof(flash) && (r=read(fd, flash+t, sizeof(flash)-t))>0) |
fmanga | 11:88c459b0ac3a | 105 | t += r; |
fmanga | 11:88c459b0ac3a | 106 | if(r<0 || t<0x480) |
fmanga | 11:88c459b0ac3a | 107 | return 0; |
fmanga | 11:88c459b0ac3a | 108 | return t; |
fmanga | 11:88c459b0ac3a | 109 | } |
fmanga | 11:88c459b0ac3a | 110 | |
fmanga | 11:88c459b0ac3a | 111 | void fakeflash(char *filename, int sz) |
fmanga | 11:88c459b0ac3a | 112 | { |
fmanga | 11:88c459b0ac3a | 113 | unsigned char *root, *fat, *dir; |
fmanga | 11:88c459b0ac3a | 114 | time_t t = time(NULL); |
fmanga | 11:88c459b0ac3a | 115 | struct tm *tm = localtime(&t); |
fmanga | 11:88c459b0ac3a | 116 | int i; |
fmanga | 11:88c459b0ac3a | 117 | char *fn2; |
fmanga | 11:88c459b0ac3a | 118 | |
fmanga | 11:88c459b0ac3a | 119 | if((fn2 = strrchr(filename, '/'))!=NULL) |
fmanga | 11:88c459b0ac3a | 120 | filename = fn2+1; |
fmanga | 11:88c459b0ac3a | 121 | else if((fn2 = strrchr(filename, '\\'))!=NULL) |
fmanga | 11:88c459b0ac3a | 122 | filename = fn2+1; |
fmanga | 11:88c459b0ac3a | 123 | memset(flash+241*512, 0, sizeof(flash)-241*512); |
fmanga | 11:88c459b0ac3a | 124 | root = flash+255*512; |
fmanga | 11:88c459b0ac3a | 125 | fat = flash+254*512; |
fmanga | 11:88c459b0ac3a | 126 | dir = flash+253*512; |
fmanga | 11:88c459b0ac3a | 127 | sz = ((sz+511)>>9); |
fmanga | 11:88c459b0ac3a | 128 | for(i=0; i<256*2; i+=2) { |
fmanga | 11:88c459b0ac3a | 129 | fat[i] = 0xfc; |
fmanga | 11:88c459b0ac3a | 130 | fat[i+1] = 0xff; |
fmanga | 11:88c459b0ac3a | 131 | } |
fmanga | 11:88c459b0ac3a | 132 | for(i=0; i<sz; i++) { |
fmanga | 11:88c459b0ac3a | 133 | fat[2*i] = i+1; |
fmanga | 11:88c459b0ac3a | 134 | fat[2*i+1] = 0; |
fmanga | 11:88c459b0ac3a | 135 | } |
fmanga | 11:88c459b0ac3a | 136 | if((--i)>=0) { |
fmanga | 11:88c459b0ac3a | 137 | fat[2*i] = 0xfa; |
fmanga | 11:88c459b0ac3a | 138 | fat[2*i+1] = 0xff; |
fmanga | 11:88c459b0ac3a | 139 | } |
fmanga | 11:88c459b0ac3a | 140 | fat[254*2] = 0xfa; |
fmanga | 11:88c459b0ac3a | 141 | fat[254*2+1] = 0xff; |
fmanga | 11:88c459b0ac3a | 142 | fat[255*2] = 0xfa; |
fmanga | 11:88c459b0ac3a | 143 | fat[255*2+1] = 0xff; |
fmanga | 11:88c459b0ac3a | 144 | for(i=253; i>241; --i) { |
fmanga | 11:88c459b0ac3a | 145 | fat[2*i] = i-1; |
fmanga | 11:88c459b0ac3a | 146 | fat[2*i+1] = 0; |
fmanga | 11:88c459b0ac3a | 147 | } |
fmanga | 11:88c459b0ac3a | 148 | fat[241*2] = 0xfa; |
fmanga | 11:88c459b0ac3a | 149 | fat[241*2+1] = 0xff; |
fmanga | 11:88c459b0ac3a | 150 | dir[0] = 0xcc; |
fmanga | 11:88c459b0ac3a | 151 | strncpy(dir+4, filename, 12); |
fmanga | 11:88c459b0ac3a | 152 | for(i=strlen(filename); i<12; i++) |
fmanga | 11:88c459b0ac3a | 153 | dir[4+i]=' '; |
fmanga | 11:88c459b0ac3a | 154 | dir[0x10] = tobcd(tm->tm_year/100+19); |
fmanga | 11:88c459b0ac3a | 155 | dir[0x11] = tobcd(tm->tm_year%100); |
fmanga | 11:88c459b0ac3a | 156 | dir[0x12] = tobcd(tm->tm_mon+1); |
fmanga | 11:88c459b0ac3a | 157 | dir[0x13] = tobcd(tm->tm_mday); |
fmanga | 11:88c459b0ac3a | 158 | dir[0x14] = tobcd(tm->tm_hour); |
fmanga | 11:88c459b0ac3a | 159 | dir[0x15] = tobcd(tm->tm_min); |
fmanga | 11:88c459b0ac3a | 160 | dir[0x16] = tobcd(tm->tm_sec); |
fmanga | 11:88c459b0ac3a | 161 | dir[0x17] = tobcd(tm->tm_wday); |
fmanga | 11:88c459b0ac3a | 162 | dir[0x18] = sz&0xff; |
fmanga | 11:88c459b0ac3a | 163 | dir[0x19] = sz>>8; |
fmanga | 11:88c459b0ac3a | 164 | dir[0x1a] = 1; |
fmanga | 11:88c459b0ac3a | 165 | memset(root, 0x55, 16); |
fmanga | 11:88c459b0ac3a | 166 | root[0x10] = 1; |
fmanga | 11:88c459b0ac3a | 167 | memcpy(root+0x30, dir+0x10, 8); |
fmanga | 11:88c459b0ac3a | 168 | root[0x44] = 255; |
fmanga | 11:88c459b0ac3a | 169 | root[0x46] = 254; |
fmanga | 11:88c459b0ac3a | 170 | root[0x48] = 1; |
fmanga | 11:88c459b0ac3a | 171 | root[0x4a] = 253; |
fmanga | 11:88c459b0ac3a | 172 | root[0x4c] = 13; |
fmanga | 11:88c459b0ac3a | 173 | root[0x50] = 200; |
fmanga | 11:88c459b0ac3a | 174 | } |
fmanga | 11:88c459b0ac3a | 175 | |
fmanga | 11:88c459b0ac3a | 176 | void check_gamesize() |
fmanga | 11:88c459b0ac3a | 177 | { |
fmanga | 11:88c459b0ac3a | 178 | unsigned char *root, *fat, *dir; |
fmanga | 11:88c459b0ac3a | 179 | int i, fatblk, dirblk, dircnt; |
fmanga | 11:88c459b0ac3a | 180 | root = flash+255*512; |
fmanga | 11:88c459b0ac3a | 181 | fatblk = (root[0x47]<<8)|root[0x46]; |
fmanga | 11:88c459b0ac3a | 182 | dirblk = (root[0x4b]<<8)|root[0x4a]; |
fmanga | 11:88c459b0ac3a | 183 | dircnt = (root[0x4d]<<8)|root[0x4c]; |
fmanga | 11:88c459b0ac3a | 184 | if(fatblk>=256 || dircnt>=256 || !dircnt) |
fmanga | 11:88c459b0ac3a | 185 | return; |
fmanga | 11:88c459b0ac3a | 186 | fat = flash+fatblk*512; |
fmanga | 11:88c459b0ac3a | 187 | while(dircnt-- && dirblk<256) { |
fmanga | 11:88c459b0ac3a | 188 | dir = flash+dirblk*512; |
fmanga | 11:88c459b0ac3a | 189 | dirblk = (fat[2*dirblk+1]<<8)|fat[2*dirblk]; |
fmanga | 11:88c459b0ac3a | 190 | for(i=0; i<16; i++) |
fmanga | 11:88c459b0ac3a | 191 | if(dir[i*32] == 0xcc) { |
fmanga | 11:88c459b0ac3a | 192 | int sz = (dir[i*32+0x19]<<8)|dir[i*32+0x18]; |
fmanga | 11:88c459b0ac3a | 193 | if(sz>1 && sz<=200) { |
fmanga | 11:88c459b0ac3a | 194 | gamesize = sz*512; |
fmanga | 11:88c459b0ac3a | 195 | return; |
fmanga | 11:88c459b0ac3a | 196 | } |
fmanga | 11:88c459b0ac3a | 197 | } |
fmanga | 11:88c459b0ac3a | 198 | } |
fmanga | 11:88c459b0ac3a | 199 | } |
fmanga | 11:88c459b0ac3a | 200 | |
fmanga | 11:88c459b0ac3a | 201 | int loadflash(char *filename) |
fmanga | 11:88c459b0ac3a | 202 | { |
fmanga | 11:88c459b0ac3a | 203 | int r, fd; |
fmanga | 11:88c459b0ac3a | 204 | |
fmanga | 11:88c459b0ac3a | 205 | if((fd = open(filename, O_RDONLY|O_BINARY))>=0) { |
fmanga | 11:88c459b0ac3a | 206 | if(!(r=initflash(fd))) { |
fmanga | 11:88c459b0ac3a | 207 | close(fd); |
fmanga | 11:88c459b0ac3a | 208 | error_msg("%s: can't load FLASH image", filename); |
fmanga | 11:88c459b0ac3a | 209 | return 0; |
fmanga | 11:88c459b0ac3a | 210 | } |
fmanga | 11:88c459b0ac3a | 211 | close(fd); |
fmanga | 11:88c459b0ac3a | 212 | gamesize = r; |
fmanga | 11:88c459b0ac3a | 213 | if(r<241*512) |
fmanga | 11:88c459b0ac3a | 214 | fakeflash(filename, r); |
fmanga | 11:88c459b0ac3a | 215 | check_gamesize(); |
fmanga | 11:88c459b0ac3a | 216 | return 1; |
fmanga | 11:88c459b0ac3a | 217 | } else { |
fmanga | 11:88c459b0ac3a | 218 | perror(filename); |
fmanga | 11:88c459b0ac3a | 219 | return 0; |
fmanga | 11:88c459b0ac3a | 220 | } |
fmanga | 11:88c459b0ac3a | 221 | } |
fmanga | 11:88c459b0ac3a | 222 | */ |
fmanga | 11:88c459b0ac3a | 223 | |
fmanga | 11:88c459b0ac3a | 224 | void halt_mode() |
fmanga | 11:88c459b0ac3a | 225 | { |
fmanga | 11:88c459b0ac3a | 226 | waitforevents(NULL); |
fmanga | 11:88c459b0ac3a | 227 | checkevents(); |
fmanga | 11:88c459b0ac3a | 228 | } |
fmanga | 11:88c459b0ac3a | 229 | |
fmanga | 11:88c459b0ac3a | 230 | void lcdrefresh() |
fmanga | 11:88c459b0ac3a | 231 | { |
fmanga | 11:88c459b0ac3a | 232 | static unsigned char icon[4][7] = { |
fmanga | 11:88c459b0ac3a | 233 | { 0x2a, 0x23, 0x47, 0xfb, 0x23, 0x23, 0x3f }, |
fmanga | 11:88c459b0ac3a | 234 | { 0xff, 0x83, 0x93, 0xbb, 0x93, 0xbb, 0xff }, |
fmanga | 11:88c459b0ac3a | 235 | { 0x7c, 0x82, 0x92, 0x9b, 0x82, 0x82, 0x7c }, |
fmanga | 11:88c459b0ac3a | 236 | { 0x10, 0x28, 0xef, 0x6e, 0x6c, 0x7e, 0xc3 } |
fmanga | 11:88c459b0ac3a | 237 | }; |
fmanga | 11:88c459b0ac3a | 238 | int y, x, i, a, b=0, p=0; |
fmanga | 11:88c459b0ac3a | 239 | |
fmanga | 11:88c459b0ac3a | 240 | p = sfr[0x22]; |
fmanga | 11:88c459b0ac3a | 241 | if(p>=0x83) |
fmanga | 11:88c459b0ac3a | 242 | p -= 0x83; |
fmanga | 11:88c459b0ac3a | 243 | b = (p>>6); |
fmanga | 11:88c459b0ac3a | 244 | p = (p&0x3f)*2; |
fmanga | 11:88c459b0ac3a | 245 | for(y=0; y<32; y++) { |
fmanga | 11:88c459b0ac3a | 246 | for(x=0; x<48; ) { |
fmanga | 11:88c459b0ac3a | 247 | int value = xram[b][p++]; |
fmanga | 11:88c459b0ac3a | 248 | if(!lcdon) |
fmanga | 11:88c459b0ac3a | 249 | value = 0; |
fmanga | 11:88c459b0ac3a | 250 | vmputpixel(x++, y, value>>7); |
fmanga | 11:88c459b0ac3a | 251 | vmputpixel(x++, y, value>>6); |
fmanga | 11:88c459b0ac3a | 252 | vmputpixel(x++, y, value>>5); |
fmanga | 11:88c459b0ac3a | 253 | vmputpixel(x++, y, value>>4); |
fmanga | 11:88c459b0ac3a | 254 | vmputpixel(x++, y, value>>3); |
fmanga | 11:88c459b0ac3a | 255 | vmputpixel(x++, y, value>>2); |
fmanga | 11:88c459b0ac3a | 256 | vmputpixel(x++, y, value>>1); |
fmanga | 11:88c459b0ac3a | 257 | vmputpixel(x++, y, value); |
fmanga | 11:88c459b0ac3a | 258 | if((p&0xf)>=12) |
fmanga | 11:88c459b0ac3a | 259 | p+=4; |
fmanga | 11:88c459b0ac3a | 260 | if(p>=128) { |
fmanga | 11:88c459b0ac3a | 261 | b++; |
fmanga | 11:88c459b0ac3a | 262 | p-=128; |
fmanga | 11:88c459b0ac3a | 263 | } |
fmanga | 11:88c459b0ac3a | 264 | if(b==2 && p>=6) { |
fmanga | 11:88c459b0ac3a | 265 | b = 0; |
fmanga | 11:88c459b0ac3a | 266 | p -= 6; |
fmanga | 11:88c459b0ac3a | 267 | } |
fmanga | 11:88c459b0ac3a | 268 | } |
fmanga | 11:88c459b0ac3a | 269 | } |
fmanga | 11:88c459b0ac3a | 270 | p++; |
fmanga | 11:88c459b0ac3a | 271 | if((p&0xf)>=12) |
fmanga | 11:88c459b0ac3a | 272 | p+=4; |
fmanga | 11:88c459b0ac3a | 273 | if(p>=128) { |
fmanga | 11:88c459b0ac3a | 274 | b++; |
fmanga | 11:88c459b0ac3a | 275 | p-=128; |
fmanga | 11:88c459b0ac3a | 276 | } |
fmanga | 11:88c459b0ac3a | 277 | if(b==2 && p>=6) { |
fmanga | 11:88c459b0ac3a | 278 | b = 0; |
fmanga | 11:88c459b0ac3a | 279 | p -= 6; |
fmanga | 11:88c459b0ac3a | 280 | } |
fmanga | 11:88c459b0ac3a | 281 | for(i=0; i<4; i++) { |
fmanga | 11:88c459b0ac3a | 282 | a = xram[b][p++]>>(2*(3-i)); |
fmanga | 11:88c459b0ac3a | 283 | if(!lcdon) |
fmanga | 11:88c459b0ac3a | 284 | a = 0; |
fmanga | 11:88c459b0ac3a | 285 | for(y=0; y<7; y++) { |
fmanga | 11:88c459b0ac3a | 286 | int value = icon[i][y]; |
fmanga | 11:88c459b0ac3a | 287 | for(x=0; x<7; x++) |
fmanga | 11:88c459b0ac3a | 288 | vmputpixel(2+i*12+x, y+33, (value>>(7-x))&a); |
fmanga | 11:88c459b0ac3a | 289 | } |
fmanga | 11:88c459b0ac3a | 290 | if((p&0xf)>=12) |
fmanga | 11:88c459b0ac3a | 291 | p+=4; |
fmanga | 11:88c459b0ac3a | 292 | if(p>=128) { |
fmanga | 11:88c459b0ac3a | 293 | b++; |
fmanga | 11:88c459b0ac3a | 294 | p-=128; |
fmanga | 11:88c459b0ac3a | 295 | } |
fmanga | 11:88c459b0ac3a | 296 | if(b==2 && p>=6) { |
fmanga | 11:88c459b0ac3a | 297 | b = 0; |
fmanga | 11:88c459b0ac3a | 298 | p -= 6; |
fmanga | 11:88c459b0ac3a | 299 | } |
fmanga | 11:88c459b0ac3a | 300 | } |
fmanga | 11:88c459b0ac3a | 301 | redrawlcd(); |
fmanga | 11:88c459b0ac3a | 302 | lcd_updated = 0; |
fmanga | 11:88c459b0ac3a | 303 | } |
fmanga | 11:88c459b0ac3a | 304 | |
fmanga | 11:88c459b0ac3a | 305 | void writemem(int addr, int value) |
fmanga | 11:88c459b0ac3a | 306 | { |
fmanga | 11:88c459b0ac3a | 307 | value &= 0xff; |
fmanga | 11:88c459b0ac3a | 308 | if(addr<0x100) { |
fmanga | 11:88c459b0ac3a | 309 | ram[(sfr[0x01]&2)>>1][addr] = value; |
fmanga | 11:88c459b0ac3a | 310 | return; |
fmanga | 11:88c459b0ac3a | 311 | } |
fmanga | 11:88c459b0ac3a | 312 | if(addr>=0x180) { |
fmanga | 11:88c459b0ac3a | 313 | int b = sfr[0x25]; |
fmanga | 11:88c459b0ac3a | 314 | if(b>2 || (b==2 && addr>=0x186)) |
fmanga | 11:88c459b0ac3a | 315 | return; |
fmanga | 11:88c459b0ac3a | 316 | xram[b][addr-0x180]=value; |
fmanga | 11:88c459b0ac3a | 317 | if(lcdon) |
fmanga | 11:88c459b0ac3a | 318 | lcd_updated = 1; |
fmanga | 11:88c459b0ac3a | 319 | } else switch(addr) { |
fmanga | 11:88c459b0ac3a | 320 | case 0x100: |
fmanga | 11:88c459b0ac3a | 321 | sfr[0x01] = (sfr[0x01]&0xfe)|parity[value]; |
fmanga | 11:88c459b0ac3a | 322 | break; |
fmanga | 11:88c459b0ac3a | 323 | case 0x10d: |
fmanga | 11:88c459b0ac3a | 324 | if((value&1) != (sfr[0x0d]&1)) { |
fmanga | 11:88c459b0ac3a | 325 | if(pc>0xfffd || rom[pc]!=0x21) |
fmanga | 11:88c459b0ac3a | 326 | error_msg("EXT 0 changed without following JMPF. pc = %04x", |
fmanga | 11:88c459b0ac3a | 327 | pc&0xffff); |
fmanga | 11:88c459b0ac3a | 328 | else |
fmanga | 11:88c459b0ac3a | 329 | pc = (rom[pc+1]<<8)|rom[pc+2]; |
fmanga | 11:88c459b0ac3a | 330 | // if(hasbios) |
fmanga | 11:88c459b0ac3a | 331 | // rom = ((value&1)? flash : bios); |
fmanga | 11:88c459b0ac3a | 332 | } |
fmanga | 11:88c459b0ac3a | 333 | break; |
fmanga | 11:88c459b0ac3a | 334 | case 0x10e: |
fmanga | 11:88c459b0ac3a | 335 | switch(value&0xa0) { |
fmanga | 11:88c459b0ac3a | 336 | case 0x00: spd = 3000; break; |
fmanga | 11:88c459b0ac3a | 337 | case 0x20: spd = 164; break; |
fmanga | 11:88c459b0ac3a | 338 | case 0x80: spd = 6000; break; |
fmanga | 11:88c459b0ac3a | 339 | case 0xa0: spd = 328; break; |
fmanga | 11:88c459b0ac3a | 340 | } |
fmanga | 11:88c459b0ac3a | 341 | break; |
fmanga | 11:88c459b0ac3a | 342 | case 0x110: |
fmanga | 11:88c459b0ac3a | 343 | if(!(value&0x40)) |
fmanga | 11:88c459b0ac3a | 344 | t0l = sfr[0x13]; |
fmanga | 11:88c459b0ac3a | 345 | if(!(value&0x80)) |
fmanga | 11:88c459b0ac3a | 346 | t0h = sfr[0x15]; |
fmanga | 11:88c459b0ac3a | 347 | break; |
fmanga | 11:88c459b0ac3a | 348 | case 0x111: |
fmanga | 11:88c459b0ac3a | 349 | t0scale = 256-value; |
fmanga | 11:88c459b0ac3a | 350 | t0base = 0; |
fmanga | 11:88c459b0ac3a | 351 | break; |
fmanga | 11:88c459b0ac3a | 352 | case 0x113: |
fmanga | 11:88c459b0ac3a | 353 | if(!(sfr[0x10]&0x40)) |
fmanga | 11:88c459b0ac3a | 354 | t0l = value; |
fmanga | 11:88c459b0ac3a | 355 | break; |
fmanga | 11:88c459b0ac3a | 356 | case 0x115: |
fmanga | 11:88c459b0ac3a | 357 | if(!(sfr[0x10]&0x80)) |
fmanga | 11:88c459b0ac3a | 358 | t0h = value; |
fmanga | 11:88c459b0ac3a | 359 | break; |
fmanga | 11:88c459b0ac3a | 360 | case 0x118: |
fmanga | 11:88c459b0ac3a | 361 | if(!(value&0x40)) |
fmanga | 11:88c459b0ac3a | 362 | t1l = sfr[0x1b]; |
fmanga | 11:88c459b0ac3a | 363 | if(!(value&0x80)) |
fmanga | 11:88c459b0ac3a | 364 | t1h = sfr[0x1d]; |
fmanga | 11:88c459b0ac3a | 365 | break; |
fmanga | 11:88c459b0ac3a | 366 | case 0x11b: |
fmanga | 11:88c459b0ac3a | 367 | if(!(sfr[0x18]&0x40)) |
fmanga | 11:88c459b0ac3a | 368 | t1l = value; |
fmanga | 11:88c459b0ac3a | 369 | break; |
fmanga | 11:88c459b0ac3a | 370 | case 0x11d: |
fmanga | 11:88c459b0ac3a | 371 | if(!(sfr[0x18]&0x80)) |
fmanga | 11:88c459b0ac3a | 372 | t1h = value; |
fmanga | 11:88c459b0ac3a | 373 | break; |
fmanga | 11:88c459b0ac3a | 374 | case 0x122: |
fmanga | 11:88c459b0ac3a | 375 | if(lcdon) |
fmanga | 11:88c459b0ac3a | 376 | lcd_updated = 1; |
fmanga | 11:88c459b0ac3a | 377 | break; |
fmanga | 11:88c459b0ac3a | 378 | case 0x127: |
fmanga | 11:88c459b0ac3a | 379 | if((!!(value&0x80)) != lcdon) { |
fmanga | 11:88c459b0ac3a | 380 | lcdon = !!(value&0x80); |
fmanga | 11:88c459b0ac3a | 381 | lcdrefresh(); |
fmanga | 11:88c459b0ac3a | 382 | } |
fmanga | 11:88c459b0ac3a | 383 | break; |
fmanga | 11:88c459b0ac3a | 384 | case 0x166: |
fmanga | 11:88c459b0ac3a | 385 | wram[0x1ff&((sfr[0x65]<<8)|sfr[0x64])] = value; |
fmanga | 11:88c459b0ac3a | 386 | if(sfr[0x63]&0x10) |
fmanga | 11:88c459b0ac3a | 387 | if(!++sfr[0x64]) |
fmanga | 11:88c459b0ac3a | 388 | sfr[0x65]^=1; |
fmanga | 11:88c459b0ac3a | 389 | return; |
fmanga | 11:88c459b0ac3a | 390 | } |
fmanga | 11:88c459b0ac3a | 391 | /* |
fmanga | 11:88c459b0ac3a | 392 | if(addr>0x10e && addr<0x120 && addr != 0x118) |
fmanga | 11:88c459b0ac3a | 393 | fprintf(stderr, "%04x: Write to %03x: %02x\n", pc, addr, value); |
fmanga | 11:88c459b0ac3a | 394 | */ |
fmanga | 11:88c459b0ac3a | 395 | sfr[addr&0xff] = value; |
fmanga | 11:88c459b0ac3a | 396 | if(addr == 0x118 || addr == 0x11b) { |
fmanga | 11:88c459b0ac3a | 397 | /* Check for sound... */ |
fmanga | 11:88c459b0ac3a | 398 | if(sfr[0x18]&0x40) |
fmanga | 11:88c459b0ac3a | 399 | sound(32768/((256-sfr[0x1b])*6)); |
fmanga | 11:88c459b0ac3a | 400 | else |
fmanga | 11:88c459b0ac3a | 401 | sound(-1); |
fmanga | 11:88c459b0ac3a | 402 | } |
fmanga | 11:88c459b0ac3a | 403 | } |
fmanga | 11:88c459b0ac3a | 404 | |
fmanga | 11:88c459b0ac3a | 405 | int readmem(int addr) |
fmanga | 11:88c459b0ac3a | 406 | { |
fmanga | 11:88c459b0ac3a | 407 | int r; |
fmanga | 11:88c459b0ac3a | 408 | if(addr<0x100) |
fmanga | 11:88c459b0ac3a | 409 | return ram[(sfr[0x01]&2)>>1][addr]; |
fmanga | 11:88c459b0ac3a | 410 | if(addr>=0x180) { |
fmanga | 11:88c459b0ac3a | 411 | int b = sfr[0x25]; |
fmanga | 11:88c459b0ac3a | 412 | if(b>2) |
fmanga | 11:88c459b0ac3a | 413 | return 0xff; |
fmanga | 11:88c459b0ac3a | 414 | return xram[b][addr-0x180]; |
fmanga | 11:88c459b0ac3a | 415 | } else switch(addr) { |
fmanga | 11:88c459b0ac3a | 416 | case 0x112: |
fmanga | 11:88c459b0ac3a | 417 | return t0l; |
fmanga | 11:88c459b0ac3a | 418 | case 0x114: |
fmanga | 11:88c459b0ac3a | 419 | return t0h; |
fmanga | 11:88c459b0ac3a | 420 | case 0x11b: |
fmanga | 11:88c459b0ac3a | 421 | return t1l; |
fmanga | 11:88c459b0ac3a | 422 | case 0x11d: |
fmanga | 11:88c459b0ac3a | 423 | return t1h; |
fmanga | 11:88c459b0ac3a | 424 | case 0x15c: |
fmanga | 11:88c459b0ac3a | 425 | return 2; |
fmanga | 11:88c459b0ac3a | 426 | case 0x165: |
fmanga | 11:88c459b0ac3a | 427 | return 0xfe|(sfr[0x65]&1); |
fmanga | 11:88c459b0ac3a | 428 | case 0x166: |
fmanga | 11:88c459b0ac3a | 429 | r = wram[0x1ff&((sfr[0x65]<<8)|sfr[0x64])]; |
fmanga | 11:88c459b0ac3a | 430 | if(sfr[0x63]&0x10) |
fmanga | 11:88c459b0ac3a | 431 | if(!++sfr[0x64]) |
fmanga | 11:88c459b0ac3a | 432 | sfr[0x65]^=1; |
fmanga | 11:88c459b0ac3a | 433 | return r; |
fmanga | 11:88c459b0ac3a | 434 | } |
fmanga | 11:88c459b0ac3a | 435 | /* |
fmanga | 11:88c459b0ac3a | 436 | if(addr>0x106 && addr<0x180) |
fmanga | 11:88c459b0ac3a | 437 | fprintf(stderr, "%04x: Read from %03x: %02x\n", pc, addr, sfr[addr&0xff]); |
fmanga | 11:88c459b0ac3a | 438 | */ |
fmanga | 11:88c459b0ac3a | 439 | return sfr[addr&0xff]; |
fmanga | 11:88c459b0ac3a | 440 | } |
fmanga | 11:88c459b0ac3a | 441 | |
fmanga | 11:88c459b0ac3a | 442 | int readlatch(int addr) |
fmanga | 11:88c459b0ac3a | 443 | { |
fmanga | 11:88c459b0ac3a | 444 | switch(addr) { |
fmanga | 11:88c459b0ac3a | 445 | case 0x11b: |
fmanga | 11:88c459b0ac3a | 446 | case 0x11d: |
fmanga | 11:88c459b0ac3a | 447 | return 0xff; |
fmanga | 11:88c459b0ac3a | 448 | default: |
fmanga | 11:88c459b0ac3a | 449 | return readmem(addr); |
fmanga | 11:88c459b0ac3a | 450 | } |
fmanga | 11:88c459b0ac3a | 451 | } |
fmanga | 11:88c459b0ac3a | 452 | |
fmanga | 11:88c459b0ac3a | 453 | void push(int n) |
fmanga | 11:88c459b0ac3a | 454 | { |
fmanga | 11:88c459b0ac3a | 455 | writemem(0x106, readmem(0x106)+1); |
fmanga | 11:88c459b0ac3a | 456 | ram[0][readmem(0x106)]=n; |
fmanga | 11:88c459b0ac3a | 457 | } |
fmanga | 11:88c459b0ac3a | 458 | |
fmanga | 11:88c459b0ac3a | 459 | int pop() |
fmanga | 11:88c459b0ac3a | 460 | { |
fmanga | 11:88c459b0ac3a | 461 | int r = ram[0][readmem(0x106)]; |
fmanga | 11:88c459b0ac3a | 462 | writemem(0x106, readmem(0x106)-1); |
fmanga | 11:88c459b0ac3a | 463 | return r; |
fmanga | 11:88c459b0ac3a | 464 | } |
fmanga | 11:88c459b0ac3a | 465 | |
fmanga | 11:88c459b0ac3a | 466 | void resetcpu() |
fmanga | 11:88c459b0ac3a | 467 | { |
fmanga | 11:88c459b0ac3a | 468 | int i; |
fmanga | 11:88c459b0ac3a | 469 | time_t t = time(NULL); |
fmanga | 11:88c459b0ac3a | 470 | struct tm *tm = localtime(&t); |
fmanga | 11:88c459b0ac3a | 471 | memset(ram, 0, sizeof(ram)); |
fmanga | 11:88c459b0ac3a | 472 | memset(xram, 0, sizeof(xram)); |
fmanga | 11:88c459b0ac3a | 473 | memset(wram, 0, sizeof(wram)); |
fmanga | 11:88c459b0ac3a | 474 | memset(sfr, 0, sizeof(sfr)); |
fmanga | 11:88c459b0ac3a | 475 | parity[0] = 0; |
fmanga | 11:88c459b0ac3a | 476 | parity[1] = 1; |
fmanga | 11:88c459b0ac3a | 477 | parity[2] = 1; |
fmanga | 11:88c459b0ac3a | 478 | parity[3] = 0; |
fmanga | 11:88c459b0ac3a | 479 | for(i=4; i<16; i++) |
fmanga | 11:88c459b0ac3a | 480 | parity[i] = parity[i&3]^parity[i>>2]; |
fmanga | 11:88c459b0ac3a | 481 | for(i=16; i<255; i++) |
fmanga | 11:88c459b0ac3a | 482 | parity[i] = parity[i&15]^parity[i>>4]; |
fmanga | 11:88c459b0ac3a | 483 | sfr[0x06] = 0x7f; |
fmanga | 11:88c459b0ac3a | 484 | sfr[0x4c] = 0xff; |
fmanga | 11:88c459b0ac3a | 485 | sfr[0x01] = 0x02; |
fmanga | 11:88c459b0ac3a | 486 | t0h = t0l = 0; |
fmanga | 11:88c459b0ac3a | 487 | t1h = t1l = 0; |
fmanga | 11:88c459b0ac3a | 488 | t0base = 0; |
fmanga | 11:88c459b0ac3a | 489 | t0scale = 256; |
fmanga | 11:88c459b0ac3a | 490 | ram[0][0x10] = tobcd(tm->tm_year/100+19); |
fmanga | 11:88c459b0ac3a | 491 | ram[0][0x11] = tobcd(tm->tm_year%100); |
fmanga | 11:88c459b0ac3a | 492 | ram[0][0x12] = tobcd(tm->tm_mon+1); |
fmanga | 11:88c459b0ac3a | 493 | ram[0][0x13] = tobcd(tm->tm_mday); |
fmanga | 11:88c459b0ac3a | 494 | ram[0][0x14] = tobcd(tm->tm_hour); |
fmanga | 11:88c459b0ac3a | 495 | ram[0][0x15] = tobcd(tm->tm_min); |
fmanga | 11:88c459b0ac3a | 496 | ram[0][0x17] = (tm->tm_year+1900)>>8; |
fmanga | 11:88c459b0ac3a | 497 | ram[0][0x18] = (tm->tm_year+1900)&0xff; |
fmanga | 11:88c459b0ac3a | 498 | ram[0][0x19] = tm->tm_mon+1; |
fmanga | 11:88c459b0ac3a | 499 | ram[0][0x1a] = tm->tm_mday; |
fmanga | 11:88c459b0ac3a | 500 | ram[0][0x1b] = tm->tm_hour; |
fmanga | 11:88c459b0ac3a | 501 | ram[0][0x1c] = tm->tm_min; |
fmanga | 11:88c459b0ac3a | 502 | ram[0][0x1d] = tm->tm_sec; |
fmanga | 11:88c459b0ac3a | 503 | ram[0][0x31] = 0xff; |
fmanga | 11:88c459b0ac3a | 504 | sfr[0x08] = 0x80; |
fmanga | 11:88c459b0ac3a | 505 | writemem(0x10e, 0x81); |
fmanga | 11:88c459b0ac3a | 506 | lcd_updated = 0; |
fmanga | 11:88c459b0ac3a | 507 | lcdon = 0; |
fmanga | 11:88c459b0ac3a | 508 | imask = 0; |
fmanga | 11:88c459b0ac3a | 509 | intreq = 0; |
fmanga | 11:88c459b0ac3a | 510 | if(hasbios) { |
fmanga | 11:88c459b0ac3a | 511 | sfr[0x0d] = 0; |
fmanga | 11:88c459b0ac3a | 512 | rom = bios; |
fmanga | 11:88c459b0ac3a | 513 | pc = 0x1f0; |
fmanga | 11:88c459b0ac3a | 514 | } else { |
fmanga | 11:88c459b0ac3a | 515 | sfr[0x0d] = 1; |
fmanga | 11:88c459b0ac3a | 516 | rom = flash; |
fmanga | 11:88c459b0ac3a | 517 | pc = 0; |
fmanga | 11:88c459b0ac3a | 518 | writemem(0x125, 2); |
fmanga | 11:88c459b0ac3a | 519 | writemem(0x182, 0x10); |
fmanga | 11:88c459b0ac3a | 520 | writemem(0x125, 0); |
fmanga | 11:88c459b0ac3a | 521 | writemem(0x127, 0x80); |
fmanga | 11:88c459b0ac3a | 522 | } |
fmanga | 11:88c459b0ac3a | 523 | sound(-1); |
fmanga | 11:88c459b0ac3a | 524 | } |
fmanga | 11:88c459b0ac3a | 525 | |
fmanga | 11:88c459b0ac3a | 526 | int month_days() |
fmanga | 11:88c459b0ac3a | 527 | { |
fmanga | 11:88c459b0ac3a | 528 | int m = ram[0][0x19]; |
fmanga | 11:88c459b0ac3a | 529 | if(m==2) { |
fmanga | 11:88c459b0ac3a | 530 | int y = ram[0][0x18] | (ram[0][0x17] << 8); |
fmanga | 11:88c459b0ac3a | 531 | if(y&3) |
fmanga | 11:88c459b0ac3a | 532 | return 28; |
fmanga | 11:88c459b0ac3a | 533 | if(!(y%4000)) |
fmanga | 11:88c459b0ac3a | 534 | return 29; |
fmanga | 11:88c459b0ac3a | 535 | if(!(y%1000)) |
fmanga | 11:88c459b0ac3a | 536 | return 28; |
fmanga | 11:88c459b0ac3a | 537 | if(!(y%400)) |
fmanga | 11:88c459b0ac3a | 538 | return 29; |
fmanga | 11:88c459b0ac3a | 539 | if(!(y%100)) |
fmanga | 11:88c459b0ac3a | 540 | return 28; |
fmanga | 11:88c459b0ac3a | 541 | return 29; |
fmanga | 11:88c459b0ac3a | 542 | } else return (m>7? ((m&1)? 30:31) : ((m&1)? 31:30)); |
fmanga | 11:88c459b0ac3a | 543 | } |
fmanga | 11:88c459b0ac3a | 544 | |
fmanga | 11:88c459b0ac3a | 545 | int handle_fwcall(int pc) |
fmanga | 11:88c459b0ac3a | 546 | { |
fmanga | 11:88c459b0ac3a | 547 | switch(pc) { |
fmanga | 11:88c459b0ac3a | 548 | case 0x100: |
fmanga | 11:88c459b0ac3a | 549 | { |
fmanga | 11:88c459b0ac3a | 550 | // int i, a = ((ram[1][0x7d]<<16)|(ram[1][0x7e]<<8)|ram[1][0x7f])&0x1ffff; |
fmanga | 11:88c459b0ac3a | 551 | // if(a>=gamesize) |
fmanga | 11:88c459b0ac3a | 552 | // writemem(0x100, 0xff); |
fmanga | 11:88c459b0ac3a | 553 | // else { |
fmanga | 11:88c459b0ac3a | 554 | // writemem(0x100, 0x00); |
fmanga | 11:88c459b0ac3a | 555 | //for(i=0; i<0x80; i++) |
fmanga | 11:88c459b0ac3a | 556 | // flash[(a&~0xff)|((a+i)&0xff)] = ram[1][i+0x80]; |
fmanga | 11:88c459b0ac3a | 557 | //#ifdef __DC__ |
fmanga | 11:88c459b0ac3a | 558 | //if(!flash_written(a)) |
fmanga | 11:88c459b0ac3a | 559 | writemem(0x100, 0xff); |
fmanga | 11:88c459b0ac3a | 560 | //#endif |
fmanga | 11:88c459b0ac3a | 561 | // } |
fmanga | 11:88c459b0ac3a | 562 | /* |
fmanga | 11:88c459b0ac3a | 563 | fprintf(stderr, "ROM write @ %05x:\n", a); |
fmanga | 11:88c459b0ac3a | 564 | for(i=0; i<0x80; i++) |
fmanga | 11:88c459b0ac3a | 565 | fprintf(stderr, " %02x", ram[1][i+0x80]); |
fmanga | 11:88c459b0ac3a | 566 | fprintf(stderr, "\n"); |
fmanga | 11:88c459b0ac3a | 567 | */ |
fmanga | 11:88c459b0ac3a | 568 | } |
fmanga | 11:88c459b0ac3a | 569 | return 0x105; |
fmanga | 11:88c459b0ac3a | 570 | case 0x110: |
fmanga | 11:88c459b0ac3a | 571 | { |
fmanga | 11:88c459b0ac3a | 572 | int i, a = ((ram[1][0x7d]<<16)|(ram[1][0x7e]<<8)|ram[1][0x7f])&0x1ffff; |
fmanga | 11:88c459b0ac3a | 573 | int r = 0; |
fmanga | 11:88c459b0ac3a | 574 | for(i=0; i<0x80; i++) |
fmanga | 11:88c459b0ac3a | 575 | if((r = (flash[(a&~0xff)|((a+i)&0xff)] ^ ram[1][i+0x80])) != 0) |
fmanga | 11:88c459b0ac3a | 576 | break; |
fmanga | 11:88c459b0ac3a | 577 | writemem(0x100, r); |
fmanga | 11:88c459b0ac3a | 578 | } |
fmanga | 11:88c459b0ac3a | 579 | return 0x115; |
fmanga | 11:88c459b0ac3a | 580 | case 0x120: |
fmanga | 11:88c459b0ac3a | 581 | { |
fmanga | 11:88c459b0ac3a | 582 | int i, a = ((ram[1][0x7d]<<16)|(ram[1][0x7e]<<8)|ram[1][0x7f])&0x1ffff; |
fmanga | 11:88c459b0ac3a | 583 | for(i=0; i<0x80; i++) |
fmanga | 11:88c459b0ac3a | 584 | ram[1][i+0x80] = flash[(a&~0xff)|((a+i)&0xff)]; |
fmanga | 11:88c459b0ac3a | 585 | /* |
fmanga | 11:88c459b0ac3a | 586 | fprintf(stderr, "ROM read @ %05x\n", a); |
fmanga | 11:88c459b0ac3a | 587 | */ |
fmanga | 11:88c459b0ac3a | 588 | } |
fmanga | 11:88c459b0ac3a | 589 | return 0x125; |
fmanga | 11:88c459b0ac3a | 590 | case 0x130: |
fmanga | 11:88c459b0ac3a | 591 | if(!((ram[0][0x1e]^=1)&1)) |
fmanga | 11:88c459b0ac3a | 592 | if(++ram[0][0x1d]>=60) { |
fmanga | 11:88c459b0ac3a | 593 | ram[0][0x1d] = 0; |
fmanga | 11:88c459b0ac3a | 594 | if(++ram[0][0x1c]>=60) { |
fmanga | 11:88c459b0ac3a | 595 | ram[0][0x1c] = 0; |
fmanga | 11:88c459b0ac3a | 596 | if(++ram[0][0x1b]>=24) { |
fmanga | 11:88c459b0ac3a | 597 | ram[0][0x1b] = 0; |
fmanga | 11:88c459b0ac3a | 598 | if(++ram[0][0x1a]>month_days()) { |
fmanga | 11:88c459b0ac3a | 599 | ram[0][0x1a] = 1; |
fmanga | 11:88c459b0ac3a | 600 | if(++ram[0][0x19]>=13) { |
fmanga | 11:88c459b0ac3a | 601 | ram[0][0x19] = 1; |
fmanga | 11:88c459b0ac3a | 602 | if(ram[0][0x18]==0xff) { |
fmanga | 11:88c459b0ac3a | 603 | ram[0][0x18]=0; |
fmanga | 11:88c459b0ac3a | 604 | ram[0][0x17]++; |
fmanga | 11:88c459b0ac3a | 605 | } else |
fmanga | 11:88c459b0ac3a | 606 | ram[0][0x18]++; |
fmanga | 11:88c459b0ac3a | 607 | } |
fmanga | 11:88c459b0ac3a | 608 | } |
fmanga | 11:88c459b0ac3a | 609 | } |
fmanga | 11:88c459b0ac3a | 610 | } |
fmanga | 11:88c459b0ac3a | 611 | } |
fmanga | 11:88c459b0ac3a | 612 | return 0x139; |
fmanga | 11:88c459b0ac3a | 613 | case 0x1f0: |
fmanga | 11:88c459b0ac3a | 614 | return 0; |
fmanga | 11:88c459b0ac3a | 615 | default: |
fmanga | 11:88c459b0ac3a | 616 | error_msg("Firmware entered at unknown vector %04x!", pc); |
fmanga | 11:88c459b0ac3a | 617 | return 0; |
fmanga | 11:88c459b0ac3a | 618 | } |
fmanga | 11:88c459b0ac3a | 619 | } |
fmanga | 11:88c459b0ac3a | 620 | |
fmanga | 11:88c459b0ac3a | 621 | void run_cpu( void ) |
fmanga | 11:88c459b0ac3a | 622 | { |
fmanga | 11:88c459b0ac3a | 623 | struct timeval epoch; |
fmanga | 11:88c459b0ac3a | 624 | int mcy = 0, tick = 0; |
fmanga | 11:88c459b0ac3a | 625 | |
fmanga | 11:88c459b0ac3a | 626 | GETTIMEOFDAY(&epoch); |
fmanga | 11:88c459b0ac3a | 627 | for(;;) { |
fmanga | 11:88c459b0ac3a | 628 | int r, s, c, cy = 1, i = rom[pc]; |
fmanga | 11:88c459b0ac3a | 629 | #ifdef TRACE |
fmanga | 11:88c459b0ac3a | 630 | printf("%04x\n", pc); |
fmanga | 11:88c459b0ac3a | 631 | #endif |
fmanga | 11:88c459b0ac3a | 632 | pc++; |
fmanga | 11:88c459b0ac3a | 633 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 634 | switch(i&0xf) { |
fmanga | 11:88c459b0ac3a | 635 | case 0: |
fmanga | 11:88c459b0ac3a | 636 | switch(i>>4) { |
fmanga | 11:88c459b0ac3a | 637 | case 0: |
fmanga | 11:88c459b0ac3a | 638 | break; |
fmanga | 11:88c459b0ac3a | 639 | case 1: |
fmanga | 11:88c459b0ac3a | 640 | cy = 4; |
fmanga | 11:88c459b0ac3a | 641 | push((pc+2)&0xff); |
fmanga | 11:88c459b0ac3a | 642 | push(((pc+2)&0xff00)>>8); |
fmanga | 11:88c459b0ac3a | 643 | pc = 0xffff&(pc+1+rom[pc]+((rom[(pc+1)&0xffff])<<8)); |
fmanga | 11:88c459b0ac3a | 644 | break; |
fmanga | 11:88c459b0ac3a | 645 | case 2: |
fmanga | 11:88c459b0ac3a | 646 | cy = 2; |
fmanga | 11:88c459b0ac3a | 647 | push((pc+2)&0xff); |
fmanga | 11:88c459b0ac3a | 648 | push(((pc+2)&0xff00)>>8); |
fmanga | 11:88c459b0ac3a | 649 | pc = (rom[pc]<<8)|rom[(pc+1)&0xffff]; |
fmanga | 11:88c459b0ac3a | 650 | break; |
fmanga | 11:88c459b0ac3a | 651 | case 3: |
fmanga | 11:88c459b0ac3a | 652 | cy = 7; |
fmanga | 11:88c459b0ac3a | 653 | r = readmem(0x102)*((readmem(0x100)<<8)|readmem(0x103)); |
fmanga | 11:88c459b0ac3a | 654 | writemem(0x101, (readmem(0x101)&0x7b)|(r>65535? 4:0)); |
fmanga | 11:88c459b0ac3a | 655 | writemem(0x103, r&0xff); |
fmanga | 11:88c459b0ac3a | 656 | writemem(0x100, (r&0xff00)>>8); |
fmanga | 11:88c459b0ac3a | 657 | writemem(0x102, (r&0xff0000)>>16); |
fmanga | 11:88c459b0ac3a | 658 | break; |
fmanga | 11:88c459b0ac3a | 659 | case 4: |
fmanga | 11:88c459b0ac3a | 660 | cy = 7; |
fmanga | 11:88c459b0ac3a | 661 | r = readmem(0x102); |
fmanga | 11:88c459b0ac3a | 662 | if(r) { |
fmanga | 11:88c459b0ac3a | 663 | int v = (readmem(0x100)<<8)|readmem(0x103); |
fmanga | 11:88c459b0ac3a | 664 | s = v%r; |
fmanga | 11:88c459b0ac3a | 665 | r = v/r; |
fmanga | 11:88c459b0ac3a | 666 | } else { |
fmanga | 11:88c459b0ac3a | 667 | r = 0xff00|readmem(0x103); |
fmanga | 11:88c459b0ac3a | 668 | s = 0; |
fmanga | 11:88c459b0ac3a | 669 | } |
fmanga | 11:88c459b0ac3a | 670 | writemem(0x101, (readmem(0x101)&0x7b)|(s? 0:4)); |
fmanga | 11:88c459b0ac3a | 671 | writemem(0x103, r&0xff); |
fmanga | 11:88c459b0ac3a | 672 | writemem(0x100, (r&0xff00)>>8); |
fmanga | 11:88c459b0ac3a | 673 | writemem(0x102, s); |
fmanga | 11:88c459b0ac3a | 674 | break; |
fmanga | 11:88c459b0ac3a | 675 | case 5: |
fmanga | 11:88c459b0ac3a | 676 | cy = 2; /* ? */ |
fmanga | 11:88c459b0ac3a | 677 | writemem(0x100, flash[0x1ffff&(readmem(0x104)+(readmem(0x105)<<8)+ |
fmanga | 11:88c459b0ac3a | 678 | (readmem(0x154)<<16))]); |
fmanga | 11:88c459b0ac3a | 679 | break; |
fmanga | 11:88c459b0ac3a | 680 | case 6: |
fmanga | 11:88c459b0ac3a | 681 | cy = 2; |
fmanga | 11:88c459b0ac3a | 682 | push(readmem(rom[pc++])); |
fmanga | 11:88c459b0ac3a | 683 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 684 | break; |
fmanga | 11:88c459b0ac3a | 685 | case 7: |
fmanga | 11:88c459b0ac3a | 686 | cy = 2; |
fmanga | 11:88c459b0ac3a | 687 | writemem(rom[pc++], pop()); |
fmanga | 11:88c459b0ac3a | 688 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 689 | break; |
fmanga | 11:88c459b0ac3a | 690 | case 8: |
fmanga | 11:88c459b0ac3a | 691 | cy = 2; |
fmanga | 11:88c459b0ac3a | 692 | if(readmem(0x100)==0) |
fmanga | 11:88c459b0ac3a | 693 | pc = 0xffff&(pc+1+SGNEXT(rom[pc])); |
fmanga | 11:88c459b0ac3a | 694 | else { |
fmanga | 11:88c459b0ac3a | 695 | pc++; |
fmanga | 11:88c459b0ac3a | 696 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 697 | } |
fmanga | 11:88c459b0ac3a | 698 | break; |
fmanga | 11:88c459b0ac3a | 699 | case 9: |
fmanga | 11:88c459b0ac3a | 700 | cy = 2; |
fmanga | 11:88c459b0ac3a | 701 | if(readmem(0x100)!=0) |
fmanga | 11:88c459b0ac3a | 702 | pc = 0xffff&(pc+1+SGNEXT(rom[pc])); |
fmanga | 11:88c459b0ac3a | 703 | else { |
fmanga | 11:88c459b0ac3a | 704 | pc++; |
fmanga | 11:88c459b0ac3a | 705 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 706 | } |
fmanga | 11:88c459b0ac3a | 707 | break; |
fmanga | 11:88c459b0ac3a | 708 | case 0xa: |
fmanga | 11:88c459b0ac3a | 709 | cy = 2; |
fmanga | 11:88c459b0ac3a | 710 | r = pop()<<8; |
fmanga | 11:88c459b0ac3a | 711 | r |= pop(); |
fmanga | 11:88c459b0ac3a | 712 | pc = r; |
fmanga | 11:88c459b0ac3a | 713 | break; |
fmanga | 11:88c459b0ac3a | 714 | case 0xb: |
fmanga | 11:88c459b0ac3a | 715 | cy = 2; |
fmanga | 11:88c459b0ac3a | 716 | r = pop()<<8; |
fmanga | 11:88c459b0ac3a | 717 | r |= pop(); |
fmanga | 11:88c459b0ac3a | 718 | pc = r; |
fmanga | 11:88c459b0ac3a | 719 | --imask; |
fmanga | 11:88c459b0ac3a | 720 | break; |
fmanga | 11:88c459b0ac3a | 721 | case 0xc: |
fmanga | 11:88c459b0ac3a | 722 | r = readmem(0x100); |
fmanga | 11:88c459b0ac3a | 723 | writemem(0x100, (r>>1)|((r&1)<<7)); |
fmanga | 11:88c459b0ac3a | 724 | break; |
fmanga | 11:88c459b0ac3a | 725 | case 0xd: |
fmanga | 11:88c459b0ac3a | 726 | r = readmem(0x100); |
fmanga | 11:88c459b0ac3a | 727 | s = readmem(0x101); |
fmanga | 11:88c459b0ac3a | 728 | writemem(0x101, (s&0x7f)|((r&1)<<7)); |
fmanga | 11:88c459b0ac3a | 729 | writemem(0x100, (r>>1)|(s&0x80)); |
fmanga | 11:88c459b0ac3a | 730 | break; |
fmanga | 11:88c459b0ac3a | 731 | case 0xe: |
fmanga | 11:88c459b0ac3a | 732 | r = readmem(0x100); |
fmanga | 11:88c459b0ac3a | 733 | writemem(0x100, (r<<1)|((r&0x80)>>7)); |
fmanga | 11:88c459b0ac3a | 734 | break; |
fmanga | 11:88c459b0ac3a | 735 | case 0xf: |
fmanga | 11:88c459b0ac3a | 736 | r = readmem(0x100); |
fmanga | 11:88c459b0ac3a | 737 | s = readmem(0x101); |
fmanga | 11:88c459b0ac3a | 738 | writemem(0x101, (s&0x7f)|(r&0x80)); |
fmanga | 11:88c459b0ac3a | 739 | writemem(0x100, (r<<1)|((s&0x80)>>7)); |
fmanga | 11:88c459b0ac3a | 740 | break; |
fmanga | 11:88c459b0ac3a | 741 | } |
fmanga | 11:88c459b0ac3a | 742 | break; |
fmanga | 11:88c459b0ac3a | 743 | case 1: |
fmanga | 11:88c459b0ac3a | 744 | switch(i>>4) { |
fmanga | 11:88c459b0ac3a | 745 | case 0: |
fmanga | 11:88c459b0ac3a | 746 | cy = 2; |
fmanga | 11:88c459b0ac3a | 747 | pc = 0xffff&(pc+1+SGNEXT(rom[pc])); |
fmanga | 11:88c459b0ac3a | 748 | break; |
fmanga | 11:88c459b0ac3a | 749 | case 1: |
fmanga | 11:88c459b0ac3a | 750 | cy = 4; |
fmanga | 11:88c459b0ac3a | 751 | pc = 0xffff&(pc+1+rom[pc]+((rom[(pc+1)&0xffff])<<8)); |
fmanga | 11:88c459b0ac3a | 752 | break; |
fmanga | 11:88c459b0ac3a | 753 | case 2: |
fmanga | 11:88c459b0ac3a | 754 | cy = 2; |
fmanga | 11:88c459b0ac3a | 755 | pc = (rom[pc]<<8)|rom[(pc+1)&0xffff]; |
fmanga | 11:88c459b0ac3a | 756 | break; |
fmanga | 11:88c459b0ac3a | 757 | case 3: |
fmanga | 11:88c459b0ac3a | 758 | cy = 2; |
fmanga | 11:88c459b0ac3a | 759 | r = readmem(0x100); |
fmanga | 11:88c459b0ac3a | 760 | writemem(0x101, (readmem(0x101)&0x7f)|(r<rom[pc]? 0x80:0)); |
fmanga | 11:88c459b0ac3a | 761 | s = (r == rom[pc++]); |
fmanga | 11:88c459b0ac3a | 762 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 763 | if(s) |
fmanga | 11:88c459b0ac3a | 764 | pc = 0xffff&(pc+1+SGNEXT(rom[pc])); |
fmanga | 11:88c459b0ac3a | 765 | else { |
fmanga | 11:88c459b0ac3a | 766 | pc++; |
fmanga | 11:88c459b0ac3a | 767 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 768 | } |
fmanga | 11:88c459b0ac3a | 769 | break; |
fmanga | 11:88c459b0ac3a | 770 | case 4: |
fmanga | 11:88c459b0ac3a | 771 | cy = 2; |
fmanga | 11:88c459b0ac3a | 772 | r = readmem(0x100); |
fmanga | 11:88c459b0ac3a | 773 | writemem(0x101, (readmem(0x101)&0x7f)|(r<rom[pc]? 0x80:0)); |
fmanga | 11:88c459b0ac3a | 774 | s = (r != rom[pc++]); |
fmanga | 11:88c459b0ac3a | 775 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 776 | if(s) |
fmanga | 11:88c459b0ac3a | 777 | pc = 0xffff&(pc+1+SGNEXT(rom[pc])); |
fmanga | 11:88c459b0ac3a | 778 | else { |
fmanga | 11:88c459b0ac3a | 779 | pc++; |
fmanga | 11:88c459b0ac3a | 780 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 781 | } |
fmanga | 11:88c459b0ac3a | 782 | break; |
fmanga | 11:88c459b0ac3a | 783 | case 5: |
fmanga | 11:88c459b0ac3a | 784 | cy = 2; /* ? * / |
fmanga | 11:88c459b0ac3a | 785 | if(!(readmem(0x154)&2)) |
fmanga | 11:88c459b0ac3a | 786 | flash[0x1ffff&(readmem(0x104)+(readmem(0x105)<<8)+ |
fmanga | 11:88c459b0ac3a | 787 | (readmem(0x154)<<16))] = readmem(0x100); |
fmanga | 11:88c459b0ac3a | 788 | /* */ |
fmanga | 11:88c459b0ac3a | 789 | break; |
fmanga | 11:88c459b0ac3a | 790 | case 6: |
fmanga | 11:88c459b0ac3a | 791 | cy = 2; |
fmanga | 11:88c459b0ac3a | 792 | push(readmem(0x100|rom[pc++])); |
fmanga | 11:88c459b0ac3a | 793 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 794 | break; |
fmanga | 11:88c459b0ac3a | 795 | case 7: |
fmanga | 11:88c459b0ac3a | 796 | cy = 2; |
fmanga | 11:88c459b0ac3a | 797 | writemem(0x100|rom[pc++], pop()); |
fmanga | 11:88c459b0ac3a | 798 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 799 | break; |
fmanga | 11:88c459b0ac3a | 800 | case 8: |
fmanga | 11:88c459b0ac3a | 801 | r = readmem(0x100); |
fmanga | 11:88c459b0ac3a | 802 | s = rom[pc++]; |
fmanga | 11:88c459b0ac3a | 803 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 804 | writemem(0x100, r+s); |
fmanga | 11:88c459b0ac3a | 805 | writemem(0x101, (readmem(0x101)&0x3b)|(r+s>255? 0x80:0)| |
fmanga | 11:88c459b0ac3a | 806 | ((r&15)+(s&15)>15? 0x40:0)|((0x80&(~r^s)&(s^(r+s)))? 4:0)); |
fmanga | 11:88c459b0ac3a | 807 | break; |
fmanga | 11:88c459b0ac3a | 808 | case 9: |
fmanga | 11:88c459b0ac3a | 809 | r = readmem(0x100); |
fmanga | 11:88c459b0ac3a | 810 | s = rom[pc++]; |
fmanga | 11:88c459b0ac3a | 811 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 812 | c = (readmem(0x101)&0x80)>>7; |
fmanga | 11:88c459b0ac3a | 813 | writemem(0x100, r+s+c); |
fmanga | 11:88c459b0ac3a | 814 | writemem(0x101, (readmem(0x101)&0x3b)|(r+s+c>255? 0x80:0)| |
fmanga | 11:88c459b0ac3a | 815 | ((r&15)+(s&15)+c>15? 0x40:0)| |
fmanga | 11:88c459b0ac3a | 816 | ((0x80&(~r^s)&(s^(r+s+c)))? 4:0)); |
fmanga | 11:88c459b0ac3a | 817 | break; |
fmanga | 11:88c459b0ac3a | 818 | case 0xa: |
fmanga | 11:88c459b0ac3a | 819 | /* FIXME: OV */ |
fmanga | 11:88c459b0ac3a | 820 | r = readmem(0x100); |
fmanga | 11:88c459b0ac3a | 821 | s = rom[pc++]; |
fmanga | 11:88c459b0ac3a | 822 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 823 | writemem(0x100, r-s); |
fmanga | 11:88c459b0ac3a | 824 | writemem(0x101, (readmem(0x101)&0x3b)|(r-s<0? 0x80:0)| |
fmanga | 11:88c459b0ac3a | 825 | ((r&15)-(s&15)<0? 0x40:0)|(0? 4:0)); |
fmanga | 11:88c459b0ac3a | 826 | break; |
fmanga | 11:88c459b0ac3a | 827 | case 0xb: |
fmanga | 11:88c459b0ac3a | 828 | /* FIXME: OV */ |
fmanga | 11:88c459b0ac3a | 829 | r = readmem(0x100); |
fmanga | 11:88c459b0ac3a | 830 | s = rom[pc++]; |
fmanga | 11:88c459b0ac3a | 831 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 832 | c = (readmem(0x101)&0x80)>>7; |
fmanga | 11:88c459b0ac3a | 833 | writemem(0x100, r-s-c); |
fmanga | 11:88c459b0ac3a | 834 | writemem(0x101, (readmem(0x101)&0x3b)|(r-s-c<0? 0x80:0)| |
fmanga | 11:88c459b0ac3a | 835 | ((r&15)-(s&15)-c<0? 0x40:0)|(0? 4:0)); |
fmanga | 11:88c459b0ac3a | 836 | break; |
fmanga | 11:88c459b0ac3a | 837 | case 0xc: |
fmanga | 11:88c459b0ac3a | 838 | cy = 2; |
fmanga | 11:88c459b0ac3a | 839 | writemem(0x100, rom[0xffff&(readmem(0x100)+readmem(0x104)+ |
fmanga | 11:88c459b0ac3a | 840 | (readmem(0x105)<<8))]); |
fmanga | 11:88c459b0ac3a | 841 | break; |
fmanga | 11:88c459b0ac3a | 842 | case 0xd: |
fmanga | 11:88c459b0ac3a | 843 | writemem(0x100, readmem(0x100)|rom[pc++]); |
fmanga | 11:88c459b0ac3a | 844 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 845 | break; |
fmanga | 11:88c459b0ac3a | 846 | case 0xe: |
fmanga | 11:88c459b0ac3a | 847 | writemem(0x100, readmem(0x100)&rom[pc++]); |
fmanga | 11:88c459b0ac3a | 848 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 849 | break; |
fmanga | 11:88c459b0ac3a | 850 | case 0xf: |
fmanga | 11:88c459b0ac3a | 851 | writemem(0x100, readmem(0x100)^rom[pc++]); |
fmanga | 11:88c459b0ac3a | 852 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 853 | break; |
fmanga | 11:88c459b0ac3a | 854 | } |
fmanga | 11:88c459b0ac3a | 855 | break; |
fmanga | 11:88c459b0ac3a | 856 | case 2: |
fmanga | 11:88c459b0ac3a | 857 | case 3: |
fmanga | 11:88c459b0ac3a | 858 | r = ((i&1)<<8)|rom[pc++]; |
fmanga | 11:88c459b0ac3a | 859 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 860 | switch(i>>4) { |
fmanga | 11:88c459b0ac3a | 861 | case 0: |
fmanga | 11:88c459b0ac3a | 862 | writemem(0x100, readmem(r)); |
fmanga | 11:88c459b0ac3a | 863 | break; |
fmanga | 11:88c459b0ac3a | 864 | case 1: |
fmanga | 11:88c459b0ac3a | 865 | writemem(r, readmem(0x100)); |
fmanga | 11:88c459b0ac3a | 866 | break; |
fmanga | 11:88c459b0ac3a | 867 | case 2: |
fmanga | 11:88c459b0ac3a | 868 | cy = 2; |
fmanga | 11:88c459b0ac3a | 869 | writemem(r, rom[pc++]); |
fmanga | 11:88c459b0ac3a | 870 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 871 | break; |
fmanga | 11:88c459b0ac3a | 872 | case 3: |
fmanga | 11:88c459b0ac3a | 873 | cy = 2; |
fmanga | 11:88c459b0ac3a | 874 | s = readmem(r); |
fmanga | 11:88c459b0ac3a | 875 | r = readmem(0x100); |
fmanga | 11:88c459b0ac3a | 876 | writemem(0x101, (readmem(0x101)&0x7f)|(r<s? 0x80:0)); |
fmanga | 11:88c459b0ac3a | 877 | if(r == s) |
fmanga | 11:88c459b0ac3a | 878 | pc = 0xffff&(pc+1+SGNEXT(rom[pc])); |
fmanga | 11:88c459b0ac3a | 879 | else { |
fmanga | 11:88c459b0ac3a | 880 | pc++; |
fmanga | 11:88c459b0ac3a | 881 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 882 | } |
fmanga | 11:88c459b0ac3a | 883 | break; |
fmanga | 11:88c459b0ac3a | 884 | case 4: |
fmanga | 11:88c459b0ac3a | 885 | cy = 2; |
fmanga | 11:88c459b0ac3a | 886 | s = readmem(r); |
fmanga | 11:88c459b0ac3a | 887 | r = readmem(0x100); |
fmanga | 11:88c459b0ac3a | 888 | writemem(0x101, (readmem(0x101)&0x7f)|(r<s? 0x80:0)); |
fmanga | 11:88c459b0ac3a | 889 | if(r != s) |
fmanga | 11:88c459b0ac3a | 890 | pc = 0xffff&(pc+1+SGNEXT(rom[pc])); |
fmanga | 11:88c459b0ac3a | 891 | else { |
fmanga | 11:88c459b0ac3a | 892 | pc++; |
fmanga | 11:88c459b0ac3a | 893 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 894 | } |
fmanga | 11:88c459b0ac3a | 895 | break; |
fmanga | 11:88c459b0ac3a | 896 | case 5: |
fmanga | 11:88c459b0ac3a | 897 | cy = 2; |
fmanga | 11:88c459b0ac3a | 898 | s = (readlatch(r)-1)&0xff; |
fmanga | 11:88c459b0ac3a | 899 | writemem(r, s); |
fmanga | 11:88c459b0ac3a | 900 | if(s != 0) |
fmanga | 11:88c459b0ac3a | 901 | pc = 0xffff&(pc+1+SGNEXT(rom[pc])); |
fmanga | 11:88c459b0ac3a | 902 | else { |
fmanga | 11:88c459b0ac3a | 903 | pc++; |
fmanga | 11:88c459b0ac3a | 904 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 905 | } |
fmanga | 11:88c459b0ac3a | 906 | break; |
fmanga | 11:88c459b0ac3a | 907 | case 6: |
fmanga | 11:88c459b0ac3a | 908 | writemem(r, readlatch(r)+1); |
fmanga | 11:88c459b0ac3a | 909 | break; |
fmanga | 11:88c459b0ac3a | 910 | case 7: |
fmanga | 11:88c459b0ac3a | 911 | writemem(r, readlatch(r)-1); |
fmanga | 11:88c459b0ac3a | 912 | break; |
fmanga | 11:88c459b0ac3a | 913 | case 8: |
fmanga | 11:88c459b0ac3a | 914 | s = readmem(r); |
fmanga | 11:88c459b0ac3a | 915 | r = readmem(0x100); |
fmanga | 11:88c459b0ac3a | 916 | writemem(0x100, r+s); |
fmanga | 11:88c459b0ac3a | 917 | writemem(0x101, (readmem(0x101)&0x3b)|(r+s>255? 0x80:0)| |
fmanga | 11:88c459b0ac3a | 918 | ((r&15)+(s&15)>15? 0x40:0)|((0x80&(~r^s)&(s^(r+s)))? 4:0)); |
fmanga | 11:88c459b0ac3a | 919 | break; |
fmanga | 11:88c459b0ac3a | 920 | case 9: |
fmanga | 11:88c459b0ac3a | 921 | s = readmem(r); |
fmanga | 11:88c459b0ac3a | 922 | r = readmem(0x100); |
fmanga | 11:88c459b0ac3a | 923 | c = (readmem(0x101)&0x80)>>7; |
fmanga | 11:88c459b0ac3a | 924 | writemem(0x100, r+s+c); |
fmanga | 11:88c459b0ac3a | 925 | writemem(0x101, (readmem(0x101)&0x3b)|(r+s+c>255? 0x80:0)| |
fmanga | 11:88c459b0ac3a | 926 | ((r&15)+(s&15)+c>15? 0x40:0)| |
fmanga | 11:88c459b0ac3a | 927 | ((0x80&(~r^s)&(s^(r+s+c)))? 4:0)); |
fmanga | 11:88c459b0ac3a | 928 | break; |
fmanga | 11:88c459b0ac3a | 929 | case 0xa: |
fmanga | 11:88c459b0ac3a | 930 | /* FIXME: OV */ |
fmanga | 11:88c459b0ac3a | 931 | s = readmem(r); |
fmanga | 11:88c459b0ac3a | 932 | r = readmem(0x100); |
fmanga | 11:88c459b0ac3a | 933 | writemem(0x100, r-s); |
fmanga | 11:88c459b0ac3a | 934 | writemem(0x101, (readmem(0x101)&0x3b)|(r-s<0? 0x80:0)| |
fmanga | 11:88c459b0ac3a | 935 | ((r&15)-(s&15)<0? 0x40:0)|(0? 4:0)); |
fmanga | 11:88c459b0ac3a | 936 | break; |
fmanga | 11:88c459b0ac3a | 937 | case 0xb: |
fmanga | 11:88c459b0ac3a | 938 | /* FIXME: OV */ |
fmanga | 11:88c459b0ac3a | 939 | s = readmem(r); |
fmanga | 11:88c459b0ac3a | 940 | r = readmem(0x100); |
fmanga | 11:88c459b0ac3a | 941 | c = (readmem(0x101)&0x80)>>7; |
fmanga | 11:88c459b0ac3a | 942 | writemem(0x100, r-s-c); |
fmanga | 11:88c459b0ac3a | 943 | writemem(0x101, (readmem(0x101)&0x3b)|(r-s-c<0? 0x80:0)| |
fmanga | 11:88c459b0ac3a | 944 | ((r&15)-(s&15)-c<0? 0x40:0)|(0? 4:0)); |
fmanga | 11:88c459b0ac3a | 945 | break; |
fmanga | 11:88c459b0ac3a | 946 | case 0xc: |
fmanga | 11:88c459b0ac3a | 947 | s = readmem(r); |
fmanga | 11:88c459b0ac3a | 948 | writemem(r, readmem(0x100)); |
fmanga | 11:88c459b0ac3a | 949 | writemem(0x100, s); |
fmanga | 11:88c459b0ac3a | 950 | break; |
fmanga | 11:88c459b0ac3a | 951 | case 0xd: |
fmanga | 11:88c459b0ac3a | 952 | writemem(0x100, readmem(0x100)|readmem(r)); |
fmanga | 11:88c459b0ac3a | 953 | break; |
fmanga | 11:88c459b0ac3a | 954 | case 0xe: |
fmanga | 11:88c459b0ac3a | 955 | writemem(0x100, readmem(0x100)&readmem(r)); |
fmanga | 11:88c459b0ac3a | 956 | break; |
fmanga | 11:88c459b0ac3a | 957 | case 0xf: |
fmanga | 11:88c459b0ac3a | 958 | writemem(0x100, readmem(0x100)^readmem(r)); |
fmanga | 11:88c459b0ac3a | 959 | break; |
fmanga | 11:88c459b0ac3a | 960 | } |
fmanga | 11:88c459b0ac3a | 961 | break; |
fmanga | 11:88c459b0ac3a | 962 | case 4: |
fmanga | 11:88c459b0ac3a | 963 | case 5: |
fmanga | 11:88c459b0ac3a | 964 | case 6: |
fmanga | 11:88c459b0ac3a | 965 | case 7: |
fmanga | 11:88c459b0ac3a | 966 | r = readmem((i&3)|((readmem(0x101)>>1)&0xc))|((i&2)? 0x100 : 0); |
fmanga | 11:88c459b0ac3a | 967 | switch(i>>4) { |
fmanga | 11:88c459b0ac3a | 968 | case 0: |
fmanga | 11:88c459b0ac3a | 969 | writemem(0x100, readmem(r)); |
fmanga | 11:88c459b0ac3a | 970 | break; |
fmanga | 11:88c459b0ac3a | 971 | case 1: |
fmanga | 11:88c459b0ac3a | 972 | writemem(r, readmem(0x100)); |
fmanga | 11:88c459b0ac3a | 973 | break; |
fmanga | 11:88c459b0ac3a | 974 | case 2: |
fmanga | 11:88c459b0ac3a | 975 | writemem(r, rom[pc++]); |
fmanga | 11:88c459b0ac3a | 976 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 977 | break; |
fmanga | 11:88c459b0ac3a | 978 | case 3: |
fmanga | 11:88c459b0ac3a | 979 | cy = 2; |
fmanga | 11:88c459b0ac3a | 980 | s = readmem(r); |
fmanga | 11:88c459b0ac3a | 981 | r = rom[pc++]; |
fmanga | 11:88c459b0ac3a | 982 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 983 | writemem(0x101, (readmem(0x101)&0x7f)|(s<r? 0x80:0)); |
fmanga | 11:88c459b0ac3a | 984 | if(r == s) |
fmanga | 11:88c459b0ac3a | 985 | pc = 0xffff&(pc+1+SGNEXT(rom[pc])); |
fmanga | 11:88c459b0ac3a | 986 | else { |
fmanga | 11:88c459b0ac3a | 987 | pc++; |
fmanga | 11:88c459b0ac3a | 988 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 989 | } |
fmanga | 11:88c459b0ac3a | 990 | break; |
fmanga | 11:88c459b0ac3a | 991 | case 4: |
fmanga | 11:88c459b0ac3a | 992 | cy = 2; |
fmanga | 11:88c459b0ac3a | 993 | s = readmem(r); |
fmanga | 11:88c459b0ac3a | 994 | r = rom[pc++]; |
fmanga | 11:88c459b0ac3a | 995 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 996 | writemem(0x101, (readmem(0x101)&0x7f)|(s<r? 0x80:0)); |
fmanga | 11:88c459b0ac3a | 997 | if(r != s) |
fmanga | 11:88c459b0ac3a | 998 | pc = 0xffff&(pc+1+SGNEXT(rom[pc])); |
fmanga | 11:88c459b0ac3a | 999 | else { |
fmanga | 11:88c459b0ac3a | 1000 | pc++; |
fmanga | 11:88c459b0ac3a | 1001 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 1002 | } |
fmanga | 11:88c459b0ac3a | 1003 | break; |
fmanga | 11:88c459b0ac3a | 1004 | case 5: |
fmanga | 11:88c459b0ac3a | 1005 | cy = 2; |
fmanga | 11:88c459b0ac3a | 1006 | s = (readlatch(r)-1)&0xff; |
fmanga | 11:88c459b0ac3a | 1007 | writemem(r, s); |
fmanga | 11:88c459b0ac3a | 1008 | if(s != 0) |
fmanga | 11:88c459b0ac3a | 1009 | pc = 0xffff&(pc+1+SGNEXT(rom[pc])); |
fmanga | 11:88c459b0ac3a | 1010 | else { |
fmanga | 11:88c459b0ac3a | 1011 | pc++; |
fmanga | 11:88c459b0ac3a | 1012 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 1013 | } |
fmanga | 11:88c459b0ac3a | 1014 | break; |
fmanga | 11:88c459b0ac3a | 1015 | case 6: |
fmanga | 11:88c459b0ac3a | 1016 | writemem(r, readlatch(r)+1); |
fmanga | 11:88c459b0ac3a | 1017 | break; |
fmanga | 11:88c459b0ac3a | 1018 | case 7: |
fmanga | 11:88c459b0ac3a | 1019 | writemem(r, readlatch(r)-1); |
fmanga | 11:88c459b0ac3a | 1020 | break; |
fmanga | 11:88c459b0ac3a | 1021 | case 8: |
fmanga | 11:88c459b0ac3a | 1022 | s = readmem(r); |
fmanga | 11:88c459b0ac3a | 1023 | r = readmem(0x100); |
fmanga | 11:88c459b0ac3a | 1024 | writemem(0x100, r+s); |
fmanga | 11:88c459b0ac3a | 1025 | writemem(0x101, (readmem(0x101)&0x3b)|(r+s>255? 0x80:0)| |
fmanga | 11:88c459b0ac3a | 1026 | ((r&15)+(s&15)>15? 0x40:0)|((0x80&(~r^s)&(s^(r+s)))? 4:0)); |
fmanga | 11:88c459b0ac3a | 1027 | break; |
fmanga | 11:88c459b0ac3a | 1028 | case 9: |
fmanga | 11:88c459b0ac3a | 1029 | s = readmem(r); |
fmanga | 11:88c459b0ac3a | 1030 | r = readmem(0x100); |
fmanga | 11:88c459b0ac3a | 1031 | c = (readmem(0x101)&0x80)>>7; |
fmanga | 11:88c459b0ac3a | 1032 | writemem(0x100, r+s+c); |
fmanga | 11:88c459b0ac3a | 1033 | writemem(0x101, (readmem(0x101)&0x3b)|(r+s+c>255? 0x80:0)| |
fmanga | 11:88c459b0ac3a | 1034 | ((r&15)+(s&15)+c>15? 0x40:0)| |
fmanga | 11:88c459b0ac3a | 1035 | ((0x80&(~r^s)&(s^(r+s+c)))? 4:0)); |
fmanga | 11:88c459b0ac3a | 1036 | break; |
fmanga | 11:88c459b0ac3a | 1037 | case 0xa: |
fmanga | 11:88c459b0ac3a | 1038 | /* FIXME: OV */ |
fmanga | 11:88c459b0ac3a | 1039 | s = readmem(r); |
fmanga | 11:88c459b0ac3a | 1040 | r = readmem(0x100); |
fmanga | 11:88c459b0ac3a | 1041 | writemem(0x100, r-s); |
fmanga | 11:88c459b0ac3a | 1042 | writemem(0x101, (readmem(0x101)&0x3b)|(r-s<0? 0x80:0)| |
fmanga | 11:88c459b0ac3a | 1043 | ((r&15)-(s&15)<0? 0x40:0)|(0? 4:0)); |
fmanga | 11:88c459b0ac3a | 1044 | break; |
fmanga | 11:88c459b0ac3a | 1045 | case 0xb: |
fmanga | 11:88c459b0ac3a | 1046 | /* FIXME: OV */ |
fmanga | 11:88c459b0ac3a | 1047 | s = readmem(r); |
fmanga | 11:88c459b0ac3a | 1048 | r = readmem(0x100); |
fmanga | 11:88c459b0ac3a | 1049 | c = (readmem(0x101)&0x80)>>7; |
fmanga | 11:88c459b0ac3a | 1050 | writemem(0x100, r-s-c); |
fmanga | 11:88c459b0ac3a | 1051 | writemem(0x101, (readmem(0x101)&0x3b)|(r-s-c<0? 0x80:0)| |
fmanga | 11:88c459b0ac3a | 1052 | ((r&15)-(s&15)-c<0? 0x40:0)|(0? 4:0)); |
fmanga | 11:88c459b0ac3a | 1053 | break; |
fmanga | 11:88c459b0ac3a | 1054 | case 0xc: |
fmanga | 11:88c459b0ac3a | 1055 | s = readmem(r); |
fmanga | 11:88c459b0ac3a | 1056 | writemem(r, readmem(0x100)); |
fmanga | 11:88c459b0ac3a | 1057 | writemem(0x100, s); |
fmanga | 11:88c459b0ac3a | 1058 | break; |
fmanga | 11:88c459b0ac3a | 1059 | case 0xd: |
fmanga | 11:88c459b0ac3a | 1060 | writemem(0x100, readmem(0x100)|readmem(r)); |
fmanga | 11:88c459b0ac3a | 1061 | break; |
fmanga | 11:88c459b0ac3a | 1062 | case 0xe: |
fmanga | 11:88c459b0ac3a | 1063 | writemem(0x100, readmem(0x100)&readmem(r)); |
fmanga | 11:88c459b0ac3a | 1064 | break; |
fmanga | 11:88c459b0ac3a | 1065 | case 0xf: |
fmanga | 11:88c459b0ac3a | 1066 | writemem(0x100, readmem(0x100)^readmem(r)); |
fmanga | 11:88c459b0ac3a | 1067 | break; |
fmanga | 11:88c459b0ac3a | 1068 | } |
fmanga | 11:88c459b0ac3a | 1069 | break; |
fmanga | 11:88c459b0ac3a | 1070 | default: |
fmanga | 11:88c459b0ac3a | 1071 | switch(i&0xe0) { |
fmanga | 11:88c459b0ac3a | 1072 | case 0x00: |
fmanga | 11:88c459b0ac3a | 1073 | cy = 2; |
fmanga | 11:88c459b0ac3a | 1074 | r = ((i&7)<<8)|((i&0x10)<<7)|rom[pc++]; |
fmanga | 11:88c459b0ac3a | 1075 | push(pc&0xff); |
fmanga | 11:88c459b0ac3a | 1076 | push((pc&0xff00)>>8); |
fmanga | 11:88c459b0ac3a | 1077 | pc = (pc&0xf000)|r; |
fmanga | 11:88c459b0ac3a | 1078 | break; |
fmanga | 11:88c459b0ac3a | 1079 | case 0x20: |
fmanga | 11:88c459b0ac3a | 1080 | cy = 2; |
fmanga | 11:88c459b0ac3a | 1081 | r = ((i&7)<<8)|((i&0x10)<<7)|rom[pc++]; |
fmanga | 11:88c459b0ac3a | 1082 | pc = (pc&0xf000)|r; |
fmanga | 11:88c459b0ac3a | 1083 | break; |
fmanga | 11:88c459b0ac3a | 1084 | case 0x40: |
fmanga | 11:88c459b0ac3a | 1085 | cy = 2; |
fmanga | 11:88c459b0ac3a | 1086 | r = ((i&0x10)<<4)|rom[pc++]; |
fmanga | 11:88c459b0ac3a | 1087 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 1088 | if((s=readmem(r))&(1<<(i&7))) { |
fmanga | 11:88c459b0ac3a | 1089 | writemem(r, s & ~(1<<(i&7))); |
fmanga | 11:88c459b0ac3a | 1090 | pc = 0xffff&(pc+1+SGNEXT(rom[pc])); |
fmanga | 11:88c459b0ac3a | 1091 | } else { |
fmanga | 11:88c459b0ac3a | 1092 | pc++; |
fmanga | 11:88c459b0ac3a | 1093 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 1094 | } |
fmanga | 11:88c459b0ac3a | 1095 | break; |
fmanga | 11:88c459b0ac3a | 1096 | case 0x60: |
fmanga | 11:88c459b0ac3a | 1097 | cy = 2; |
fmanga | 11:88c459b0ac3a | 1098 | r = ((i&0x10)<<4)|rom[pc++]; |
fmanga | 11:88c459b0ac3a | 1099 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 1100 | if(readmem(r)&(1<<(i&7))) |
fmanga | 11:88c459b0ac3a | 1101 | pc = 0xffff&(pc+1+SGNEXT(rom[pc])); |
fmanga | 11:88c459b0ac3a | 1102 | else { |
fmanga | 11:88c459b0ac3a | 1103 | pc++; |
fmanga | 11:88c459b0ac3a | 1104 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 1105 | } |
fmanga | 11:88c459b0ac3a | 1106 | break; |
fmanga | 11:88c459b0ac3a | 1107 | case 0x80: |
fmanga | 11:88c459b0ac3a | 1108 | cy = 2; |
fmanga | 11:88c459b0ac3a | 1109 | r = ((i&0x10)<<4)|rom[pc++]; |
fmanga | 11:88c459b0ac3a | 1110 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 1111 | if(!(readmem(r)&(1<<(i&7)))) |
fmanga | 11:88c459b0ac3a | 1112 | pc = 0xffff&(pc+1+SGNEXT(rom[pc])); |
fmanga | 11:88c459b0ac3a | 1113 | else { |
fmanga | 11:88c459b0ac3a | 1114 | pc++; |
fmanga | 11:88c459b0ac3a | 1115 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 1116 | } |
fmanga | 11:88c459b0ac3a | 1117 | break; |
fmanga | 11:88c459b0ac3a | 1118 | case 0xa0: |
fmanga | 11:88c459b0ac3a | 1119 | r = ((i&0x10)<<4)|rom[pc++]; |
fmanga | 11:88c459b0ac3a | 1120 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 1121 | writemem(r, readlatch(r) ^ (1<<(i&7))); |
fmanga | 11:88c459b0ac3a | 1122 | break; |
fmanga | 11:88c459b0ac3a | 1123 | case 0xc0: |
fmanga | 11:88c459b0ac3a | 1124 | r = ((i&0x10)<<4)|rom[pc++]; |
fmanga | 11:88c459b0ac3a | 1125 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 1126 | writemem(r, readlatch(r) & ~(1<<(i&7))); |
fmanga | 11:88c459b0ac3a | 1127 | break; |
fmanga | 11:88c459b0ac3a | 1128 | case 0xe0: |
fmanga | 11:88c459b0ac3a | 1129 | r = ((i&0x10)<<4)|rom[pc++]; |
fmanga | 11:88c459b0ac3a | 1130 | pc &= 0xffff; |
fmanga | 11:88c459b0ac3a | 1131 | writemem(r, readlatch(r) | (1<<(i&7))); |
fmanga | 11:88c459b0ac3a | 1132 | break; |
fmanga | 11:88c459b0ac3a | 1133 | } |
fmanga | 11:88c459b0ac3a | 1134 | break; |
fmanga | 11:88c459b0ac3a | 1135 | } |
fmanga | 11:88c459b0ac3a | 1136 | mcy += cy; |
fmanga | 11:88c459b0ac3a | 1137 | if(mcy>=spd) { |
fmanga | 11:88c459b0ac3a | 1138 | struct timeval now, t; |
fmanga | 11:88c459b0ac3a | 1139 | if(lcd_updated) |
fmanga | 11:88c459b0ac3a | 1140 | lcdrefresh(); |
fmanga | 11:88c459b0ac3a | 1141 | GETTIMEOFDAY(&now); |
fmanga | 11:88c459b0ac3a | 1142 | if((epoch.tv_usec += 10000)>=1000000) { |
fmanga | 11:88c459b0ac3a | 1143 | epoch.tv_usec -= 1000000; |
fmanga | 11:88c459b0ac3a | 1144 | epoch.tv_sec++; |
fmanga | 11:88c459b0ac3a | 1145 | } |
fmanga | 11:88c459b0ac3a | 1146 | if(now.tv_sec>epoch.tv_sec || |
fmanga | 11:88c459b0ac3a | 1147 | (now.tv_sec == epoch.tv_sec && now.tv_usec >= epoch.tv_usec)) { |
fmanga | 11:88c459b0ac3a | 1148 | t.tv_usec = 0; |
fmanga | 11:88c459b0ac3a | 1149 | t.tv_sec = 0; |
fmanga | 11:88c459b0ac3a | 1150 | } else if(epoch.tv_usec<now.tv_usec) { |
fmanga | 11:88c459b0ac3a | 1151 | t.tv_usec = 1000000 + epoch.tv_usec - now.tv_usec; |
fmanga | 11:88c459b0ac3a | 1152 | t.tv_sec = epoch.tv_sec - now.tv_sec - 1; |
fmanga | 11:88c459b0ac3a | 1153 | } else { |
fmanga | 11:88c459b0ac3a | 1154 | t.tv_usec = epoch.tv_usec - now.tv_usec; |
fmanga | 11:88c459b0ac3a | 1155 | t.tv_sec = epoch.tv_sec - now.tv_sec; |
fmanga | 11:88c459b0ac3a | 1156 | } |
fmanga | 11:88c459b0ac3a | 1157 | waitforevents(&t); |
fmanga | 11:88c459b0ac3a | 1158 | checkevents(); |
fmanga | 11:88c459b0ac3a | 1159 | mcy -= spd; |
fmanga | 11:88c459b0ac3a | 1160 | ++tick; |
fmanga | 11:88c459b0ac3a | 1161 | if(tick>=50) { |
fmanga | 11:88c459b0ac3a | 1162 | intreq |= 1<<3; |
fmanga | 11:88c459b0ac3a | 1163 | tick -= 50; |
fmanga | 11:88c459b0ac3a | 1164 | } |
fmanga | 11:88c459b0ac3a | 1165 | } |
fmanga | 11:88c459b0ac3a | 1166 | /* Timer 0 */ |
fmanga | 11:88c459b0ac3a | 1167 | if(sfr[0x10] & 0xc0) { |
fmanga | 11:88c459b0ac3a | 1168 | int c0=0; |
fmanga | 11:88c459b0ac3a | 1169 | if((t0base+=cy) >= t0scale) |
fmanga | 11:88c459b0ac3a | 1170 | do |
fmanga | 11:88c459b0ac3a | 1171 | c0++; |
fmanga | 11:88c459b0ac3a | 1172 | while((t0base-=t0scale) >= t0scale); |
fmanga | 11:88c459b0ac3a | 1173 | if(c0) |
fmanga | 11:88c459b0ac3a | 1174 | if((sfr[0x10] & 0xe0) == 0xe0) { |
fmanga | 11:88c459b0ac3a | 1175 | t0l += c0; |
fmanga | 11:88c459b0ac3a | 1176 | if(t0l>=256) { |
fmanga | 11:88c459b0ac3a | 1177 | t0l -= 256; |
fmanga | 11:88c459b0ac3a | 1178 | if(++t0h >= 256) { |
fmanga | 11:88c459b0ac3a | 1179 | t0h -= 256; |
fmanga | 11:88c459b0ac3a | 1180 | if((t0l += sfr[0x13])>=256) { |
fmanga | 11:88c459b0ac3a | 1181 | t0l -= 256; |
fmanga | 11:88c459b0ac3a | 1182 | if((t0h += sfr[0x15])>=256) { |
fmanga | 11:88c459b0ac3a | 1183 | t0l = sfr[0x13]; |
fmanga | 11:88c459b0ac3a | 1184 | t0h = sfr[0x15]; |
fmanga | 11:88c459b0ac3a | 1185 | } |
fmanga | 11:88c459b0ac3a | 1186 | } |
fmanga | 11:88c459b0ac3a | 1187 | sfr[0x10] |= 10; |
fmanga | 11:88c459b0ac3a | 1188 | if(sfr[0x10]&4) |
fmanga | 11:88c459b0ac3a | 1189 | intreq |= 1<<4; |
fmanga | 11:88c459b0ac3a | 1190 | } |
fmanga | 11:88c459b0ac3a | 1191 | } |
fmanga | 11:88c459b0ac3a | 1192 | } else { |
fmanga | 11:88c459b0ac3a | 1193 | if(sfr[0x10] & 0x40) { |
fmanga | 11:88c459b0ac3a | 1194 | t0l += c0; |
fmanga | 11:88c459b0ac3a | 1195 | if(t0l>=256) { |
fmanga | 11:88c459b0ac3a | 1196 | t0l -= 256; |
fmanga | 11:88c459b0ac3a | 1197 | if((t0l += sfr[0x13])>=256) |
fmanga | 11:88c459b0ac3a | 1198 | t0l = sfr[0x13]; |
fmanga | 11:88c459b0ac3a | 1199 | sfr[0x10] |= 2; |
fmanga | 11:88c459b0ac3a | 1200 | if(sfr[0x10]&1) |
fmanga | 11:88c459b0ac3a | 1201 | intreq |= 1<<2; |
fmanga | 11:88c459b0ac3a | 1202 | } |
fmanga | 11:88c459b0ac3a | 1203 | } |
fmanga | 11:88c459b0ac3a | 1204 | if(sfr[0x10] & 0x80) { |
fmanga | 11:88c459b0ac3a | 1205 | t0h += c0; |
fmanga | 11:88c459b0ac3a | 1206 | if(t0h>=256) { |
fmanga | 11:88c459b0ac3a | 1207 | t0h -= 256; |
fmanga | 11:88c459b0ac3a | 1208 | if((t0h += sfr[0x15])>=256) |
fmanga | 11:88c459b0ac3a | 1209 | t0h = sfr[0x15]; |
fmanga | 11:88c459b0ac3a | 1210 | sfr[0x10] |= 8; |
fmanga | 11:88c459b0ac3a | 1211 | if(sfr[0x10]&4) |
fmanga | 11:88c459b0ac3a | 1212 | intreq |= 1<<4; |
fmanga | 11:88c459b0ac3a | 1213 | } |
fmanga | 11:88c459b0ac3a | 1214 | } |
fmanga | 11:88c459b0ac3a | 1215 | } |
fmanga | 11:88c459b0ac3a | 1216 | } |
fmanga | 11:88c459b0ac3a | 1217 | /* Timer 1 */ |
fmanga | 11:88c459b0ac3a | 1218 | if(sfr[0x18] & 0xc0) { |
fmanga | 11:88c459b0ac3a | 1219 | if((sfr[0x18] & 0xe0) == 0xe0) { |
fmanga | 11:88c459b0ac3a | 1220 | t1l += cy; |
fmanga | 11:88c459b0ac3a | 1221 | if(t1l>=256) { |
fmanga | 11:88c459b0ac3a | 1222 | t1l -= 256; |
fmanga | 11:88c459b0ac3a | 1223 | if(++t1h >= 256) { |
fmanga | 11:88c459b0ac3a | 1224 | t1h -= 256; |
fmanga | 11:88c459b0ac3a | 1225 | if((t1l += sfr[0x1b])>=256) { |
fmanga | 11:88c459b0ac3a | 1226 | t1l -= 256; |
fmanga | 11:88c459b0ac3a | 1227 | if((t1h += sfr[0x1d])>=256) { |
fmanga | 11:88c459b0ac3a | 1228 | t1l = sfr[0x1b]; |
fmanga | 11:88c459b0ac3a | 1229 | t1h = sfr[0x1d]; |
fmanga | 11:88c459b0ac3a | 1230 | } |
fmanga | 11:88c459b0ac3a | 1231 | } |
fmanga | 11:88c459b0ac3a | 1232 | sfr[0x18] |= 10; |
fmanga | 11:88c459b0ac3a | 1233 | if(sfr[0x18]&4) |
fmanga | 11:88c459b0ac3a | 1234 | intreq |= 1<<5; |
fmanga | 11:88c459b0ac3a | 1235 | } |
fmanga | 11:88c459b0ac3a | 1236 | } |
fmanga | 11:88c459b0ac3a | 1237 | } else { |
fmanga | 11:88c459b0ac3a | 1238 | if(sfr[0x18] & 0x40) { |
fmanga | 11:88c459b0ac3a | 1239 | t1l += cy; |
fmanga | 11:88c459b0ac3a | 1240 | if(t1l>=256) { |
fmanga | 11:88c459b0ac3a | 1241 | t1l -= 256; |
fmanga | 11:88c459b0ac3a | 1242 | if((t1l += sfr[0x1b])>=256) |
fmanga | 11:88c459b0ac3a | 1243 | t1l = sfr[0x1b]; |
fmanga | 11:88c459b0ac3a | 1244 | sfr[0x18] |= 2; |
fmanga | 11:88c459b0ac3a | 1245 | if(sfr[0x18]&1) |
fmanga | 11:88c459b0ac3a | 1246 | intreq |= 1<<5; |
fmanga | 11:88c459b0ac3a | 1247 | } |
fmanga | 11:88c459b0ac3a | 1248 | } |
fmanga | 11:88c459b0ac3a | 1249 | if(sfr[0x18] & 0x80) { |
fmanga | 11:88c459b0ac3a | 1250 | t1h += cy; |
fmanga | 11:88c459b0ac3a | 1251 | if(t1h>=256) { |
fmanga | 11:88c459b0ac3a | 1252 | t1h -= 256; |
fmanga | 11:88c459b0ac3a | 1253 | if((t1h += sfr[0x1d])>=256) |
fmanga | 11:88c459b0ac3a | 1254 | t1h = sfr[0x1d]; |
fmanga | 11:88c459b0ac3a | 1255 | sfr[0x18] |= 8; |
fmanga | 11:88c459b0ac3a | 1256 | if(sfr[0x18]&4) |
fmanga | 11:88c459b0ac3a | 1257 | intreq |= 1<<5; |
fmanga | 11:88c459b0ac3a | 1258 | } |
fmanga | 11:88c459b0ac3a | 1259 | } |
fmanga | 11:88c459b0ac3a | 1260 | } |
fmanga | 11:88c459b0ac3a | 1261 | } |
fmanga | 11:88c459b0ac3a | 1262 | if(!(sfr[0x0d]&1) && !hasbios) |
fmanga | 11:88c459b0ac3a | 1263 | if(!(pc=handle_fwcall(pc))) |
fmanga | 11:88c459b0ac3a | 1264 | break; |
fmanga | 11:88c459b0ac3a | 1265 | else |
fmanga | 11:88c459b0ac3a | 1266 | sfr[0x0d]|=1; |
fmanga | 11:88c459b0ac3a | 1267 | |
fmanga | 11:88c459b0ac3a | 1268 | if((sfr[0x4e]&3)==3 && !imask) |
fmanga | 11:88c459b0ac3a | 1269 | intreq |= 1<<9; |
fmanga | 11:88c459b0ac3a | 1270 | |
fmanga | 11:88c459b0ac3a | 1271 | if(!intreq || imask || !(sfr[0x08]&0x80)) |
fmanga | 11:88c459b0ac3a | 1272 | continue; |
fmanga | 11:88c459b0ac3a | 1273 | for(r=0; r<10; r++) |
fmanga | 11:88c459b0ac3a | 1274 | if(intreq & (1<<r)) |
fmanga | 11:88c459b0ac3a | 1275 | break; |
fmanga | 11:88c459b0ac3a | 1276 | intreq &= ~(1<<r); |
fmanga | 11:88c459b0ac3a | 1277 | push(pc&0xff); |
fmanga | 11:88c459b0ac3a | 1278 | push((pc&0xff00)>>8); |
fmanga | 11:88c459b0ac3a | 1279 | imask++; |
fmanga | 11:88c459b0ac3a | 1280 | pc = ((r&~1)<<3)+((r&1)?0xb:0x3); |
fmanga | 11:88c459b0ac3a | 1281 | } |
fmanga | 11:88c459b0ac3a | 1282 | } |
fmanga | 11:88c459b0ac3a | 1283 | |
fmanga | 11:88c459b0ac3a | 1284 | /* |
fmanga | 11:88c459b0ac3a | 1285 | int do_vmsgame(char *filename, char *biosname) |
fmanga | 11:88c459b0ac3a | 1286 | { |
fmanga | 11:88c459b0ac3a | 1287 | if(filename == NULL && biosname == NULL) |
fmanga | 11:88c459b0ac3a | 1288 | return 0; |
fmanga | 11:88c459b0ac3a | 1289 | if(biosname != NULL) |
fmanga | 11:88c459b0ac3a | 1290 | if(!loadbios(biosname)) |
fmanga | 11:88c459b0ac3a | 1291 | return 0; |
fmanga | 11:88c459b0ac3a | 1292 | if(filename != NULL) |
fmanga | 11:88c459b0ac3a | 1293 | if(!loadflash(filename)) |
fmanga | 11:88c459b0ac3a | 1294 | return 0; |
fmanga | 11:88c459b0ac3a | 1295 | resetcpu(); |
fmanga | 11:88c459b0ac3a | 1296 | run_cpu(); |
fmanga | 11:88c459b0ac3a | 1297 | return 1; |
fmanga | 11:88c459b0ac3a | 1298 | } |
fmanga | 11:88c459b0ac3a | 1299 | */ |