avr: initial commit
[z80.git] / avr / mem.c
1 /* MEMORY access */
2
3 #include <stdio.h>
4
5 #include <avr/io.h>
6
7 #include "i2c.h"
8 #include "bus.h"
9 #include "mem.h"
10
11 #define MEMTEST_MAX 512
12
13 static uint8_t rand(uint16_t *x)
14 {
15         *x ^= (*x <<  1);
16         *x ^= (*x >>  1);
17         *x ^= (*x << 14);
18         return(*x & 0xFF);
19 }
20
21 void mem_init(void)
22 {
23         int seed;
24         int s = 0;
25
26         mem_start();
27         seed = 0x4D7A;
28         for(uint16_t i = 0; i < MEMTEST_MAX; i++) {
29                 if(!(i%512)) printf("|");
30                 mem_write(i, rand(&seed));
31         }
32         mem_stop();
33
34         mem_start();
35         seed = 0x4D7A;
36         for(uint16_t i = 0; i < MEMTEST_MAX; i++) {
37                 if(!(i%512)) printf("-");
38                 uint8_t v1 = mem_read(i);
39                 uint8_t v2 = rand(&seed);
40
41                 if((v1 & 0xFF) != (v2 & 0xFF)) {
42                         if(!s) printf("<0x%x-", i);
43                         s = 1;
44                 } else {
45                         if(s) printf("0x%x>", i-1);
46                         s = 0;
47                 }
48         }
49         mem_stop();
50 }
51
52 void mem_start(void)
53 {
54         bus_lock();                                     /* get bus access */
55         MEMPORT |= (1 << MREQ) | (1 << RD) | (1 << WR); /* turn on pullups */
56         MEMDDR  |= (1 << MREQ) | (1 << RD) | (1 << WR); /* pins as outputs */
57 }
58
59 void mem_stop(void)
60 {
61         MEMDDR  &= ~((1 << MREQ) | (1 << RD) | (1 << WR)); /* pins as inputs */
62         i2c_write(I2C_ALOW,  0xFF);                     /* tristate PCF8574s */
63         i2c_write(I2C_AHIGH, 0xFF);
64         i2c_write(I2C_DATA,  0xFF);
65 }
66
67 uint8_t mem_read(uint16_t addr)
68 {
69         uint8_t data;
70
71         /* do a read request */
72         i2c_write(I2C_ALOW,  (addr & 0x00FF));
73         i2c_write(I2C_AHIGH, (addr & 0xFF00) >> 8);
74         i2c_write(I2C_DATA,  0xFF);
75         MEMPORT &= ~((1 << MREQ) | (1 << RD));
76         data = i2c_read(I2C_DATA);
77         MEMPORT |= (1 << MREQ) | (1 << RD);
78
79         return(data);
80 }
81
82 void mem_write(uint16_t addr, uint8_t data)
83 {
84         /* do a write request */
85         i2c_write(I2C_ALOW,  (addr & 0x00FF));
86         i2c_write(I2C_AHIGH, (addr & 0xFF00) >> 8);
87         i2c_write(I2C_DATA,  data);
88         MEMPORT &= ~((1 << MREQ) | (1 << WR));
89         MEMPORT |= (1 << MREQ) | (1 << WR);
90 }
91