1
/*****************************************************************************
4
* portable sharp 61860 emulator interface
5
* (sharp pocket computers)
7
* Copyright Peter Trauner, all rights reserved.
9
* - This source code is released as freeware for non-commercial purposes.
10
* - You are free to use and redistribute this code in modified or
11
* unmodified form, provided you list me in the credits.
12
* - If you modify this source code, you must add a notice to each modified
13
* source file that it has been changed. If you're a nice person, you
14
* will clearly mark each change too. :)
15
* - If you wish to use this for commercial purposes, please contact me at
16
* peter.trauner@jk.uni-linz.ac.at
17
* - The author of this copywritten work reserves the right to change the
18
* terms of its usage and license at any time, including retroactively
19
* - This entire notice must remain in the source code.
22
* 21.07.2001 Several changes listed below were made by Mario Konegger
23
* (konegger@itp.tu-graz.ac.at)
24
* replaced buggy BCD-commands add_bcd, sub_bcd, add_bcd_a,
25
* sub_bcd_a and changed out_c, to implement HLT-mode of the CPU.
27
*****************************************************************************/
29
INLINE UINT8 READ_OP(sc61860_state *cpustate)
31
return cpustate->direct->read_decrypted_byte(cpustate->pc++);
34
INLINE UINT8 READ_OP_ARG(sc61860_state *cpustate)
36
return cpustate->direct->read_raw_byte(cpustate->pc++);
39
INLINE UINT16 READ_OP_ARG_WORD(sc61860_state *cpustate)
41
UINT16 t=cpustate->direct->read_decrypted_byte(cpustate->pc++)<<8;
42
t|=cpustate->direct->read_decrypted_byte(cpustate->pc++);
46
INLINE UINT8 READ_BYTE(sc61860_state *cpustate, UINT16 adr)
48
return cpustate->program->read_byte(adr);
51
INLINE void WRITE_BYTE(sc61860_state *cpustate, UINT16 a, UINT8 v)
53
cpustate->program->write_byte(a, v);
56
INLINE UINT8 READ_RAM(sc61860_state *cpustate, int r)
58
return cpustate->ram[r];
61
INLINE void WRITE_RAM(sc61860_state *cpustate, int r, UINT8 v)
66
INLINE void PUSH(sc61860_state *cpustate, UINT8 v)
69
WRITE_RAM(cpustate, cpustate->r, v);
72
INLINE UINT8 POP(sc61860_state *cpustate)
74
UINT8 t = READ_RAM(cpustate, cpustate->r);
79
INLINE void sc61860_load_imm(sc61860_state *cpustate, int r, UINT8 v)
81
WRITE_RAM(cpustate, r, v);
84
INLINE void sc61860_load(sc61860_state *cpustate)
86
WRITE_RAM(cpustate, A, READ_RAM(cpustate, cpustate->p));
89
INLINE void sc61860_load_imm_p(sc61860_state *cpustate, UINT8 v)
94
INLINE void sc61860_load_imm_q(sc61860_state *cpustate, UINT8 v)
99
INLINE void sc61860_load_r(sc61860_state *cpustate)
101
cpustate->r = READ_RAM(cpustate, A) & 0x7f;
104
INLINE void sc61860_load_ext(sc61860_state *cpustate, int r)
106
WRITE_RAM(cpustate, r, READ_BYTE(cpustate, cpustate->dp));
109
INLINE void sc61860_load_dp(sc61860_state *cpustate)
111
cpustate->dp=READ_OP_ARG_WORD(cpustate);
114
INLINE void sc61860_load_dl(sc61860_state *cpustate)
116
cpustate->dp=(cpustate->dp&~0xff)|READ_OP_ARG(cpustate);
119
INLINE void sc61860_store_p(sc61860_state *cpustate)
121
WRITE_RAM(cpustate, A, cpustate->p);
124
INLINE void sc61860_store_q(sc61860_state *cpustate)
126
WRITE_RAM(cpustate, A, cpustate->q);
129
INLINE void sc61860_store_r(sc61860_state *cpustate)
131
WRITE_RAM(cpustate, A, cpustate->r);
134
INLINE void sc61860_store_ext(sc61860_state *cpustate, int r)
136
WRITE_BYTE(cpustate, cpustate->dp, READ_RAM(cpustate, r));
139
INLINE void sc61860_exam(sc61860_state *cpustate, int a, int b)
141
UINT8 t = READ_RAM(cpustate, a);
142
WRITE_RAM(cpustate, a, READ_RAM(cpustate, b));
143
WRITE_RAM(cpustate, b, t);
146
INLINE void sc61860_test(sc61860_state *cpustate, int reg, UINT8 value)
148
cpustate->zero=(READ_RAM(cpustate, reg) & value)==0;
151
INLINE void sc61860_test_ext(sc61860_state *cpustate)
153
cpustate->zero=(READ_BYTE(cpustate, cpustate->dp)&READ_OP_ARG(cpustate))==0;
156
INLINE void sc61860_and(sc61860_state *cpustate, int reg, UINT8 value)
158
UINT8 t = READ_RAM(cpustate, reg) & value;
159
WRITE_RAM(cpustate, reg, t);
163
INLINE void sc61860_and_ext(sc61860_state *cpustate)
165
UINT8 t = READ_BYTE(cpustate, cpustate->dp) & READ_OP_ARG(cpustate);
167
WRITE_BYTE(cpustate, cpustate->dp, t);
170
INLINE void sc61860_or(sc61860_state *cpustate, int reg, UINT8 value)
172
UINT8 t = READ_RAM(cpustate, reg) | value;
173
WRITE_RAM(cpustate, reg, t);
177
INLINE void sc61860_or_ext(sc61860_state *cpustate)
179
UINT8 t=READ_BYTE(cpustate, cpustate->dp)|READ_OP_ARG(cpustate);
181
WRITE_BYTE(cpustate, cpustate->dp, t);
184
INLINE void sc61860_rotate_right(sc61860_state *cpustate)
186
int t = READ_RAM(cpustate, A);
187
if (cpustate->carry) t|=0x100;
189
WRITE_RAM(cpustate, A, t>>1);
192
INLINE void sc61860_rotate_left(sc61860_state *cpustate)
194
int t = READ_RAM(cpustate, A) << 1;
195
if (cpustate->carry) t|=1;
196
cpustate->carry=t&0x100;
197
WRITE_RAM(cpustate, A, t);
200
INLINE void sc61860_swap(sc61860_state *cpustate)
202
int t = READ_RAM(cpustate, A);
203
WRITE_RAM(cpustate, A, (t<<4)|((t>>4)&0xf));
207
INLINE void sc61860_inc(sc61860_state *cpustate, int reg)
209
UINT8 t = READ_RAM(cpustate, reg) + 1;
211
WRITE_RAM(cpustate, reg, t);
213
cpustate->carry=t==0;
216
INLINE void sc61860_inc_p(sc61860_state *cpustate)
222
INLINE void sc61860_dec(sc61860_state *cpustate, int reg)
224
UINT8 t = READ_RAM(cpustate, reg) - 1;
226
WRITE_RAM(cpustate, reg, t);
228
cpustate->carry=t==0xff;
231
INLINE void sc61860_dec_p(sc61860_state *cpustate)
236
INLINE void sc61860_add(sc61860_state *cpustate, int reg, UINT8 value)
238
int t = READ_RAM(cpustate, reg) + value;
239
WRITE_RAM(cpustate, reg, t);
240
cpustate->zero=(t&0xff)==0;
241
cpustate->carry=t>=0x100;
244
INLINE void sc61860_add_carry(sc61860_state *cpustate)
246
int t = READ_RAM(cpustate, cpustate->p) + READ_RAM(cpustate, A);
247
if (cpustate->carry) t++;
248
WRITE_RAM(cpustate, cpustate->p, t);
249
cpustate->zero=(t&0xff)==0;
250
cpustate->carry=t>=0x100;
254
INLINE void sc61860_add_word(sc61860_state *cpustate)
256
int t = READ_RAM(cpustate, cpustate->p) + READ_RAM(cpustate, A), t2;
257
WRITE_RAM(cpustate, cpustate->p, t);
259
t2 = READ_RAM(cpustate, cpustate->p) + READ_RAM(cpustate, B);
261
WRITE_RAM(cpustate, cpustate->p, t2);
262
cpustate->zero=(t2&0xff)==0 &&(t&0xff)==0;
263
cpustate->carry=t2>=0x100;
267
INLINE void sc61860_sub(sc61860_state *cpustate, int reg, UINT8 value)
269
int t = READ_RAM(cpustate, reg) - value;
270
WRITE_RAM(cpustate, reg, t);
271
cpustate->zero=(t&0xff)==0;
275
INLINE void sc61860_sub_carry(sc61860_state *cpustate)
277
int t = READ_RAM(cpustate, cpustate->p) - READ_RAM(cpustate, A);
278
if (cpustate->carry) t--;
279
WRITE_RAM(cpustate, cpustate->p, t);
280
cpustate->zero=(t&0xff)==0;
286
INLINE void sc61860_sub_word(sc61860_state *cpustate)
288
int t = READ_RAM(cpustate, cpustate->p) - READ_RAM(cpustate, A), t2;
289
WRITE_RAM(cpustate, cpustate->p, t);
291
t2 = READ_RAM(cpustate, cpustate->p) - READ_RAM(cpustate, B);
293
WRITE_RAM(cpustate, cpustate->p, t2);
294
cpustate->zero=(t2&0xff)==0 && (t&0xff)==0;
295
cpustate->carry=t2<0;
298
INLINE void sc61860_cmp(sc61860_state *cpustate, int reg, UINT8 value)
300
int t = READ_RAM(cpustate, reg) - value;
305
INLINE void sc61860_pop(sc61860_state *cpustate)
307
WRITE_RAM(cpustate, A, POP(cpustate));
310
INLINE void sc61860_push(sc61860_state *cpustate)
312
PUSH(cpustate, READ_RAM(cpustate, A));
315
INLINE void sc61860_prepare_table_call(sc61860_state *cpustate)
318
cpustate->h=READ_OP(cpustate);
319
adr=READ_OP_ARG_WORD(cpustate);
320
PUSH(cpustate, adr>>8);
321
PUSH(cpustate, adr&0xff);
324
INLINE void sc61860_execute_table_call(sc61860_state *cpustate)
327
for (i=0; i<cpustate->h; i++) {
329
adr=READ_OP_ARG_WORD(cpustate);
330
cpustate->zero=v==READ_RAM(cpustate, A);
331
if (cpustate->zero) {
336
cpustate->pc=READ_OP_ARG_WORD(cpustate);
340
INLINE void sc61860_call(sc61860_state *cpustate, UINT16 adr)
342
PUSH(cpustate, cpustate->pc>>8);
343
PUSH(cpustate, cpustate->pc&0xff);
347
INLINE void sc61860_return(sc61860_state *cpustate)
349
UINT16 t=POP(cpustate);
354
INLINE void sc61860_jump(sc61860_state *cpustate, int yes)
356
UINT16 adr = READ_OP_ARG_WORD(cpustate);
362
INLINE void sc61860_jump_rel_plus(sc61860_state *cpustate, int yes)
364
UINT16 adr = cpustate->pc + READ_OP_ARG(cpustate);
371
INLINE void sc61860_jump_rel_minus(sc61860_state *cpustate, int yes)
373
UINT16 adr = cpustate->pc - READ_OP_ARG(cpustate);
380
INLINE void sc61860_loop(sc61860_state *cpustate)
382
UINT16 adr = cpustate->pc - READ_OP_ARG(cpustate);
383
UINT8 t = READ_RAM(cpustate, cpustate->r) - 1;
384
WRITE_RAM(cpustate, cpustate->r, t);
386
cpustate->carry=t==0xff;
387
if (!cpustate->carry) {
394
INLINE void sc61860_leave(sc61860_state *cpustate)
396
WRITE_RAM(cpustate, cpustate->r, 0);
399
INLINE void sc61860_wait(sc61860_state *cpustate)
401
int t=READ_OP(cpustate);
407
INLINE void sc61860_set_carry(sc61860_state *cpustate)
413
INLINE void sc61860_reset_carry(sc61860_state *cpustate)
419
INLINE void sc61860_out_a(sc61860_state *cpustate)
422
if (cpustate->config&&cpustate->config->outa)
423
cpustate->config->outa(cpustate->device, READ_RAM(cpustate, IA));
426
INLINE void sc61860_out_b(sc61860_state *cpustate)
429
if (cpustate->config&&cpustate->config->outb)
430
cpustate->config->outb(cpustate->device, READ_RAM(cpustate, IB));
433
INLINE void sc61860_out_f(sc61860_state *cpustate)
436
/*READ_RAM(cpustate, F0); */
444
c4 beeper frequency (1 4khz, 0 2khz), or (c5=0) membran pos1/pos2
446
c6 beeper steuerung*/
447
INLINE void sc61860_out_c(sc61860_state *cpustate)
450
if (cpustate->config&&cpustate->config->outc)
451
cpustate->config->outc(cpustate->device, READ_RAM(cpustate, C));
452
cpustate->c = READ_RAM(cpustate, C);
455
INLINE void sc61860_in_a(sc61860_state *cpustate)
458
if (cpustate->config&&cpustate->config->ina) data=cpustate->config->ina(cpustate->device);
459
WRITE_RAM(cpustate, A, data);
460
cpustate->zero=data==0;
463
INLINE void sc61860_in_b(sc61860_state *cpustate)
466
if (cpustate->config&&cpustate->config->inb) data=cpustate->config->inb(cpustate->device);
467
WRITE_RAM(cpustate, A, data);
468
cpustate->zero=data==0;
471
/* 0 systemclock 512ms
479
INLINE void sc61860_test_special(sc61860_state *cpustate)
482
if (cpustate->timer.t512ms) t|=1;
483
if (cpustate->timer.t2ms) t|=2;
484
if (cpustate->config&&cpustate->config->brk&&cpustate->config->brk(cpustate->device)) t|=8;
485
if (cpustate->config&&cpustate->config->reset&&cpustate->config->reset(cpustate->device)) t|=0x40;
486
if (cpustate->config&&cpustate->config->x&&cpustate->config->x(cpustate->device)) t|=0x80;
488
cpustate->zero=(t&READ_OP(cpustate))==0;
491
/************************************************************************************
493
***********************************************************************************/
496
INLINE void sc61860_add_bcd_a(sc61860_state *cpustate)
498
UINT8 help = READ_RAM(cpustate, A);
499
int i, hlp, hlp1 = 0;
501
for (i=0; i <= READ_RAM(cpustate, I); i++) {
502
int t = READ_RAM(cpustate, cpustate->p);
503
hlp1 = (t & 0x0f) + (help & 0x0f) + hlp1;
504
if (hlp1 > 9) { hlp = hlp1 - 0x0a; hlp1 = 0x10; }
505
else { hlp = hlp1; hlp1 = 0x00; }
506
hlp1 = (t & 0xf0) + (help & 0xf0) + hlp1;
507
if (hlp1 > 0x90) { WRITE_RAM(cpustate, cpustate->p, hlp1 - 0xa0 + hlp); hlp1 = 1; }
508
else { WRITE_RAM(cpustate, cpustate->p, hlp1 + hlp); hlp1 = 0; }
509
if ( READ_RAM(cpustate, cpustate->p) != 0 ) cpustate->zero = 0;
513
cpustate->carry= ( hlp1 ) ? 1 : 0;
514
cpustate->icount-=3*(READ_RAM(cpustate, I)+1);
518
// p-=I+1, q-=I+2 sideeffect
519
INLINE void sc61860_add_bcd(sc61860_state *cpustate)
521
int i, hlp, hlp1 = 0;
523
for (i=0; i <= READ_RAM(cpustate, I); i++) {
524
int t = READ_RAM(cpustate, cpustate->p);
525
int t2 = READ_RAM(cpustate, cpustate->q);
526
hlp1 = (t & 0x0f) + (t2 & 0x0f) + hlp1;
527
if (hlp1 > 9) { hlp = hlp1 - 0x0a; hlp1 = 0x10; }
528
else { hlp = hlp1; hlp1 = 0x00; }
529
hlp1 = (t & 0xf0) + (t2 & 0xf0) + hlp1;
531
if (hlp1 > 0x90) { WRITE_RAM(cpustate, cpustate->p, hlp1 - 0xa0 + hlp); hlp1 = 1; }
532
else { WRITE_RAM(cpustate, cpustate->p, hlp1 + hlp); hlp1 = 0; }
533
if ( READ_RAM(cpustate, cpustate->p) != 0 ) cpustate->zero = 0;
536
cpustate->carry= ( hlp1 ) ? 1 : 0;
537
cpustate->icount-=3*(READ_RAM(cpustate, I)+1);
543
INLINE void sc61860_sub_bcd_a(sc61860_state *cpustate)
545
UINT8 help = READ_RAM(cpustate, A);
546
int i, hlp, hlp1 = 0;
548
for (i=0; i <= READ_RAM(cpustate, I); i++) {
549
int t = READ_RAM(cpustate, cpustate->p);
550
hlp1 = (t & 0x0f) - (help & 0x0f) - hlp1;
551
if ( hlp1 < 0 ) { hlp = hlp1 + 0x0a; hlp1 = 0x10; }
552
else { hlp = hlp1; hlp1 = 0x00; }
553
hlp1 = (t & 0xf0) - (help & 0xf0) - hlp1;
554
if ( hlp1 < 0 ) { WRITE_RAM(cpustate, cpustate->p, hlp1 + 0xa0 + hlp); hlp1 = 1; }
555
else { WRITE_RAM(cpustate, cpustate->p, hlp1 + hlp); hlp1 = 0; }
556
if ( READ_RAM(cpustate, cpustate->p) != 0 ) cpustate->zero = 0;
560
cpustate->carry= ( hlp1 ) ? 1 : 0;
561
cpustate->icount-=3*(READ_RAM(cpustate, I)+1);
565
// p-=I+1, q-=I+2 sideeffect
566
INLINE void sc61860_sub_bcd(sc61860_state *cpustate)
568
int i, hlp, hlp1 = 0;
570
for (i=0; i <= READ_RAM(cpustate, I); i++) {
571
int t = READ_RAM(cpustate, cpustate->p);
572
int t2 = READ_RAM(cpustate, cpustate->q);
573
hlp1 = (t & 0x0f) - (t2 & 0x0f) - hlp1;
574
if ( hlp1 < 0 ) { hlp = hlp1 + 0x0a; hlp1 = 0x10; }
575
else { hlp = hlp1; hlp1 = 0x00; }
576
hlp1 = (t & 0xf0) - (t2 & 0xf0) - hlp1;
578
if ( hlp1 < 0 ) { WRITE_RAM(cpustate, cpustate->p, hlp1 + 0xa0 + hlp); hlp1 = 1; }
579
else { WRITE_RAM(cpustate, cpustate->p, hlp1 + hlp); hlp1 = 0; }
580
if ( READ_RAM(cpustate, cpustate->p) != 0 ) cpustate->zero = 0;
583
cpustate->carry= ( hlp1 ) ? 1 : 0;
584
cpustate->icount-=3*(READ_RAM(cpustate, I)+1);
588
/* side effect p-i-1 -> p correct! */
589
INLINE void sc61860_shift_left_nibble(sc61860_state *cpustate)
592
for (i=0; i<=READ_RAM(cpustate, I); i++) {
593
t |= READ_RAM(cpustate, cpustate->p)<<4;
594
WRITE_RAM(cpustate, cpustate->p, t);
601
/* side effect p+i+1 -> p correct! */
602
INLINE void sc61860_shift_right_nibble(sc61860_state *cpustate)
605
for (i=0; i<=READ_RAM(cpustate, I); i++) {
606
t |= READ_RAM(cpustate, cpustate->p);
607
WRITE_RAM(cpustate, cpustate->p, t>>4);
614
// q=reg+1 sideeffect
615
INLINE void sc61860_inc_load_dp(sc61860_state *cpustate, int reg)
617
UINT8 t = READ_RAM(cpustate, reg) + 1;
618
UINT8 t2 = READ_RAM(cpustate, reg + 1);
619
WRITE_RAM(cpustate, reg, t);
620
if (t == 0) { t2++; WRITE_RAM(cpustate, reg + 1, t2); }
621
cpustate->dp=t|(t2<<8);
625
// q=reg+1 sideeffect
626
INLINE void sc61860_dec_load_dp(sc61860_state *cpustate, int reg)
628
UINT8 t = READ_RAM(cpustate, reg) - 1;
629
UINT8 t2 = READ_RAM(cpustate, reg + 1);
630
WRITE_RAM(cpustate, reg, t);
631
if (t == 0xff) { t2--; WRITE_RAM(cpustate, reg + 1, t2); }
632
cpustate->dp=t|(t2<<8);
637
INLINE void sc61860_inc_load_dp_load(sc61860_state *cpustate)
639
sc61860_inc_load_dp(cpustate, XL);
640
WRITE_RAM(cpustate, A, READ_BYTE(cpustate, cpustate->dp));
644
INLINE void sc61860_dec_load_dp_load(sc61860_state *cpustate)
646
sc61860_dec_load_dp(cpustate, XL);
647
WRITE_RAM(cpustate, A, READ_BYTE(cpustate, cpustate->dp));
651
INLINE void sc61860_inc_load_dp_store(sc61860_state *cpustate)
653
sc61860_inc_load_dp(cpustate, YL);
654
WRITE_BYTE(cpustate, cpustate->dp, READ_RAM(cpustate, A));
658
INLINE void sc61860_dec_load_dp_store(sc61860_state *cpustate)
660
sc61860_dec_load_dp(cpustate, YL);
661
WRITE_BYTE(cpustate, cpustate->dp, READ_RAM(cpustate, A));
664
INLINE void sc61860_fill(sc61860_state *cpustate)
667
for (i=0;i<=READ_RAM(cpustate, I);i++) {
668
WRITE_RAM(cpustate, cpustate->p, READ_RAM(cpustate, A)); /* could be overwritten? */
674
INLINE void sc61860_fill_ext(sc61860_state *cpustate)
677
for (i=0;i<=READ_RAM(cpustate, I);i++) {
678
WRITE_BYTE(cpustate, cpustate->dp, READ_RAM(cpustate, A));
679
if (i!=READ_RAM(cpustate, I)) cpustate->dp++;
684
// p+=count+1, q+=count+1 sideeffects
685
INLINE void sc61860_copy(sc61860_state *cpustate, int count)
688
for (i=0; i<=count; i++) {
689
WRITE_RAM(cpustate, cpustate->p, READ_RAM(cpustate, cpustate->q));
697
// p+=count+1, dp+=count sideeffects
698
INLINE void sc61860_copy_ext(sc61860_state *cpustate, int count)
701
for (i=0; i<=count; i++) {
702
WRITE_RAM(cpustate, cpustate->p, READ_BYTE(cpustate, cpustate->dp));
704
if (i!=count) cpustate->dp++;
709
INLINE void sc61860_copy_int(sc61860_state *cpustate, int count)
712
for (i=0; i<=count; i++) {
713
UINT8 t = READ_BYTE(cpustate, (READ_RAM(cpustate, A)|(READ_RAM(cpustate, B)<<8))); /* internal rom! */
714
WRITE_RAM(cpustate, cpustate->p, t);
717
t = READ_RAM(cpustate, A) + 1;
718
WRITE_RAM(cpustate, A, t);
720
t = READ_RAM(cpustate, B) + 1;
721
WRITE_RAM(cpustate, B, t);
728
INLINE void sc61860_exchange(sc61860_state *cpustate, int count)
732
for (i=0; i<=count; i++) {
733
t = READ_RAM(cpustate, cpustate->p);
734
WRITE_RAM(cpustate, cpustate->p, READ_RAM(cpustate, cpustate->q));
735
WRITE_RAM(cpustate, cpustate->q, t);
742
INLINE void sc61860_exchange_ext(sc61860_state *cpustate, int count)
746
for (i=0; i<=count; i++) {
747
t = READ_RAM(cpustate, cpustate->p);
748
WRITE_RAM(cpustate, cpustate->p, READ_BYTE(cpustate, cpustate->dp));
750
WRITE_BYTE(cpustate, cpustate->dp, t);
751
if (i!=count) cpustate->dp++;
757
// only 1 opcode working in pc1403
758
// both opcodes working in pc1350
759
INLINE void sc61860_wait_x(sc61860_state *cpustate, int level)
762
cpustate->zero=level;
764
if (cpustate->config&&cpustate->config->x) {
765
for (c=READ_RAM(cpustate, I); c>=0; c--) {
766
UINT8 t = (READ_RAM(cpustate, cpustate->p)+1)&0x7f;
767
WRITE_RAM(cpustate, cpustate->p, t);
768
cpustate->zero=cpustate->config->x(cpustate->device);
770
if (level != cpustate->zero) break;