[ucsim-z80] Fix #3828: uCsim SM83 flags simulation
[sdcc.git] / sdcc / sim / ucsim / src / sims / pdk.src / wdt.cc
blob379b296adf508356835b838475ec7f64baca6dd6
1 /*
2 * Simulator of microcontrollers (wdt.cc)
4 * Copyright (C) 2024 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 "osccl.h"
30 #include "wdtcl.h"
33 cl_wdt::cl_wdt(class cl_uc *auc, const char *aname):
34 cl_hw(auc, HW_TIMER, 0, aname)
36 puc= (class cl_pdk *)auc;
39 int
40 cl_wdt::init(void)
42 mod= register_cell(puc->sfr, 3);
43 misc= register_cell(puc->sfr, 0x49);
44 cl_hw::init();
45 uc->mk_mvar(cfg, wdt_cnt, "WDT", cfg_help(wdt_cnt));
46 reset();
47 return 0;
50 const char *
51 cl_wdt::cfg_help(t_addr addr)
53 switch ((enum wdt_cfg)addr)
55 case wdt_on: return "Turn ticking of WDT on/off (bool, RW)";
56 case wdt_cnt: return "WDT counter value (RW)";
57 case wdt_nuof: return "";
59 return "Not used";
62 void
63 cl_wdt::reset(void)
65 cnt= 0;
66 last= 0;
67 mod->set(0);
68 recalc();
71 void
72 cl_wdt::recalc(void)
74 run= mod->get() & 2;
75 set_len();
76 last= puc->osc->ilrc;
79 void
80 cl_wdt::set_len(void)
82 u8_t v= misc->get();
83 switch (v&3)
85 case 0: len= 8192; break;
86 case 1: len= 16384; break;
87 case 2: len= 65536; break;
88 case 3: len= 262144; break;
92 void
93 cl_wdt::write(class cl_memory_cell *cell, t_mem *val)
95 if (conf(cell, val))
96 return;
97 if (cell == mod)
99 if ((*val & 0xff) != cell->get())
101 cell->set(*val);
102 recalc();
105 else if (cell == misc)
107 if ((*val & 0xff) != cell->get())
109 cell->set(*val);
110 recalc();
113 /*else if (cell == irq)
116 cell->set(*val);
119 t_mem
120 cl_wdt::conf_op(cl_memory_cell *cell, t_addr addr, t_mem *val)
122 switch (addr)
124 case wdt_on: // turn this HW on/off
125 if (val)
126 on= *val;
127 else
128 cell->set(on?1:0);
129 break;
130 case wdt_cnt:
131 if (val)
132 cnt= *val & 0xffffff;
133 else
134 cell->set(cnt);
135 break;
137 return cell->get();
141 cl_wdt::tick(int cycles)
143 t_mem act= puc->osc->ilrc;
144 if (run && (act != last))
146 int d= act - last, i;
147 if (d<0) d= -d;
148 if (d)
150 cnt+= d;
151 if (cnt > len)
152 puc->reset();
154 last= act;
156 return 0;
159 void
160 cl_wdt::print_info(class cl_console_base *con)
162 con->dd_printf("WDT run=%s len=%u\n",
163 run?"YES":"NO", MU(len));
164 con->dd_printf("cnt= %6u 0x%08x\n", MU(cnt), MU(cnt));
168 /* End of pdk.src/wdt.cc */