2 * Simulator of microcontrollers (pdk.cc)
4 * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
6 * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
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
28 //#include "ddconfig.h"
31 //#include <stdarg.h> /* for va_list */
36 //#include "i_string.h"
50 //#include "regspdk.h"
52 /*******************************************************************/
54 cl_fppa::cl_fppa(int aid
, class cl_pdk
*the_puc
, class cl_sim
*asim
):
64 * Base type of PDK controllers
67 cl_fppa::cl_fppa(int aid
, class cl_pdk
*the_puc
, struct cpu_entry
*IType
, class cl_sim
*asim
) : cl_uc(asim
)
74 int cl_fppa::init(void) {
75 cl_uc::init(); /* Memories now exist */
79 // rom = address_space(MEM_ROM_ID);
80 // ram = mem(MEM_XRAM);
83 // zero out ram(this is assumed in regression tests)
84 // for (int i = 0x0; i < 0x8000; i++) {
85 // ram->set((t_addr)i, 0);
103 void cl_fppa::reset(void) {
109 for (t_addr i
= 0; i
< io_size
; ++i
) {
114 void cl_fppa::mk_hw_elements(void)
116 // TODO: Add hardware stuff here.
118 cl_uc::mk_hw_elements();
120 add_hw(h
= new cl_dreg(this, 0, "dreg"));
124 void cl_fppa::make_memories(void)
126 class cl_address_space
*as
;
127 int rom_storage
, ram_storage
;
137 rom_storage
= 0x1000;
139 rom
= as
= new cl_address_space("rom", 0, rom_storage
, 16);
141 address_spaces
->add(as
);
142 ram
= as
= new cl_address_space("ram", 0, ram_storage
, 8);
144 address_spaces
->add(as
);
145 sfr
= as
= new cl_address_space("regs8", 0, io_size
+ 1, 8);
147 address_spaces
->add(as
);
149 class cl_address_decoder
*ad
;
150 class cl_memory_chip
*chip
;
152 chip
= new cl_chip16("rom_chip", rom_storage
, 16);
156 ad
= new cl_address_decoder(as
= rom
, chip
, 0, rom_storage
-1, 0);
158 as
->decoders
->add(ad
);
161 chip
= new cl_chip16("ram_chip", ram_storage
, 8);
165 ad
= new cl_address_decoder(as
= ram
, chip
, 0, ram_storage
-1, 0);
167 as
->decoders
->add(ad
);
170 chip
= new cl_chip16("io_chip", io_size
, 8);
174 ad
= new cl_address_decoder(as
= sfr
, chip
, 0, io_size
-1, 0);
176 as
->decoders
->add(ad
);
179 // extra byte of the IO memory will point to the A register just for the debugger
180 sfr
->get_cell(io_size
)->decode(&(rA
));
183 cSP
= sfr
->get_cell(2);
184 cF
= sfr
->get_cell(0);
190 cl_fppa::build_cmdset(class cl_cmdset
*cmdset
)
193 cl_uc::build_cmdset(cmdset
);
198 * Help command interpreter
201 struct dis_entry
*cl_fppa::dis_tbl(void) {
202 switch (type
->type
) {
204 return (disass_pdk_13
);
206 return (disass_pdk_14
);
208 return (disass_pdk_15
);
210 return NULL
;//__builtin_unreachable();
215 int cl_fppa::inst_length(t_addr
/*addr*/) {
219 int cl_fppa::inst_branch(t_addr addr
) {
222 get_disasm_info(addr
, NULL
, &b
, NULL
, NULL
);
227 bool cl_fppa::is_call(t_addr addr
) {
230 get_disasm_info(addr
, NULL
, NULL
, NULL
, &e
);
232 return e
? (e
->is_call
) : false;
235 int cl_fppa::longest_inst(void) { return 1; }
237 const char *cl_fppa::get_disasm_info(t_addr addr
, int *ret_len
, int *ret_branch
,
239 struct dis_entry
**dentry
) {
240 const char *b
= NULL
;
242 int start_addr
= addr
;
243 struct dis_entry
*instructions
;
245 switch (type
->type
) {
246 /* Dispatch to appropriate pdk port. */
248 instructions
= disass_pdk_13
;
252 instructions
= disass_pdk_14
;
256 instructions
= disass_pdk_15
;
260 return "";//__builtin_unreachable();
263 uint code
= rom
->get(addr
++);
265 while ((code
& instructions
[i
].mask
) != instructions
[i
].code
&&
266 instructions
[i
].mnemonic
)
268 dis_entry
*dis_e
= &instructions
[i
];
269 b
= instructions
[i
].mnemonic
;
272 *ret_branch
= dis_e
->branch
;
277 *immed_offset
= immed_n
;
279 *immed_offset
= (addr
- start_addr
);
282 if (ret_len
) *ret_len
= 1;
284 if (dentry
) *dentry
= dis_e
;
289 char *cl_fppa::disass(t_addr addr
)
294 int immed_offset
= 0;
295 struct dis_entry
*dis_e
;
300 b
= get_disasm_info(addr
, &len
, NULL
, &immed_offset
, &dis_e
);
304 return (strdup("UNKNOWN/INVALID"));
309 if ((*b
== ' ') && first
)
312 while (work
.len() < 6) work
.append(' ');
318 uint code
= rom
->get(addr
) & ~(uint
)dis_e
->mask
;
321 case 'k': // k immediate addressing
322 temp
.format("#0x%x", code
);
324 case 'm': // m memory addressing
326 switch (type
->type
) {
337 ;//__builtin_unreachable();
341 temp
.format("0x%x", code
);
343 case 'i': // i IO addressing
344 // TODO: Maybe add pretty printing.
346 switch (type
->type
) {
357 ;//__builtin_unreachable();
362 temp
.format("[0x%x]", code
);
364 case 'n': // n N-bit addressing
366 switch (type
->type
) {
368 n
= (code
& 0xE0) >> 5;
371 n
= (code
& 0x1C0) >> 6;
374 n
= (code
& 0x380) >> 7;
377 n
= 0;//__builtin_unreachable();
379 temp
.format("#0x%x", n
);
391 return strdup(work
.c_str());
395 cl_fppa::print_regs(class cl_console_base
*con
)
398 con
->dd_color("answer");
399 con
->dd_printf("A = %02x %3u\n", rA
, rA
);
400 con
->dd_printf(" OACZ\n");
401 con
->dd_printf("F = %02x ", rF
);
402 con
->dd_printf("%d%d%d%d\n", fO
, fA
, fC
, fZ
);
403 con
->dd_printf("SP= %02x\n", rSP
);
404 print_disass(PC
, con
);
411 int cl_fppa::exec_inst(void)
418 return (resBREAKPOINT
);
422 int status
= execute(code
);
423 if (status
== resINV_INST
)
425 //PC = instPC;//rom->inc_address(PC, -1);
426 return (resINV_INST
);
433 cl_fppa::stack_check_overflow(void)
437 class cl_stack_op
*op
;
438 op
= new cl_stack_op(stack_push
, instPC
, rSP
-1, rSP
);
439 class cl_error_stack_overflow
*e
=
440 new cl_error_stack_overflow(op
);
447 /****************************************************************************/
450 /* Set nr of active FPP */
453 cl_act_cell::write(t_mem val
)
455 val
= puc
->set_act(val
);
456 return cl_pdk_cell::write(val
);
462 cl_nuof_cell::write(t_mem val
)
464 val
= puc
->set_nuof(val
);
465 return cl_pdk_cell::write(val
);
469 cl_fppen_op::cl_fppen_op(class cl_pdk
*the_puc
, class cl_memory_cell
*acell
):
470 cl_memory_operator(acell
)
476 cl_fppen_op::write(t_mem val
)
478 return puc
->set_fppen(val
);
486 cl_pdk::cl_pdk(struct cpu_entry
*IType
, class cl_sim
*asim
):
499 class cl_fppen_op
*op
;
502 cFPPEN
= sfr
->get_cell(1);
503 op
= new cl_fppen_op(this, cFPPEN
);
505 cFPPEN
->append_operator(op
);
506 reg_cell_var(cFPPEN
, &rFPPEN
, "FPPEN", "FPP unit Enable Register");
507 mk_cvar(sfr
->get_cell(0), "FLAG", "ACC Status Flag Register");
508 mk_cvar(sfr
->get_cell(2), "SP", "Stack Pointer Register");
510 cact
= new cl_act_cell(this);
511 reg_cell_var(cact
, &act
, "fpp", "ID of actual FPPA");
513 cnuof_fpp
= new cl_nuof_cell(this);
514 reg_cell_var(cnuof_fpp
, &nuof_fpp
, "nuof_fpp", "Number of FPPs");
516 if (type
->type
== CPU_PDKX
)
534 cl_pdk::id_string(void)
552 cl_pdk::make_memories(void)
554 class cl_address_space
*as
;
555 class cl_address_decoder
*ad
;
556 class cl_memory_chip
*chip
;
557 int rom_size
= 0x1000, ram_size
=0x100;
559 rom
= as
= new cl_address_space("rom", 0, rom_size
, 16);
561 address_spaces
->add(as
);
562 ram
= as
= new cl_address_space("ram", 0, ram_size
, 8);
564 address_spaces
->add(as
);
565 sfr
= as
= new cl_address_space("regs8", 0, io_size
+ 1, 8);
567 address_spaces
->add(as
);
569 chip
= new cl_chip16("rom_chip", rom_size
, 16);
573 ad
= new cl_address_decoder(as
= rom
, chip
, 0, rom_size
-1, 0);
575 as
->decoders
->add(ad
);
578 chip
= new cl_chip16("ram_chip", ram_size
, 8);
582 ad
= new cl_address_decoder(as
= ram
, chip
, 0, ram_size
-1, 0);
584 as
->decoders
->add(ad
);
587 chip
= new cl_chip16("io_chip", io_size
, 8);
591 ad
= new cl_address_decoder(as
= sfr
, chip
, 0, io_size
-1, 0);
593 as
->decoders
->add(ad
);
598 cl_pdk::mk_fppa(int id
)
603 case CPU_PDK13
: fppa
= new cl_fppa13(id
, this, sim
); break;
604 case CPU_PDK14
: fppa
= new cl_fppa14(id
, this, sim
); break;
605 case CPU_PDK15
: fppa
= new cl_fppa15(id
, this, sim
); break;
606 case CPU_PDK16
: fppa
= new cl_fppa16(id
, this, sim
); break;
607 case CPU_PDKX
: fppa
= new cl_fppa15(id
, this, sim
); break;
608 default: fppa
= new cl_fppa14(id
, this, sim
); break;
616 cl_pdk::set_fppen(u8_t val
)
622 for (i
=0, m
=1; i
<8; i
++, m
<<=1)
631 cl_pdk::set_act(u8_t val
)
639 cl_pdk::set_nuof(u8_t val
)
673 cl_pdk::exec_inst(void)
675 while (!(rFPPEN
& (1<<act
)))
676 act
= (act
+1)%nuof_fpp
;
677 fpps
[act
]->pre_inst();
678 int ret
= fpps
[act
]->exec_inst();
679 fpps
[act
]->post_inst();
680 tick(inst_ticks
= fpps
[act
]->inst_ticks
);
684 act
= (act
+1)%nuof_fpp
;
685 while (!(rFPPEN
& (1<<act
)));
692 cl_pdk::print_regs(class cl_console_base
*con
)
696 for (i
= 0; i
<nuof_fpp
; i
++)
698 //con->dd_color((i==act)?"result":"answer");
700 con
->dd_cprintf("ui_run", "FPP%d:EN ", i
);
702 con
->dd_cprintf("ui_stop", "FPP%d:DIS ", i
);
704 con
->dd_printf("\n");
705 for (i
= 0; i
<nuof_fpp
; i
++)
707 con
->dd_color((i
==act
)?"result":"answer");
708 con
->dd_printf("A=%02x %3u ", fpps
[i
]->rA
, fpps
[i
]->rA
);
710 con
->dd_printf("\n");
711 for (i
= 0; i
<nuof_fpp
; i
++)
713 con
->dd_color((i
==act
)?"result":"answer");
714 con
->dd_printf(" OACZ ");
716 con
->dd_printf("\n");
717 for (i
= 0; i
<nuof_fpp
; i
++)
719 con
->dd_color((i
==act
)?"result":"answer");
720 con
->dd_printf("F=", fpps
[i
]->rF
);
721 con
->dd_printf("%d%d%d%d ",
722 ((fpps
[i
]->rF
&BIT_OV
)>>BITPOS_OV
),
723 ((fpps
[i
]->rF
&BIT_AC
)>>BITPOS_AC
),
724 ((fpps
[i
]->rF
&BIT_C
)>>BITPOS_C
),
725 ((fpps
[i
]->rF
&BIT_Z
)>>BITPOS_Z
));
727 con
->dd_printf("\n");
728 for (i
= 0; i
<nuof_fpp
; i
++)
730 con
->dd_color((i
==act
)?"result":"answer");
731 con
->dd_printf("SP=%02x ", fpps
[i
]->rSP
);
733 con
->dd_printf("\n");
735 for (i
=0; i
<nuof_fpp
; i
++)
737 con
->dd_color((i
==act
)?"result":"answer");
738 con
->dd_printf("FPP%d: ", i
);
739 fpps
[0]->print_disass(fpps
[i
]->PC
, con
);
744 /* End of pdk.src/pdk.cc */