00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00101 #include "StdAfx.h"
00102 #include "DPR.h"
00103 #include "System.h"
00104 #include "Serial.h"
00105 #include <time.h>
00106 #include "AlphaCPU.h"
00107
00108 #define ToBCD(x) (((x) / 10 << 4) | ((x) % 10))
00109
00110 extern CSerial* srl[2];
00111
00115 CDPR::CDPR(CConfigurator* cfg, CSystem* c) : CSystemComponent(cfg, c)
00116 {
00117 if(theDPR)
00118 FAILURE(Configuration, "More than one DPR");
00119 theDPR = this;
00120
00121 c->RegisterMemory(this, 0, U64(0x0000080110000000), 0x100000);
00122 }
00123
00127 void CDPR::init()
00128 {
00129 int i;
00130
00131 memset(&state, 0, sizeof(state));
00132 RestoreStateF();
00133
00134 for(i = 0; i < cSystem->get_cpu_num(); i++)
00135 {
00136 state.ram[i * 0x20 + 0x00] = 1;
00137 state.ram[i * 0x20 + 0x01] = (i == 0) ? 0x80 : i;
00138 state.ram[i * 0x20 + 0x02] = 1;
00139 state.ram[i * 0x20 + 0x03] = 1;
00140 state.ram[i * 0x20 + 0x04] = 1;
00141 state.ram[i * 0x20 + 0x05] = 1;
00142 state.ram[i * 0x20 + 0x06] = 1;
00143 state.ram[i * 0x20 + 0x07] = 1;
00144 state.ram[i * 0x20 + 0x08] = 0xdd;
00145 state.ram[i * 0x20 + 0x09] = 1;
00146 state.ram[i * 0x20 + 0x0a] = 0xff;
00147 state.ram[i * 0x20 + 0x0b] = (cSystem->get_cpu(i)->get_speed() / 1000000) % 256;
00148 state.ram[i * 0x20 + 0x0c] = (cSystem->get_cpu(i)->get_speed() / 1000000) / 256;
00149
00150
00151 time_t now = time(NULL);
00152 struct tm* t = localtime(&now);
00153 state.ram[i * 0x20 + 0x10] = ToBCD(t->tm_hour);
00154 state.ram[i * 0x20 + 0x11] = ToBCD(t->tm_min);
00155 state.ram[i * 0x20 + 0x12] = ToBCD(t->tm_sec);
00156 state.ram[i * 0x20 + 0x13] = ToBCD(t->tm_mday);
00157 state.ram[i * 0x20 + 0x14] = ToBCD(t->tm_mon + 1);
00158 state.ram[i * 0x20 + 0x15] = ToBCD(t->tm_year - 100);
00159 #if defined(DEBUG_DPR)
00160 printf("%%DPR-I-BOOTDATE: %02x-%02x-%02x, %02x:%02x:%02x\n",
00161 state.ram[i * 0x20 + 21], state.ram[i * 0x20 + 20],
00162 state.ram[i * 0x20 + 19], state.ram[i * 0x20 + 16],
00163 state.ram[i * 0x20 + 17], state.ram[i * 0x20 + 18]);
00164 #endif
00165 state.ram[i * 0x20 + 0x16] = 0;
00166 state.ram[i * 0x20 + 0x1e] = 0x80;
00167 state.ram[i * 0x20 + 0x1f] = 8;
00168 }
00169
00170 state.ram[0xda] = 0xaa;
00171
00172
00173 state.ram[0x80] = 0xf0;
00174 state.ram[0x81] = 0x01;
00175
00176
00177
00178
00179
00180
00181
00182
00183 state.ram[0x88] = 0;
00184 state.ram[0x89] = 0x00;
00185 state.ram[0x8a] = 0x00;
00186 state.ram[0x8b] = 0x00;
00187
00188
00189 state.ram[0x8c] = 0;
00190 state.ram[0x8d] = 0;
00191 state.ram[0x8e] = 0;
00192 state.ram[0x8f] = 0;
00193 state.ram[0x90] = 0xff;
00194 state.ram[0x91] = 0x00;
00195 state.ram[0x92] = 0x07;
00196 state.ram[0x93] = 0x25;
00197 state.ram[0x94] = 0x25;
00198 state.ram[0x95] = 0x25;
00199 state.ram[0x96] = 0x25;
00200 state.ram[0x97] = 0x25;
00201 state.ram[0x98] = 0x25;
00202 state.ram[0x99] = 0x25;
00203 state.ram[0x9a] = 0x8b;
00204 state.ram[0x9b] = 0x8b;
00205 state.ram[0x9c] = 0x8b;
00206 state.ram[0x9d] = 0x8b;
00207 state.ram[0x9e] = 0x8b;
00208 state.ram[0x9f] = 0x8b;
00209
00210
00211 for(i = 0xa0; i < 0xaa; i++)
00212 state.ram[i] = 0;
00213
00214 state.ram[0xaa] = 0x00;
00215
00216
00217 state.ram[0xab] = 0;
00218 state.ram[0xac] = 0xff;
00219 state.ram[0xad] = 0xff;
00220 state.ram[0xae] = 0xff;
00221 switch(cSystem->get_cpu_num())
00222 {
00223 case 1: state.ram[0xaf] = 0x0e;
00224 break;
00225 case 2: state.ram[0xaf] = 0x0c;
00226 break;
00227 case 3: state.ram[0xaf] = 0x08;
00228 break;
00229 case 4: state.ram[0xaf] = 0x00;
00230 break;
00231 }
00232
00233 state.ram[0xb0] = 0x00;
00234 state.ram[0xb1] = 0x00;
00235 state.ram[0xb2] = 0x00;
00236 state.ram[0xba] = 0xba;
00237 state.ram[0xbb] = 0x00;
00238 state.ram[0xbc] = 0x00;
00239
00240
00241 state.ram[0xbd] = 0x07;
00242 state.ram[0xbe] = 0;
00243 state.ram[0xbf] = 0;
00244 state.ram[0xda] = 0xaa;
00245
00246
00247 state.ram[0xdb] = 0xf4;
00248 state.ram[0xdc] = 0x45;
00249 state.ram[0xdd] = 0x51;
00250 state.ram[0xde] = 0x37;
00251 state.ram[0xdf] = 0x8b;
00252 state.ram[0xe0] = 0xd6;
00253 state.ram[0xe1] = 0x49;
00254 state.ram[0xe2] = 0x4b;
00255 state.ram[0xe4] = 0xf5;
00256 state.ram[0xe5] = 0x45;
00257 state.ram[0xe6] = 0x51;
00258 state.ram[0xe7] = 0x37;
00259 state.ram[0xe8] = 0x8b;
00260 state.ram[0xe9] = 0xd6;
00261 state.ram[0xea] = 0x49;
00262 state.ram[0xeb] = 0x4b;
00263 state.ram[0xed] = 0xf6;
00264 state.ram[0xee] = 0x45;
00265 state.ram[0xef] = 0x51;
00266 state.ram[0xf0] = 0x37;
00267 state.ram[0xf1] = 0x8b;
00268 state.ram[0xf2] = 0xd6;
00269 state.ram[0xf3] = 0x49;
00270 state.ram[0xf4] = 0x4b;
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 state.ram[0x3000] = 'V';
00334 state.ram[0x3001] = '2';
00335 state.ram[0x3002] = '.';
00336 state.ram[0x3003] = '2';
00337 state.ram[0x3004] = '2';
00338 state.ram[0x3005] = 'G';
00339 state.ram[0x3006] = 0;
00340 state.ram[0x3007] = 0;
00341 state.ram[0x3008] = 0;
00342
00343
00344
00345 state.ram[0x3009] = 'V';
00346 state.ram[0x300a] = 0x31;
00347 state.ram[0x300b] = 0x30;
00348
00349
00350
00351 state.ram[0x300c] = 'V';
00352 state.ram[0x300d] = 0x31;
00353 state.ram[0x300e] = 0x30;
00354
00355
00356
00357 state.ram[0x3400] = 8;
00358
00359
00360 state.ram[0x3401] = 1;
00361
00362
00363 state.ram[0x3402] = 0;
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380 for(i = 0; i < 0x20; i++)
00381 state.ram[0x34a0 + i] = i;
00382
00383
00384
00385
00386
00387
00388
00389 printf("%s: $Id: DPR.cpp,v 1.22 2008/04/09 12:59:42 iamcamiel Exp $\n",
00390 devid_string);
00391 }
00392
00396 CDPR::~CDPR()
00397 { }
00398 u64 CDPR::ReadMem(int index, u64 address, int dsize)
00399 {
00400 u64 data = 0;
00401 int a = (int) (address >> 6);
00402
00403 data = state.ram[a];
00404
00405 #if defined(DEBUG_DPR)
00406 printf("%%DPR-I-READ: Dual-Port RAM read @ 0x%08x: 0x%02x\n", a,
00407 (u32) (data & 0xff));
00408 #endif
00409 return data;
00410 }
00411
00412 void CDPR::WriteMem(int index, u64 address, int dsize, u64 data)
00413 {
00414 int i;
00415 int a = (int) (address >> 6);
00416 #if defined(DEBUG_DPR)
00417 printf("%%DPR-I-WRITE: Dual-Port RAM write 0x%08x 0x%02x:\n", a,
00418 (u32) (data & 0xff));
00419 #endif
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434 state.ram[a] = (char) data;
00435 switch(a)
00436 {
00437 case 0xff:
00438
00439
00440 state.ram[0xfd] = state.ram[0xff];
00441 switch(state.ram[0xfe])
00442 {
00443 case 1:
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495 switch(state.ram[0xfb])
00496 {
00497 case 0x21:
00498 case 0x22:
00499 case 0x23:
00500 case 0x24:
00501 if((state.ram[0xfb] - 0x20) > cSystem->get_cpu_num())
00502 {
00503 state.ram[0xfc] = 0x80;
00504 break;
00505 }
00506
00507 case 1:
00508 case 2:
00509 case 3:
00510 case 4:
00511 case 5:
00512 case 6:
00513 case 7:
00514 case 8:
00515 case 0x25:
00516 case 0x26:
00517 case 0x27:
00518 case 0x28:
00519 case 0x29:
00520 case 0x2a:
00521 case 0x31:
00522 case 0x32:
00523 case 0x33:
00524 case 0x3b:
00525 case 0x3c:
00526 case 0x3d:
00527 case 0x3e:
00528 case 0x3f:
00529 for(i = 0; i < state.ram[0xf9] + 1; i++)
00530 {
00531 state.ram[state.ram[0xfb] * 0x100 + state.ram[0xfa] + i] = state.ram[0x3500 + state.ram[0xfa] + i];
00532 #if defined(DEBUG_DPR)
00533 printf("%%DPR-I-FRU: FRU data %02x @ FRU %02x set to %02x\n",
00534 state.ram[0xfa] + i, state.ram[0xfb],
00535 state.ram[0x3500 + state.ram[0xfa] + i]);
00536 #endif
00537 }
00538
00539 state.ram[0xfc] = 0;
00540 break;
00541
00542 default:
00543 #if defined(DEBUG_DPR)
00544 printf("%%DPR-I-RMC: RMC Command given: %02x\r\n", state.ram[0xfe]);
00545 printf("%%DPR-I-RMC: f9:%02x fb-fa:%02x%02x\r\n", state.ram[0xf9],
00546 state.ram[0xfb], state.ram[0xfa]);
00547 #endif
00548 state.ram[0xfc] = 0x80;
00549 }
00550 break;
00551
00552 case 2:
00553 state.ram[0xfc] = 0;
00554 break;
00555
00556 case 3:
00557
00558
00559 #if defined(DEBUG_DPR)
00560 sprintf(trcbuffer,
00561 "%%%%DPR-I-OCP: OCP Text set to \"0123456789abcdef\"\r\n");
00562 memcpy(trcbuffer + 29, &(state.ram[0x3500]), 16);
00563
00564
00565 printf(trcbuffer);
00566 #endif
00567 state.ram[0xfc] = 0;
00568 break;
00569
00570 case 0xf0:
00571 state.ram[0xfc] = 0;
00572
00573 default:
00574 #if defined(DEBUG_DPR)
00575 printf("%%DPR-I-RMC: RMC Command given: %02x\r\n", state.ram[0xfe]);
00576 printf("%%DPR-I-RMC: f9:%02x fb-fa:%02x%02x\r\n", state.ram[0xf9],
00577 state.ram[0xfb], state.ram[0xfa]);
00578 #endif
00579 state.ram[0xfc] = 0x81;
00580 }
00581 break;
00582
00583 case 0xfd:
00584
00585
00586 state.ram[0xff] = state.ram[0xfd];
00587 }
00588
00589 return;
00590 }
00591
00595 void CDPR::SaveStateF(char* fn)
00596 {
00597 FILE* ff;
00598 ff = fopen(fn, "wb");
00599 if(ff)
00600 {
00601 SaveState(ff);
00602 fclose(ff);
00603 printf("%%DPR-I-SAVEST: DPR state saved to %s\n", fn);
00604 }
00605 else
00606 {
00607 printf("%%DPR-F-NOSAVE: DPR could not be saved to %s\n", fn);
00608 }
00609 }
00610
00614 void CDPR::SaveStateF()
00615 {
00616 SaveStateF(myCfg->get_text_value("rom.dpr", "dpr.rom"));
00617 }
00618
00622 void CDPR::RestoreStateF(char* fn)
00623 {
00624 FILE* ff;
00625 ff = fopen(fn, "rb");
00626 if(ff)
00627 {
00628 RestoreState(ff);
00629 fclose(ff);
00630 printf("%%DPR-I-RESTST: DPR state restored from %s\n", fn);
00631 }
00632 else
00633 {
00634 printf("%%DPR-F-NOREST: DPR could not be restored from %s\n", fn);
00635 }
00636 }
00637
00638 static u32 dpr_magic1 = 0x18A7B92D;
00639 static u32 dpr_magic2 = 0xD29B7A81;
00640
00644 int CDPR::SaveState(FILE* f)
00645 {
00646 long ss = sizeof(state);
00647
00648 fwrite(&dpr_magic1, sizeof(u32), 1, f);
00649 fwrite(&ss, sizeof(long), 1, f);
00650 fwrite(&state, sizeof(state), 1, f);
00651 fwrite(&dpr_magic2, sizeof(u32), 1, f);
00652 printf("%s: %d bytes saved.\n", "dpr", ss);
00653 return 0;
00654 }
00655
00659 int CDPR::RestoreState(FILE* f)
00660 {
00661 long ss;
00662 u32 m1;
00663 u32 m2;
00664 size_t r;
00665
00666 r = fread(&m1, sizeof(u32), 1, f);
00667 if(r != 1)
00668 {
00669 printf("%s: unexpected end of file!\n", "dpr");
00670 return -1;
00671 }
00672
00673 if(m1 != dpr_magic1)
00674 {
00675 printf("%s: MAGIC 1 does not match!\n", "dpr");
00676 return -1;
00677 }
00678
00679 fread(&ss, sizeof(long), 1, f);
00680 if(r != 1)
00681 {
00682 printf("%s: unexpected end of file!\n", "dpr");
00683 return -1;
00684 }
00685
00686 if(ss != sizeof(state))
00687 {
00688 printf("%s: STRUCT SIZE does not match!\n", "dpr");
00689 return -1;
00690 }
00691
00692 fread(&state, sizeof(state), 1, f);
00693 if(r != 1)
00694 {
00695 printf("%s: unexpected end of file!\n", "dpr");
00696 return -1;
00697 }
00698
00699 r = fread(&m2, sizeof(u32), 1, f);
00700 if(r != 1)
00701 {
00702 printf("%s: unexpected end of file!\n", "dpr");
00703 return -1;
00704 }
00705
00706 if(m2 != dpr_magic2)
00707 {
00708 printf("%s: MAGIC 1 does not match!\n", "dpr");
00709 return -1;
00710 }
00711
00712 printf("%s: %d bytes restored.\n", "dpr", ss);
00713 return 0;
00714 }
00715
00719 void CDPR::RestoreStateF()
00720 {
00721 RestoreStateF(myCfg->get_text_value("rom.dpr", "dpr.rom"));
00722 }
00723
00724 CDPR* theDPR = 0;