157a624236dc948b6b319603b3e50259c16f0654
[simavr] / simavr / sim / avr_ioport.c
1 /*
2         avr_ioport.c
3
4         Copyright 2008, 2009 Michel Pollet <buserror@gmail.com>
5
6         This file is part of simavr.
7
8         simavr is free software: you can redistribute it and/or modify
9         it under the terms of the GNU General Public License as published by
10         the Free Software Foundation, either version 3 of the License, or
11         (at your option) any later version.
12
13         simavr is distributed in the hope that it will be useful,
14         but WITHOUT ANY WARRANTY; without even the implied warranty of
15         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16         GNU General Public License for more details.
17
18         You should have received a copy of the GNU General Public License
19         along with simavr.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include <stdio.h>
23 #include "avr_ioport.h"
24
25 static void avr_ioport_run(avr_t * avr, avr_io_t * port)
26 {
27         //printf("%s\n", __FUNCTION__);
28 }
29
30 static uint8_t avr_ioport_read(struct avr_t * avr, uint8_t addr, void * param)
31 {
32         avr_ioport_t * p = (avr_ioport_t *)param;
33         uint8_t v = avr->data[addr];
34
35         if (addr == p->r_pin) {
36                 uint8_t v = avr->data[p->r_port];
37                 avr->data[addr] = v;
38                 // made to trigger potential watchpoints
39                 v = avr_core_watch_read(avr, addr);
40 //              printf("** PIN%c(%02x) = %02x\n", p->name, addr, v);
41         }
42         return v;
43 }
44
45 static void avr_ioport_write(struct avr_t * avr, uint8_t addr, uint8_t v, void * param)
46 {
47         avr_ioport_t * p = (avr_ioport_t *)param;
48         uint8_t oldv = avr->data[addr];
49
50         if (addr == p->r_port) {
51         //      printf("PORT%c(%02x) = %02x (was %02x)\n", p->name, addr, v, oldv);
52
53                 avr_core_watch_write(avr, addr, v);
54                 if (v != oldv) {
55                         int raise = 1;
56                         int mask = v ^ oldv;
57                         if (p->r_pcint)
58                                 raise = avr->data[p->r_pcint] & mask;
59                         if (raise)
60                                 avr_raise_interupt(avr, &p->pcint);
61                 }
62
63
64                 if (p->name == 'D') {
65                         static int cs = -1;
66                         if ((oldv & 0xf0) != (v & 0xf0)) {
67                                 for (int i = 0; i < 4; i++) {
68                                         
69                                 }
70                         } 
71                         {
72                         }
73                 }
74         }
75 }
76
77 static void avr_ioport_reset(avr_t * avr, avr_io_t * port)
78 {
79 }
80
81 static  avr_io_t        _io = {
82         .kind = "io",
83         .run = avr_ioport_run,
84         .reset = avr_ioport_reset,
85 };
86
87 void avr_ioport_init(avr_t * avr, avr_ioport_t * port)
88 {
89         port->io = _io;
90         printf("%s PIN%c 0x%02x DDR%c 0x%02x PORT%c 0x%02x\n",
91                 __FUNCTION__,
92                 port->name, port->r_pin,
93                 port->name, port->r_ddr,
94                 port->name, port->r_port);
95
96         avr_register_io(avr, &port->io);
97         avr_register_vector(avr, &port->pcint);
98
99         avr_register_io_write(avr, port->r_port, avr_ioport_write, port);
100         avr_register_io_read(avr, port->r_pin, avr_ioport_read, port);
101 }
102