[ucsim] Update email and file info, fix stm8 flash controller
[sdcc.git] / sdcc / sim / ucsim / src / sims / z80.src / gb80.cc
blob4d7ea593410cb934ed671f2bc44bc11325735861
1 /*
2 * Simulator of microcontrollers (gb80.cc)
4 * Copyright (C) 2021 Drotos Daniel
5 *
6 * To contact author send email to dr.dkdb@gmail.com
8 */
10 /* This file is part of microcontroller simulator: ucsim.
12 UCSIM is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
17 UCSIM is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with UCSIM; see the file COPYING. If not, write to the Free
24 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 02111-1307, USA. */
26 /*@1@*/
28 //#include "ddconfig.h"
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <ctype.h>
33 #include <string.h>
35 // prj
36 //#include "pobjcl.h"
37 #include "utils.h"
39 // sim
40 #include "simcl.h"
42 // local
43 //#include "z80cl.h"
44 #include "gb80cl.h"
45 #include "glob.h"
47 //#define uint32 t_addr
48 //#define uint8 unsigned char
50 /*******************************************************************/
52 cl_gb80::cl_gb80(struct cpu_entry *Itype, class cl_sim *asim):
53 cl_z80(Itype, asim)
55 type= Itype;
56 BIT_C= 0x10;
57 BIT_A= 0x20;
58 BIT_N= 0x40;
59 BIT_Z= 0x80;
60 BIT_ALL= (BIT_C |BIT_N |BIT_A |BIT_Z);
61 BIT_P= 0;
62 BIT_S= 0;
63 regs.raf.F= 0;
64 regs.ralt_af.aF= 0;
67 int
68 cl_gb80::init(void)
70 /*cl_uc*/cl_z80::init(); /* Memories now exist */
72 ttab_00= gb_ttab_00;
73 ttab_cb= gb_ttab_cb;
75 return(0);
78 const char *
79 cl_gb80::id_string(void)
81 return("GB80");
85 void
86 cl_gb80::mk_hw_elements(void)
88 cl_uc::mk_hw_elements();
91 void
92 cl_gb80::make_memories(void)
94 class cl_memory_chip *chip;
95 class cl_address_decoder *ad;
96 class cl_address_space *as;
98 chip= new cl_chip8("rom_chip", 0x10000, 8, 0);
99 chip->init();
100 memchips->add(chip);
102 rom= new cl_address_space("rom",
103 0,//lr35902_rom_start,
104 0x10000,//lr35902_rom_size,
106 rom->init();
107 address_spaces->add(rom);
109 ad= new cl_address_decoder(as= address_space("rom"),
110 chip,
111 0,//lr35902_rom_start,
112 0xffff,//lr35902_rom_size-1,
113 0//lr35902_rom_start
115 ad->init();
116 as->decoders->add(ad);
117 ad->activate(0);
119 ram= rom;
120 rom->altname= "xram";
122 regs8= new cl_address_space("regs8", 0, 16, 8);
123 regs8->init();
124 regs8->get_cell(0)->decode((t_mem*)&regs.raf.A);
125 regs8->get_cell(1)->decode((t_mem*)&regs.raf.F);
126 regs8->get_cell(2)->decode((t_mem*)&regs.bc.h);
127 regs8->get_cell(3)->decode((t_mem*)&regs.bc.l);
128 regs8->get_cell(4)->decode((t_mem*)&regs.de.h);
129 regs8->get_cell(5)->decode((t_mem*)&regs.de.l);
130 regs8->get_cell(6)->decode((t_mem*)&regs.hl.h);
131 regs8->get_cell(7)->decode((t_mem*)&regs.hl.l);
133 regs8->get_cell(8)->decode((t_mem*)&regs.ralt_af.aA);
134 regs8->get_cell(9)->decode((t_mem*)&regs.ralt_af.aF);
135 regs8->get_cell(10)->decode((t_mem*)&regs.a_bc.h);
136 regs8->get_cell(11)->decode((t_mem*)&regs.a_bc.l);
137 regs8->get_cell(12)->decode((t_mem*)&regs.a_de.h);
138 regs8->get_cell(13)->decode((t_mem*)&regs.a_de.l);
139 regs8->get_cell(14)->decode((t_mem*)&regs.a_hl.h);
140 regs8->get_cell(15)->decode((t_mem*)&regs.a_hl.l);
142 regs16= new cl_address_space("regs16", 0, 11, 16);
143 regs16->init();
145 regs16->get_cell(0)->decode((t_mem*)&regs.AF);
146 regs16->get_cell(1)->decode((t_mem*)&regs.BC);
147 regs16->get_cell(2)->decode((t_mem*)&regs.DE);
148 regs16->get_cell(3)->decode((t_mem*)&regs.HL);
149 regs16->get_cell(4)->decode((t_mem*)&regs.IX);
150 regs16->get_cell(5)->decode((t_mem*)&regs.IY);
151 regs16->get_cell(6)->decode((t_mem*)&regs.SP);
152 regs16->get_cell(7)->decode((t_mem*)&regs.aAF);
153 regs16->get_cell(8)->decode((t_mem*)&regs.aBC);
154 regs16->get_cell(9)->decode((t_mem*)&regs.aDE);
155 regs16->get_cell(10)->decode((t_mem*)&regs.aHL);
157 address_spaces->add(regs8);
158 address_spaces->add(regs16);
160 class cl_var *v;
161 vars->add(v= new cl_var("A", regs8, 0, ""));
162 v->init();
163 vars->add(v= new cl_var("F", regs8, 1, ""));
164 v->init();
165 vars->add(v= new cl_var("B", regs8, 2, ""));
166 v->init();
167 vars->add(v= new cl_var("C", regs8, 3, ""));
168 v->init();
169 vars->add(v= new cl_var("D", regs8, 4, ""));
170 v->init();
171 vars->add(v= new cl_var("E", regs8, 5, ""));
172 v->init();
173 vars->add(v= new cl_var("H", regs8, 6, ""));
174 v->init();
175 vars->add(v= new cl_var("L", regs8, 7, ""));
176 v->init();
178 vars->add(v= new cl_var("AF", regs16, 0, ""));
179 v->init();
180 vars->add(v= new cl_var("BC", regs16, 1, ""));
181 v->init();
182 vars->add(v= new cl_var("DE", regs16, 2, ""));
183 v->init();
184 vars->add(v= new cl_var("HL", regs16, 3, ""));
185 v->init();
186 vars->add(v= new cl_var("IX", regs16, 4, ""));
187 v->init();
188 vars->add(v= new cl_var("IY", regs16, 5, ""));
189 v->init();
190 vars->add(v= new cl_var("SP", regs16, 6, ""));
191 v->init();
194 void
195 cl_gb80::store1(u16_t addr, t_mem val)
197 rom->write(addr, val);
200 void
201 cl_gb80::store2(u16_t addr, u16_t val)
203 rom->write(addr, val);
204 rom->write(addr+1, val>>8);
207 u8_t
208 cl_gb80::get1(u16_t addr)
210 return rom->read(addr);
213 u16_t
214 cl_gb80::get2(u16_t addr)
216 u8_t l= rom->read(addr);
217 u8_t h= rom->read(addr+1);
218 return (h<<8)|l;
223 * Help command interpreter
226 struct dis_entry *
227 cl_gb80::dis_tbl(void)
229 return(disass_gb80);
234 cl_gb80::inst_length(t_addr addr)
236 int len = 0;
238 get_disasm_info(addr, &len, NULL, NULL);
240 return len;
244 cl_gb80::inst_branch(t_addr addr)
246 int b;
248 get_disasm_info(addr, NULL, &b, NULL);
250 return b;
254 cl_gb80::longest_inst(void)
256 return 4;
260 const char *
261 cl_gb80::get_disasm_info(t_addr addr,
262 int *ret_len,
263 int *ret_branch,
264 int *immed_offset)
266 const char *b = NULL;
267 uint code;
268 int len = 0;
269 int immed_n = 0;
270 int i;
271 int start_addr = addr;
272 struct dis_entry *dis_e;
274 code= rom->get(addr++);
275 dis_e = NULL;
277 switch(code) {
278 case 0xcb: /* ESC code to lots of op-codes, all 2-byte */
279 code= rom->get(addr++);
280 i= 0;
281 while ((code & disass_gb80_cb[i].mask) != disass_gb80_cb[i].code &&
282 disass_gb80_cb[i].mnemonic)
283 i++;
284 dis_e = &disass_gb80_cb[i];
285 b= disass_gb80_cb[i].mnemonic;
286 if (b != NULL)
287 len += (disass_gb80_cb[i].length + 1);
288 break;
290 default:
291 i= 0;
292 while ((code & disass_gb80[i].mask) != disass_gb80[i].code &&
293 disass_gb80[i].mnemonic)
294 i++;
295 dis_e = &disass_gb80[i];
296 b= disass_gb80[i].mnemonic;
297 if (b != NULL)
298 len += (disass_gb80[i].length);
299 break;
303 if (ret_branch) {
304 *ret_branch = dis_e->branch;
307 if (immed_offset) {
308 if (immed_n > 0)
309 *immed_offset = immed_n;
310 else *immed_offset = (addr - start_addr);
313 if (len == 0)
314 len = 1;
316 if (ret_len)
317 *ret_len = len;
319 return b;
322 char *
323 cl_gb80::disass(t_addr addr)
325 chars work, temp;
326 const char *b;
327 int len = 0;
328 int immed_offset = 0;
329 bool first= true;
331 work= "";
332 b = get_disasm_info(addr, &len, NULL, &immed_offset);
333 if (b == NULL)
335 return strdup("UNKNOWN/INVALID");
338 while (*b)
340 if ((*b == ' ') && first)
342 first= false;
343 while (work.len() < 6) work.append(' ');
345 if (*b == '%')
347 temp= "";
348 b++;
349 switch (*(b++))
351 case 'd': // d jump relative target, signed? byte immediate operand
352 temp.format("#%d", (char)rom->get(addr+immed_offset));
353 ++immed_offset;
354 break;
355 case 'w': // w word immediate operand
356 temp.format("#0x%04x",
357 (uint)((rom->get(addr+immed_offset)) |
358 (rom->get(addr+immed_offset+1)<<8)) );
359 ++immed_offset;
360 ++immed_offset;
361 break;
362 case 'b': // b byte immediate operand
363 temp.format("#0x%02x", (uint)rom->get(addr+immed_offset));
364 ++immed_offset;
365 break;
366 default:
367 temp= "?";
368 break;
370 work+= temp;
372 else
373 work+= *(b++);
375 return strdup(work.c_str());
379 void
380 cl_gb80::print_regs(class cl_console_base *con)
382 con->dd_color("answer");
383 con->dd_printf("ZNHC---- Flags= 0x%02x %3d %c ",
384 regs.raf.F, regs.raf.F, isprint(regs.raf.F)?regs.raf.F:'.');
385 con->dd_printf("A= 0x%02x %3d %c\n",
386 regs.raf.A, regs.raf.A, isprint(regs.raf.A)?regs.raf.A:'.');
387 con->dd_printf("%s\n", cbin(regs.raf.F,8).c_str());
389 con->dd_printf("BC= 0x%04x [BC]= %02x %3d %c ",
390 regs.BC, get1(regs.BC), get1(regs.BC),
391 isprint(get1(regs.BC))?get1(regs.BC):'.');
392 con->dd_printf("DE= 0x%04x [DE]= %02x %3d %c ",
393 regs.DE, get1(regs.DE), get1(regs.DE),
394 isprint(get1(regs.DE))?get1(regs.DE):'.');
395 con->dd_printf("HL= 0x%04x [HL]= %02x %3d %c\n",
396 regs.HL, get1(regs.HL), get1(regs.HL),
397 isprint(get1(regs.HL))?get1(regs.HL):'.');
398 con->dd_printf("SP= 0x%04x [SP]= %02x %3d %c\n",
399 regs.SP, get1(regs.SP), get1(regs.SP),
400 isprint(get1(regs.SP))?get1(regs.SP):'.');
402 print_disass(PC, con);
406 * Execution
410 cl_gb80::exec_inst(void)
412 t_mem code;
413 int res= -1;
415 instPC= PC;
417 if (fetch(&code))
418 return(resBREAKPOINT);
419 tick(1);
420 inc_R();
421 cond_true= false;
423 switch (code)
425 case 0x00: res= (inst_nop(code)); break;
426 case 0x01:
427 case 0x02: case 0x06: res= (inst_ld(code)); break;
428 case 0x03:
429 case 0x04: res= (inst_inc(code)); break;
430 case 0x05: res= (inst_dec(code)); break;
431 case 0x07: {
432 int ret= (inst_rlca(code));
433 regs.raf.F&= ~(BIT_Z|BIT_A|BIT_N);
434 res= ret;
435 break;
437 case 0x08: res= (inst_st_sp_abs(code)); break;
438 case 0x09: res= (inst_add(code)); break;
439 case 0x0a: case 0x0e: res= (inst_ld(code)); break;
440 case 0x0b:
441 case 0x0d: res= (inst_dec(code)); break;
442 case 0x0c: res= (inst_inc(code)); break;
443 case 0x0f: {
444 int ret= (inst_rrca(code));
445 regs.raf.F&= ~(BIT_Z|BIT_A|BIT_N);
446 res= ret;
447 break;
450 case 0x10: res= (inst_stop0(code)); break;
451 case 0x11:
452 case 0x12: case 0x16: res= (inst_ld(code)); break;
453 case 0x13:
454 case 0x14: res= (inst_inc(code)); break;
455 case 0x15: res= (inst_dec(code)); break;
456 case 0x17: {
457 int ret= (inst_rla(code));
458 regs.raf.F&= ~(BIT_Z|BIT_A|BIT_N);
459 res= ret;
460 break;
462 case 0x18: res= (inst_jr(code)); break;
463 case 0x19: res= (inst_add(code)); break;
464 case 0x1a: case 0x1e: res= (inst_ld(code)); break;
465 case 0x1b:
466 case 0x1d: res= (inst_dec(code)); break;
467 case 0x1c: res= (inst_inc(code)); break;
468 case 0x1f: {
469 int ret= (inst_rra(code));
470 regs.raf.F&= ~(BIT_Z|BIT_A|BIT_N);
471 res= ret;
472 break;
475 case 0x20: res= (inst_jr(code)); break;
476 case 0x21:
477 case 0x26: res= (inst_ld(code)); break;
478 case 0x22: res= inst_ldi(code); break;
479 case 0x23:
480 case 0x24: res= (inst_inc(code)); break;
481 case 0x25: res= (inst_dec(code)); break;
482 case 0x27: res= (inst_daa(code)); break;
484 case 0x28: res= (inst_jr(code)); break;
485 case 0x29: res= (inst_add(code)); break;
486 case 0x2a: res= (inst_ldi(code)); break;
487 case 0x2b:
488 case 0x2d: res= (inst_dec(code)); break;
489 case 0x2c: res= (inst_inc(code)); break;
490 case 0x2e: res= (inst_ld(code)); break;
491 case 0x2f: res= (inst_cpl(code)); break;
493 case 0x30: res= (inst_jr(code)); break;
494 case 0x31: case 0x36: res= (inst_ld(code)); break;
495 case 0x32: res= (inst_ldd(code)); break;
496 case 0x33:
497 case 0x34: res= (inst_inc(code)); break;
498 case 0x35: res= (inst_dec(code)); break;
499 case 0x37: res= (inst_scf(code)); break;
501 case 0x38: res= (inst_jr(code)); break;
502 case 0x39: res= (inst_add(code)); break;
503 case 0x3a: res= inst_ldd(code); break;
504 case 0x3b:
505 case 0x3d: res= (inst_dec(code)); break;
506 case 0x3c: res= (inst_inc(code)); break;
507 case 0x3e: res= (inst_ld(code)); break;
508 case 0x3f: res= (inst_ccf(code)); break;
510 case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x47:
511 case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4f:
512 res= (inst_ld(code));
513 break;
514 case 0x46: case 0x4e: res= (inst_ld(code)); break;
516 case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x57:
517 case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5f:
518 res= (inst_ld(code));
519 break;
520 case 0x56: case 0x5e: res= (inst_ld(code)); break;
522 case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x67:
523 case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6f:
524 res= (inst_ld(code));
525 break;
526 case 0x66: case 0x6e: res= (inst_ld(code)); break;
528 case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x77: case 0x7e:
529 res= (inst_ld(code));
530 break;
531 case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7f:
532 res= (inst_ld(code));
533 break;
534 case 0x76: res= (inst_halt(code)); break;
536 case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x87:
537 res= (inst_add(code));
538 break;
539 case 0x86: res= (inst_add(code)); break;
540 case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8f:
541 res= (inst_adc(code));
542 break;
543 case 0x8e: res= (inst_adc(code)); break;
545 case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x97:
546 res= (inst_sub(code));
547 break;
548 case 0x96: res= (inst_sub(code)); break;
549 case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9f:
550 res= (inst_sbc(code));
551 break;
552 case 0x9e: res= (inst_sbc(code)); break;
554 case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa7:
555 res= (inst_and(code));
556 break;
557 case 0xa6: res= (inst_and(code)); break;
558 case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xaf:
559 res= (inst_xor(code));
560 break;
561 case 0xae: res= (inst_xor(code)); break;
563 case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb7:
564 res= (inst_or(code));
565 break;
566 case 0xb6: res= (inst_or(code)); break;
567 case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbf:
568 res= (inst_cp(code));
569 break;
570 case 0xbe: res= (inst_cp(code)); break;
572 case 0xc0: res= (inst_ret(code)); break;
573 case 0xc1: res= (inst_pop(code)); break;
574 case 0xc2: res= (inst_jp(code)); break;
575 case 0xc3: res= (inst_jp(code)); break;
576 case 0xc4: res= (inst_call(code)); break;
577 case 0xc5: res= (inst_push(code)); break;
578 case 0xc6: res= (inst_add(code)); break;
579 case 0xc7: res= (inst_rst(code)); break;
581 case 0xc8: res= (inst_ret(code)); break;
582 case 0xc9: res= (inst_ret(code)); break;
583 case 0xca: res= (inst_jp(code)); break;
585 /* CB escapes out to 2 byte opcodes(CB include), opcodes
586 to do register bit manipulations */
587 case 0xcb: res= (inst_cb( )); break;
588 case 0xcc: res= (inst_call(code)); break;
589 case 0xcd: res= (inst_call(code)); break;
590 case 0xce: res= (inst_adc(code)); break;
591 case 0xcf: res= (inst_rst(code)); break;
593 case 0xd0: res= (inst_ret(code)); break;
594 case 0xd1: res= (inst_pop(code)); break;
595 case 0xd2: res= (inst_jp(code)); break;
596 case 0xd3: break;
597 case 0xd4: res= (inst_call(code)); break;
598 case 0xd5: res= (inst_push(code)); break;
599 case 0xd6: res= (inst_sub(code)); break;
600 case 0xd7: res= (inst_rst(code)); break;
602 case 0xd8: res= (inst_ret(code)); break;
603 case 0xd9: res= (inst_reti(code)); break;
604 case 0xda: res= (inst_jp(code)); break;
605 case 0xdb: break;
606 case 0xdc: res= (inst_call(code)); break;
608 case 0xdd: break; /* IX register doesn't exist on the GB80 */
609 case 0xde: res= (inst_sbc(code)); break;
610 case 0xdf: res= (inst_rst(code)); break;
613 case 0xe0: res= (inst_ldh(code)); break;
614 case 0xe1: res= (inst_pop(code)); break;
615 case 0xe2: res= (inst_ldh(code)); break;
616 case 0xe3:
617 case 0xe4: break;
618 case 0xe5: res= (inst_push(code)); break;
619 case 0xe6: res= (inst_and(code)); break;
620 case 0xe7: res= (inst_rst(code)); break;
622 case 0xe8: res= (inst_add_sp_d(code)); break;
623 case 0xe9: res= (inst_jp(code)); break;
624 case 0xea: res= (inst_ld16(code)); break;
625 case 0xeb:
626 case 0xec: case 0xed: break;
627 case 0xee: res= (inst_xor(code)); break;
628 case 0xef: res= (inst_rst(code)); break;
630 case 0xf0: res= (inst_ldh(code)); break;
631 case 0xf1: {
632 int ret= (inst_pop(code));
633 regs.raf.F&= 0xf0;
635 res= ret;
636 break;
638 case 0xf2: res= (inst_ldh(code)); break;
639 case 0xf3: res= (inst_di(code)); break;
640 case 0xf4: break;
641 case 0xf5: res= (inst_push(code)); break;
642 case 0xf6: res= (inst_or(code)); break;
643 case 0xf7: res= (inst_rst(code)); break;
645 case 0xf8: res= (inst_ldhl_sp(code)); break;
646 case 0xf9: res= (inst_ld(code)); break;
647 case 0xfa: res= (inst_ld16(code)); break;
648 case 0xfb: res= (inst_ei(code)); break;
649 case 0xfc:
650 case 0xfd: break;
651 case 0xfe: res= (inst_cp(code)); break;
652 case 0xff: res= (inst_rst(code)); break;
656 tickt(code);
658 if (res >= 0)
659 return res;
660 return(resINV_INST);
665 cl_gb80::tickt(t_mem code)
667 // special cases: dd, cb, ed, ddcb, fd, fdcb
668 u16_t t= 0;
669 u8_t c2, c3, c4;
670 switch (code)
672 case 0xcb:
673 c2= rom->read(instPC+1);
674 t= gb_ttab_cb[c2];
675 break;
676 default:
677 t= gb_ttab_00[code];
678 break;
680 if (cond_true)
681 t>>= 8;
682 else
683 t&= 0xff;
684 tick(t-1);
685 return t;
689 /* End of z80.src/gb80.cc */