Marcus Comstedt's SoftVMS ported to Pokitto.

Dependencies:   PokittoLib

Fork of HelloWorld by Pokitto Community Team

Committer:
fmanga
Date:
Sat Mar 31 19:07:59 2018 +0000
Revision:
11:88c459b0ac3a
Initial SoftVMS port

Who changed what in which revision?

UserRevisionLine numberNew 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 */