1 /* This file is part of microcontroller simulator: ucsim.
2
3 UCSIM is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2 of the License, or
6 (at your option) any later version.
7
8 UCSIM is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with UCSIM; see the file COPYING. If not, write to the Free
15 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
16 02111-1307, USA. */
17 /*@1@*/
18
19 #include "ddconfig.h"
20
21 // local
22 #include "r2kcl.h"
23 #include "z80mac.h"
24
25
word_parity(u16_t x)26 unsigned word_parity( u16_t x ) {
27 // bitcount(x) performed by shift-and-add
28 u16_t tmp = (x & 0x5555) + ((x & 0xAAAA) >> 1);
29 tmp = (tmp & 0x3333) + ((tmp & 0xCCCC) >> 2);
30 tmp = (tmp & 0x0F0F) + ((tmp & 0xF0F0) >> 4);
31 tmp = (tmp & 0x000F) + ((tmp & 0x0F00) >> 8);
32
33 // parity determined by count being odd or even
34 return 0x01 ^ (tmp & 1);
35 }
36
37 /******** rabbit 2000 memory access helper functions *****************/
logical_addr_to_phys(u16_t logical_addr)38 u32_t rabbit_mmu::logical_addr_to_phys( u16_t logical_addr ) {
39 u32_t phys_addr = logical_addr;
40 unsigned segnib = logical_addr >> 12;
41
42 if (segnib >= 0xE000)
43 {
44 phys_addr += ((u32_t)xpc) << 12;
45 }
46 else if (segnib >= ((segsize >> 4) & 0x0F))
47 {
48 phys_addr += ((u32_t)stackseg) << 12;
49 }
50 else if (segnib >= (segsize & 0x0F))
51 {
52 phys_addr += ((u32_t)dataseg) << 12;
53 }
54
55 return phys_addr;
56 }
57
store1(u16_t addr,t_mem val)58 void cl_r2k::store1( u16_t addr, t_mem val ) {
59 u32_t phys_addr;
60
61 if (mmu.io_flag == IOI) {
62 if ((mmu.mmidr ^ 0x80) & 0x80)
63 /* bit 7 = 0 --> use only 8-bits for internal I/O addresses */
64 addr = addr & 0x0ff;
65
66 if (addr == MMIDR) {
67 mmu.mmidr = val;
68 return;
69 }
70
71 if (addr == SADR) {
72 /* serial A (console when using the rabbit programming cable) */
73 putchar(val);
74 fflush(stdout);
75 }
76 return;
77 }
78 if (mmu.io_flag == IOE) {
79 /* I/O operation for external device (such as an ethernet controller) */
80 return;
81 }
82
83 phys_addr = mmu.logical_addr_to_phys( addr );
84 ram->write(phys_addr, val);
85 }
86
store2(u16_t addr,u16_t val)87 void cl_r2k::store2( u16_t addr, u16_t val ) {
88 u32_t phys_addr;
89
90 if (mmu.io_flag == IOI) {
91 /* I/O operation for on-chip device (serial ports, timers, etc) */
92 return;
93 }
94
95 if (mmu.io_flag == IOE) {
96 /* I/O operation for external device (such as an ethernet controller) */
97 return;
98 }
99
100 phys_addr = mmu.logical_addr_to_phys( addr );
101
102 ram->write(phys_addr, val & 0xff);
103 ram->write(phys_addr+1, (val >> 8) & 0xff);
104 }
105
get1(u16_t addr)106 u8_t cl_r2k::get1( u16_t addr ) {
107 u32_t phys_addr = mmu.logical_addr_to_phys( addr );
108
109 if (mmu.io_flag == IOI) {
110 /* stub for on-chip device I/O */
111 return 0;
112 }
113 if (mmu.io_flag == IOE) {
114 /* stub for external device I/O */
115 return 0;
116 }
117
118 return ram->read(phys_addr);
119 }
120
get2(u16_t addr)121 u16_t cl_r2k::get2( u16_t addr ) {
122 u32_t phys_addr = mmu.logical_addr_to_phys( addr );
123 u16_t l, h;
124
125 if (mmu.io_flag == IOI) {
126 /* stub for on-chip device I/O */
127 return 0;
128 }
129 if (mmu.io_flag == IOE) {
130 /* stub for external device I/O */
131 return 0;
132 }
133
134 l = ram->read(phys_addr );
135 h = ram->read(phys_addr+1);
136
137 return (h << 8) | l;
138 }
139
fetch1(void)140 t_mem cl_r2k::fetch1( void ) {
141 return fetch( );
142 }
143
fetch2(void)144 u16_t cl_r2k::fetch2( void ) {
145 u16_t c1, c2;
146
147 c1 = fetch( );
148 c2 = fetch( );
149 return (c2 << 8) | c1;
150 }
151
fetch(void)152 t_mem cl_r2k::fetch(void) {
153 /*
154 * Fetch without checking for breakpoint hit
155 *
156 * Used by bool cl_uc::fetch(t_mem *code) in sim.src/uc.cc
157 * which does check for a breakpoint hit
158 */
159
160 u32_t phys_addr = mmu.logical_addr_to_phys( PC );
161 ulong code;
162
163 if (!rom)
164 return(0);
165
166 code= rom->read(phys_addr);
167 PC = (PC + 1) & 0xffffUL;
168 vc.fetch++;
169 return(code);
170 }
171
172 /******** start rabbit 2000 specific codes *****************/
inst_add_sp_d(t_mem code)173 int cl_r2k::inst_add_sp_d(t_mem code) {
174 u16_t d = fetch( );
175 /* sign-extend d from 8-bits to 16-bits */
176 d |= (d>>7)*0xFF00;
177 regs.SP = (regs.SP + d) & 0xffff;
178 return(resGO);
179 }
180
inst_altd(t_mem code)181 int cl_r2k::inst_altd(t_mem code) {
182 // stub
183 return(resGO);
184 }
185
186 int
inst_r2k_ld(t_mem code)187 cl_r2k::inst_r2k_ld(t_mem code)
188 {
189 /* 0xC4 ld hl,(sp+n)
190 * 0xD4 ld (sp+n),hl
191 * 0xE4 ld hl,(ix+d)
192 * DD E4 = ld hl,(hl+d) [note: (hl+d) breaks the normal prefix pattern]
193 * FD E4 = ld hl,(iy+d)
194 * 0xF4 ld (ix+d),hl
195 * DD F4 = ld (hl+d),hl
196 * FD F4 = ld (iy+d),hl
197 */
198 switch(code) {
199 case 0xC4: regs.HL = get2( add_u16_disp(regs.SP, fetch()) ); vc.rd+= 2; break;
200 case 0xD4: store2( add_u16_disp(regs.SP, fetch()), regs.HL ); vc.wr+= 2; break;
201 case 0xE4: regs.HL = get2( add_u16_disp(regs.IX, fetch()) ); vc.rd+= 2; break;
202 case 0xF4: store2( add_u16_disp(regs.IX, fetch()), regs.HL ); vc.wr+= 2; break;
203 default:
204 return(resINV_INST);
205 }
206
207 return(resGO);
208 }
209
inst_r2k_ex(t_mem code)210 int cl_r2k::inst_r2k_ex (t_mem code) {
211 u16_t tempw;
212
213 switch(code) {
214 case 0xE3:
215 // EX DE', HL on rabbit processors
216 tempw = regs.aDE;
217 regs.aDE = regs.HL;
218 regs.HL = tempw;
219 return(resGO);
220
221 default:
222 return(resINV_INST);
223 }
224 }
225
inst_ljp(t_mem code)226 int cl_r2k::inst_ljp(t_mem code) {
227 u16_t mn;
228
229 mn = fetch2(); /* don't clobber PC before the fetch for xmem page */
230 mmu.xpc = fetch1();
231 PC = mn;
232
233 return(resGO);
234 }
235
inst_lcall(t_mem code)236 int cl_r2k::inst_lcall(t_mem code) {
237 u16_t mn;
238
239 push1(mmu.xpc);
240 push2(PC+2);
241 vc.wr+= 2;
242
243 mn = fetch2(); /* don't clobber PC before the fetch for xmem page */
244 mmu.xpc = fetch1();
245 PC = mn;
246
247 return(resGO);
248 }
249
inst_bool(t_mem code)250 int cl_r2k::inst_bool(t_mem code) {
251 regs.raf.F &= ~BIT_ALL;
252 if (regs.HL)
253 regs.HL = 1;
254 else
255 regs.raf.F |= BIT_Z;
256 return(resGO);
257 }
258
inst_r2k_and(t_mem code)259 int cl_r2k::inst_r2k_and(t_mem code) { // AND HL,DE
260 regs.HL &= regs.DE;
261
262 regs.raf.F &= ~BIT_ALL;
263 if (regs.DE & 0x8000)
264 regs.raf.F |= BIT_S;
265 if (regs.DE == 0)
266 regs.raf.F |= BIT_Z;
267 if (word_parity(regs.DE))
268 regs.raf.F |= BIT_P;
269 return(resGO);
270 }
271
inst_r2k_or(t_mem code)272 int cl_r2k::inst_r2k_or (t_mem code) { // OR HL,DE
273 regs.HL |= regs.DE;
274
275 regs.raf.F &= ~BIT_ALL;
276 if (regs.DE & 0x8000)
277 regs.raf.F |= BIT_S;
278 if (regs.DE == 0)
279 regs.raf.F |= BIT_Z;
280 if (word_parity(regs.DE))
281 regs.raf.F |= BIT_P;
282 return(resGO);
283 }
284
inst_mul(t_mem code)285 int cl_r2k::inst_mul(t_mem code) {
286 long m;
287 long m1 = (long)(regs.BC & 0x7fff);
288 long m2 = (long)(regs.DE & 0x7fff);
289 if (regs.BC & 0x8000)
290 m1 -= (1 << 15);
291 if (regs.DE & 0x8000)
292 m2 -= (1 << 15);
293 m = m1 * m2;
294 regs.BC = ((unsigned long)(m) & 0xffff);
295 regs.HL = ((unsigned long)(m) >> 16) & 0xffff;
296 return(resGO);
297 }
298
inst_rl_de(t_mem code)299 int cl_r2k::inst_rl_de(t_mem code) {
300 unsigned int oldcarry = (regs.raf.F & BIT_C);
301
302 regs.raf.F &= ~BIT_ALL;
303 regs.raf.F |= (((regs.DE >> 15) & 1U) << BITPOS_C);
304 regs.DE = (regs.DE << 1) | (oldcarry >> BITPOS_C);
305
306 if (regs.DE & 0x8000)
307 regs.raf.F |= BIT_S;
308 if (regs.DE == 0)
309 regs.raf.F |= BIT_Z;
310 if (word_parity(regs.DE))
311 regs.raf.F |= BIT_P;
312 return(resGO);
313 }
314
inst_rr_de(t_mem code)315 int cl_r2k::inst_rr_de(t_mem code) {
316 unsigned int oldcarry = (regs.raf.F & BIT_C);
317
318 regs.raf.F &= ~BIT_ALL;
319 regs.raf.F |= ((regs.DE & 1) << BITPOS_C);
320 regs.DE = (regs.DE >> 1) | (oldcarry << (15 - BITPOS_C));
321
322 if (regs.DE & 0x8000)
323 regs.raf.F |= BIT_S;
324 if (regs.DE == 0)
325 regs.raf.F |= BIT_Z;
326 if (word_parity(regs.DE))
327 regs.raf.F |= BIT_P;
328 return(resGO);
329 }
330
inst_rr_hl(t_mem code)331 int cl_r2k::inst_rr_hl(t_mem code) // RR HL
332 {
333 unsigned int oldcarry = (regs.raf.F & BIT_C);
334
335 regs.raf.F &= ~BIT_ALL;
336 regs.raf.F |= ((regs.HL & 1) << BITPOS_C);
337 regs.HL = (regs.HL >> 1) | (oldcarry << (15 - BITPOS_C));
338
339 if (regs.HL & 0x8000)
340 regs.raf.F |= BIT_S;
341 if (regs.HL == 0)
342 regs.raf.F |= BIT_Z;
343 if (word_parity(regs.HL))
344 regs.raf.F |= BIT_P;
345 return(resGO);
346 }
347
348
349 int
inst_rst(t_mem code)350 cl_r2k::inst_rst(t_mem code)
351 {
352 switch(code) {
353 case 0xC7: // RST 0
354 push2(PC+2);
355 PC = 0x0;
356 vc.wr+= 2;
357 break;
358 case 0xCF: // RST 8
359 return(resINV_INST);
360
361 case 0xD7: // RST 10H
362 push2(PC+2);
363 PC = 0x10;
364 vc.wr+= 2;
365 break;
366 case 0xDF: // RST 18H
367 push2(PC+2);
368 PC = 0x18;
369 vc.wr+= 2;
370 break;
371 case 0xE7: // RST 20H
372 push2(PC+2);
373 PC = 0x20;
374 vc.wr+= 2;
375 break;
376 case 0xEF: // RST 28H
377 //PC = 0x28;
378 switch (regs.raf.A) {
379 case 0:
380 return(resBREAKPOINT);
381 // ::exit(0);
382 break;
383
384 case 1:
385 //printf("PUTCHAR-----> %xH\n", regs.hl.l);
386 putchar(regs.hl.l);
387 fflush(stdout);
388 break;
389 }
390 break;
391 case 0xF7: // RST 30H
392 return(resINV_INST); // opcode is used for MUL on rabbit 2000+
393 break;
394 case 0xFF: // RST 38H
395 push2(PC+2);
396 PC = 0x38;
397 vc.wr+= 2;
398 break;
399 default:
400 return(resINV_INST);
401 break;
402 }
403 return(resGO);
404 }
405
inst_xd(t_mem prefix)406 int cl_r2k::inst_xd(t_mem prefix)
407 {
408 u16_t *regs_IX_OR_IY = (prefix==0xdd)?(®s.IX):(®s.IY);
409 t_mem code;
410
411 if (fetch(&code))
412 return(resBREAKPOINT);
413
414 switch (code) {
415
416 // 0x06 LD A,(IX+A) is r4k+ instruction
417 case 0x21: // LD IX,nnnn
418 case 0x22: // LD (nnnn),IX
419
420 case 0x2A: // LD IX,(nnnn)
421 case 0x2E: // LD LX,nn
422 case 0x36: // LD (IX+dd),nn
423 case 0x46: // LD B,(IX+dd)
424 case 0x4E: // LD C,(IX+dd)
425 case 0x56: // LD D,(IX+dd)
426 case 0x5E: // LD E,(IX+dd)
427 case 0x66: // LD H,(IX+dd)
428 case 0x6E: // LD L,(IX+dd)
429
430 case 0x70: // LD (IX+dd),B
431 case 0x71: // LD (IX+dd),C
432 case 0x72: // LD (IX+dd),D
433 case 0x73: // LD (IX+dd),E
434 case 0x74: // LD (IX+dd),H
435 case 0x75: // LD (IX+dd),L
436 case 0x77: // LD (IX+dd),A
437 case 0x7E: // LD A,(IX+dd)
438 case 0xF9: // LD SP,IX
439 if (prefix == 0xdd)
440 return(inst_dd_ld(code));
441 else
442 return(inst_fd_ld(code));
443
444 case 0x7C: // LD HL,IX
445 regs.HL = *regs_IX_OR_IY; // LD HL, IX|IY for rabbit processors
446 return(resGO);
447 case 0x7D: // LD IX,HL
448 *regs_IX_OR_IY = regs.HL; // LD IX|IY,HL for rabbit processors
449 return(resGO);
450
451 case 0x23: // INC IX
452 case 0x34: // INC (IX+dd)
453 if (prefix == 0xdd)
454 return(inst_dd_inc(code));
455 else
456 return(inst_fd_inc(code));
457
458 case 0x09: // ADD IX,BC
459 case 0x19: // ADD IX,DE
460 case 0x29: // ADD IX,IX
461 case 0x39: // ADD IX,SP
462 case 0x86: // ADD A,(IX)
463 if (prefix == 0xdd)
464 return(inst_dd_add(code));
465 else
466 return(inst_fd_add(code));
467
468 case 0x2B: // DEC IX
469 case 0x35: // DEC (IX+dd)
470 if (prefix == 0xdd)
471 return(inst_dd_dec(code));
472 else
473 return(inst_fd_dec(code));
474
475 // 0x4C TEST IX is r4k+
476
477 case 0x8E: // ADC A,(IX)
478 case 0x96: // SUB (IX+dd)
479 case 0x9E: // SBC A,(IX+dd)
480 case 0xA6: // AND (IX+dd)
481 case 0xAE: // XOR (IX+dd)
482 case 0xB6: // OR (IX+dd)
483 case 0xBE: // CP (IX+dd)
484 if (prefix == 0xdd)
485 return(inst_dd_misc(code));
486 else
487 return(inst_fd_misc(code));
488
489 case 0xC4: // LD IX,(SP+n)
490 *regs_IX_OR_IY = get2( add_u16_disp(regs.SP, fetch()) );
491 vc.rd+= 2;
492 return(resGO);
493
494 case 0xCB: // escape, IX prefix to CB commands
495 // fixme: limit the opcodes passed through to those officially
496 // documented as present on the rabbit processors
497 if (prefix == 0xdd)
498 return(inst_ddcb()); /* see inst_ddcb.cc */
499 else
500 return(inst_fdcb()); /* see inst_fdcb.cc */
501
502 case 0xCC: // BOOL IX|IY
503 if (*regs_IX_OR_IY)
504 *regs_IX_OR_IY = 1;
505
506 // update flags
507 regs.raf.F &= ~BIT_ALL;
508 // bit 15 will never be set, so S<=0
509 if (*regs_IX_OR_IY == 0)
510 regs.raf.F |= BIT_Z;
511 // L/V and C are always cleared
512 return(resGO);
513
514 case 0xD4: // LD (SP+n),IX|IY
515 store2( add_u16_disp(regs.SP, fetch()), *regs_IX_OR_IY );
516 vc.wr+= 2;
517 return(resGO);
518
519 case 0xE1: // POP IX
520 *regs_IX_OR_IY = get2(regs.SP);
521 regs.SP+=2;
522 vc.rd+= 2;
523 return(resGO);
524
525 case 0xE3: // EX (SP),IX
526 {
527 u16_t tempw;
528
529 tempw = *regs_IX_OR_IY;
530 *regs_IX_OR_IY = get2(regs.SP);
531 store2(regs.SP, tempw);
532 vc.rd+= 2;
533 vc.wr+= 2;
534 }
535 return(resGO);
536
537 case 0xE4:
538 if (prefix == 0xDD)
539 regs.HL = get2( add_u16_disp(regs.HL, fetch()) );
540 else
541 regs.HL = get2( add_u16_disp(regs.IY, fetch()) );
542 vc.rd+= 2;
543 return(resGO);
544
545 case 0xE5: // PUSH IX
546 push2(*regs_IX_OR_IY);
547 vc.wr+= 2;
548 return(resGO);
549
550 case 0xE9: // JP (IX)
551 PC = *regs_IX_OR_IY;
552 return(resGO);
553
554 case 0xEA:
555 push2(PC);
556 PC = *regs_IX_OR_IY;
557 vc.wr+= 2;
558 return(resGO);
559
560 case 0xDC: // AND IX|IY,DE for rabbit processors
561 case 0xEC: // OR IX|IY,DE for rabbit processors
562 if (code == 0xDC)
563 *regs_IX_OR_IY &= regs.DE;
564 else
565 *regs_IX_OR_IY |= regs.DE;
566
567 // update flags
568 regs.raf.F &= ~BIT_ALL;
569 if (*regs_IX_OR_IY & 0x8000)
570 regs.raf.F |= BIT_S;
571 if (regs_IX_OR_IY == 0)
572 regs.raf.F |= BIT_Z;
573 if (word_parity(*regs_IX_OR_IY))
574 regs.raf.F |= BIT_P;
575 return(resGO);
576
577 case 0xF4: // LD (HL|IY+d),HL
578 if (prefix == 0xDD)
579 store2( add_u16_disp(regs.HL, fetch()), regs.HL );
580 else
581 store2( add_u16_disp(regs.IY, fetch()), regs.HL );
582 vc.wr+= 2;
583 return(resGO);
584
585 case 0xFC: // RR IX|IY
586 {
587 u16_t tmp = (regs.raf.F & BIT_C) << (15 - BITPOS_C);
588 tmp |= (*regs_IX_OR_IY >> 1);
589
590 regs.raf.F = (regs.raf.F & ~BIT_C) | ((*regs_IX_OR_IY & 1) << BITPOS_C);
591
592 if (*regs_IX_OR_IY & 0x8000)
593 regs.raf.F |= BIT_S;
594 if (*regs_IX_OR_IY == 0)
595 regs.raf.F |= BIT_Z;
596 if (word_parity(*regs_IX_OR_IY))
597 regs.raf.F |= BIT_P;
598 return(resGO);
599 }
600
601 default:
602 return(resINV_INST);
603 }
604
605 return(resINV_INST);
606 }
607