Mirror of CollapseOS
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

158 rindas
3.3KB

  1. /* Common code between all z80 emulators
  2. */
  3. #include <string.h>
  4. #include "emul.h"
  5. static Machine m;
  6. static ushort traceval = 0;
  7. static uint8_t io_read(int unused, uint16_t addr)
  8. {
  9. addr &= 0xff;
  10. IORD fn = m.iord[addr];
  11. if (fn != NULL) {
  12. return fn();
  13. } else {
  14. fprintf(stderr, "Out of bounds I/O read: %d\n", addr);
  15. return 0;
  16. }
  17. }
  18. static void io_write(int unused, uint16_t addr, uint8_t val)
  19. {
  20. addr &= 0xff;
  21. IOWR fn = m.iowr[addr];
  22. if (fn != NULL) {
  23. fn(val);
  24. } else {
  25. fprintf(stderr, "Out of bounds I/O write: %d / %d (0x%x)\n", addr, val, val);
  26. }
  27. }
  28. uint8_t emul_mem_read(int unused, uint16_t addr)
  29. {
  30. return m.mem[addr];
  31. }
  32. void emul_mem_write(int unused, uint16_t addr, uint8_t val)
  33. {
  34. if (addr < m.ramstart) {
  35. fprintf(stderr, "Writing to ROM (%d)!\n", addr);
  36. emul_memdump();
  37. fprintf(stderr, "Press any key to continue...\n");
  38. while (getchar() > 0x100);
  39. }
  40. m.mem[addr] = val;
  41. }
  42. Machine* emul_init(char *binpath, ushort binoffset)
  43. {
  44. // initialize memory
  45. memset(m.mem, 0, 0x10000);
  46. FILE *bfp = fopen(binpath, "r");
  47. if (!bfp) {
  48. fprintf(stderr, "Can't open %s\n", binpath);
  49. return NULL;
  50. }
  51. int i = binoffset;
  52. int c = getc(bfp);
  53. while (c != EOF) {
  54. #ifdef MAX_ROMSIZE
  55. if (i >= MAX_ROMSIZE) {
  56. fprintf(stderr, "ROM image too large.\n");
  57. fclose(fp);
  58. return NULL;
  59. }
  60. #endif
  61. m.mem[i++] = c;
  62. c = getc(bfp);
  63. }
  64. fclose(bfp);
  65. m.ramstart = 0;
  66. m.minsp = 0xffff;
  67. m.maxix = 0;
  68. for (int i=0; i<0x100; i++) {
  69. m.iord[i] = NULL;
  70. m.iowr[i] = NULL;
  71. }
  72. m.pchooks_cnt = 0;
  73. Z80RESET(&m.cpu);
  74. m.cpu.memRead = emul_mem_read;
  75. m.cpu.memWrite = emul_mem_write;
  76. m.cpu.ioRead = io_read;
  77. m.cpu.ioWrite = io_write;
  78. return &m;
  79. }
  80. bool emul_step()
  81. {
  82. if (!m.cpu.halted) {
  83. Z80Execute(&m.cpu);
  84. ushort newsp = m.cpu.R1.wr.SP;
  85. if (newsp != 0 && newsp < m.minsp) {
  86. m.minsp = newsp;
  87. }
  88. if (m.cpu.R1.wr.IX > m.maxix) {
  89. m.maxix = m.cpu.R1.wr.IX;
  90. }
  91. for (int i=0; i<m.pchooks_cnt; i++) {
  92. if (m.cpu.PC == m.pchooks[i]) {
  93. m.pchookfunc(&m);
  94. break;
  95. }
  96. }
  97. return true;
  98. } else {
  99. return false;
  100. }
  101. }
  102. bool emul_steps(unsigned int steps)
  103. {
  104. while (steps) {
  105. if (!emul_step()) {
  106. return false;
  107. }
  108. steps--;
  109. }
  110. return true;
  111. }
  112. void emul_loop()
  113. {
  114. while (emul_step());
  115. }
  116. void emul_trace(ushort addr)
  117. {
  118. ushort newval = m.mem[addr+1] << 8 | m.mem[addr];
  119. if (newval != traceval) {
  120. traceval = newval;
  121. fprintf(stderr, "trace: %04x PC: %04x\n", traceval, m.cpu.PC);
  122. }
  123. }
  124. void emul_memdump()
  125. {
  126. fprintf(stderr, "Dumping memory to memdump. PC %04x\n", m.cpu.PC);
  127. FILE *fp = fopen("memdump", "w");
  128. fwrite(m.mem, 0x10000, 1, fp);
  129. fclose(fp);
  130. }
  131. void emul_debugstr(char *s)
  132. {
  133. sprintf(s, "SP %04x (%04x) IX %04x (%04x)",
  134. m.cpu.R1.wr.SP, m.minsp, m.cpu.R1.wr.IX, m.maxix);
  135. }
  136. void emul_printdebug()
  137. {
  138. fprintf(stderr, "Min SP: %04x\n", m.minsp);
  139. fprintf(stderr, "Max IX: %04x\n", m.maxix);
  140. }
  141. byte iord_noop() { return 0; }
  142. void iowr_noop(byte val) {}