mirror of
https://github.com/rkujawa/rk65c02.git
synced 2024-12-13 01:29:57 +00:00
More work on devices subsystem.
This commit is contained in:
parent
7baefe9277
commit
5cec9a9784
@ -1,7 +1,7 @@
|
|||||||
CLI=rk65c02cli
|
CLI=rk65c02cli
|
||||||
CLI_OBJS=rk65c02cli.o
|
CLI_OBJS=rk65c02cli.o
|
||||||
|
|
||||||
LIB_OBJS=rk65c02.o bus.o instruction.o emulation.o debug.o
|
LIB_OBJS=rk65c02.o bus.o instruction.o emulation.o debug.o device_ram.o
|
||||||
LIB_SO=librk65c02.so
|
LIB_SO=librk65c02.so
|
||||||
LIB_STATIC=librk65c02.a
|
LIB_STATIC=librk65c02.a
|
||||||
|
|
||||||
|
77
src/bus.c
77
src/bus.c
@ -9,24 +9,69 @@
|
|||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <utlist.h>
|
||||||
|
|
||||||
#include "bus.h"
|
#include "bus.h"
|
||||||
|
|
||||||
|
#include "device_ram.h"
|
||||||
|
|
||||||
#define RK65C02_BUS_SIZE 64*1024
|
#define RK65C02_BUS_SIZE 64*1024
|
||||||
|
|
||||||
|
void
|
||||||
|
bus_device_add(bus_t *b, device_t *d, uint16_t addr)
|
||||||
|
{
|
||||||
|
device_mapping_t *dm;
|
||||||
|
|
||||||
|
dm = (device_mapping_t *) malloc(sizeof(device_mapping_t));
|
||||||
|
|
||||||
|
dm->dev = d;
|
||||||
|
dm->addr = addr;
|
||||||
|
|
||||||
|
LL_APPEND((b->dm_head), dm);
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t
|
uint8_t
|
||||||
bus_read_1(bus_t *t, uint16_t addr)
|
bus_read_1(bus_t *t, uint16_t addr)
|
||||||
{
|
{
|
||||||
uint8_t val;
|
uint8_t val;
|
||||||
// val = t->space[addr];
|
device_mapping_t *dm;
|
||||||
/* printf("bus READ @ %x value %x\n", addr, val); */
|
device_t *d;
|
||||||
|
|
||||||
|
LL_FOREACH(t->dm_head, dm) {
|
||||||
|
d = dm->dev;
|
||||||
|
|
||||||
|
if (dm->addr == 0)
|
||||||
|
val = d->read_1(d, addr);
|
||||||
|
/*
|
||||||
|
* else
|
||||||
|
* Check if address is inside of given device range, calculate
|
||||||
|
* offset.
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
printf("bus READ @ %x value %x\n", addr, val);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
bus_write_1(bus_t *t, uint16_t addr, uint8_t val)
|
bus_write_1(bus_t *t, uint16_t addr, uint8_t val)
|
||||||
{
|
{
|
||||||
/* printf("bus WRITE @ %x value %x\n", addr, val); */
|
device_mapping_t *dm;
|
||||||
// t->space[addr] = val;
|
device_t *d;
|
||||||
|
|
||||||
|
LL_FOREACH(t->dm_head, dm) {
|
||||||
|
d = dm->dev;
|
||||||
|
|
||||||
|
if (dm->addr == 0)
|
||||||
|
d->write_1(d, addr, val);
|
||||||
|
/*
|
||||||
|
* else
|
||||||
|
* Check if address is inside of given device range, calculate
|
||||||
|
* offset.
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
printf("bus WRITE @ %x value %x\n", addr, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
bus_t
|
bus_t
|
||||||
@ -34,15 +79,23 @@ bus_init()
|
|||||||
{
|
{
|
||||||
bus_t t;
|
bus_t t;
|
||||||
|
|
||||||
// t.space = (uint8_t *) malloc(RK65C02_BUS_SIZE);
|
t.dm_head = NULL;
|
||||||
|
|
||||||
// assert(t.space != NULL);
|
|
||||||
|
|
||||||
// memset(t.space, 0, RK65C02_BUS_SIZE);
|
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
|
bus_t
|
||||||
|
bus_init_with_default_devs()
|
||||||
|
{
|
||||||
|
bus_t t;
|
||||||
|
|
||||||
|
t = bus_init();
|
||||||
|
|
||||||
|
bus_device_add(&t, device_ram_init(), 0x0);
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
bus_load_buf(bus_t *t, uint16_t addr, uint8_t *buf, uint16_t bufsize)
|
bus_load_buf(bus_t *t, uint16_t addr, uint8_t *buf, uint16_t bufsize)
|
||||||
{
|
{
|
||||||
@ -53,13 +106,13 @@ bus_load_buf(bus_t *t, uint16_t addr, uint8_t *buf, uint16_t bufsize)
|
|||||||
// XXX: add sanity checks
|
// XXX: add sanity checks
|
||||||
|
|
||||||
while (i < bufsize) {
|
while (i < bufsize) {
|
||||||
t->space[addr+i] = buf[i]; // XXX: overflow addr
|
bus_write_1(t, i, buf[i]); // XXX: overflow addr
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
bool
|
bool
|
||||||
bus_load_file(bus_t *t, uint16_t addr, const char *filename)
|
bus_load_file(bus_t *t, uint16_t addr, const char *filename)
|
||||||
{
|
{
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#define RK65C02_BUS_SIZE 64*1024
|
#define RK65C02_BUS_SIZE 64*1024
|
||||||
|
|
||||||
struct bus_tag {
|
struct bus_tag {
|
||||||
device_t *device_head;
|
device_mapping_t *dm_head;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct bus_tag bus_t;
|
typedef struct bus_tag bus_t;
|
||||||
@ -18,7 +18,7 @@ uint8_t bus_read_1(bus_t *, uint16_t);
|
|||||||
void bus_write_1(bus_t *, uint16_t, uint8_t);
|
void bus_write_1(bus_t *, uint16_t, uint8_t);
|
||||||
bus_t bus_init();
|
bus_t bus_init();
|
||||||
void bus_finish(bus_t *);
|
void bus_finish(bus_t *);
|
||||||
bool bus_load_file(bus_t *, uint16_t, const char *);
|
//bool bus_load_file(bus_t *, uint16_t, const char *);
|
||||||
bool bus_load_buf(bus_t *, uint16_t, uint8_t *, uint16_t);
|
bool bus_load_buf(bus_t *, uint16_t, uint8_t *, uint16_t);
|
||||||
|
|
||||||
#endif /* _BUS_H_ */
|
#endif /* _BUS_H_ */
|
||||||
|
31
src/device.h
31
src/device.h
@ -1,27 +1,24 @@
|
|||||||
#ifndef _DEVICE_H_
|
#ifndef _DEVICE_H_
|
||||||
#define _DEVICE_H_
|
#define _DEVICE_H_
|
||||||
|
|
||||||
//#include "bus.h"
|
|
||||||
|
|
||||||
typedef struct device_space_t {
|
|
||||||
//uint8_t id;
|
|
||||||
uint16_t address;
|
|
||||||
uint16_t size;
|
|
||||||
|
|
||||||
uint8_t (*read_1)(uint16_t addr);
|
|
||||||
void (*write_1)(uint16_t addr, uint8_t val);
|
|
||||||
|
|
||||||
void *aux; /* any additional space-specific data */
|
|
||||||
|
|
||||||
struct device_space_t *next;
|
|
||||||
} device_space_t;
|
|
||||||
|
|
||||||
typedef struct device_t {
|
typedef struct device_t {
|
||||||
const char *name;
|
const char *name;
|
||||||
device_space_t *space_head;
|
|
||||||
|
|
||||||
struct device_t *next;
|
uint16_t size;
|
||||||
|
|
||||||
|
uint8_t (*read_1)(void *, uint16_t doff);
|
||||||
|
void (*write_1)(void *, uint16_t, uint8_t val);
|
||||||
|
|
||||||
|
void *config;
|
||||||
|
void *aux; /* any dev space-specific data */
|
||||||
} device_t;
|
} device_t;
|
||||||
|
|
||||||
|
typedef struct device_mapping_t {
|
||||||
|
device_t *dev;
|
||||||
|
uint16_t addr;
|
||||||
|
|
||||||
|
struct device_mapping_t *next;
|
||||||
|
} device_mapping_t;
|
||||||
|
|
||||||
#endif /* _DEVICE_H_ */
|
#endif /* _DEVICE_H_ */
|
||||||
|
|
||||||
|
@ -1,8 +1,57 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "bus.h"
|
#include "bus.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
|
|
||||||
bool
|
#define RAM_SIZE 0xDFFF /* should be configurable */
|
||||||
device_ram_add(bus_t *t)
|
|
||||||
|
uint8_t
|
||||||
|
device_ram_read_1(void *vd, uint16_t offset)
|
||||||
{
|
{
|
||||||
|
device_t *d;
|
||||||
|
uint8_t *ram;
|
||||||
|
|
||||||
|
d = (device_t *) vd;
|
||||||
|
ram = d->aux;
|
||||||
|
|
||||||
|
return ram[offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
device_ram_write_1(void *vd, uint16_t offset, uint8_t val)
|
||||||
|
{
|
||||||
|
device_t *d;
|
||||||
|
uint8_t *ram;
|
||||||
|
|
||||||
|
d = (device_t *) vd;
|
||||||
|
ram = d->aux;
|
||||||
|
|
||||||
|
ram[offset] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
device_t *
|
||||||
|
device_ram_init()
|
||||||
|
{
|
||||||
|
device_t *d;
|
||||||
|
|
||||||
|
d = (device_t *) malloc(sizeof(device_t));
|
||||||
|
|
||||||
|
assert(d != NULL);
|
||||||
|
|
||||||
|
d->name = "RAM";
|
||||||
|
d->size = RAM_SIZE;
|
||||||
|
|
||||||
|
d->read_1 = device_ram_read_1;
|
||||||
|
d->write_1 = device_ram_write_1;
|
||||||
|
|
||||||
|
d->aux = malloc(RAM_SIZE);
|
||||||
|
memset(d->aux, 0, RAM_SIZE);
|
||||||
|
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: device_ram_finish */
|
||||||
|
|
||||||
|
8
src/device_ram.h
Normal file
8
src/device_ram.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#ifndef _DEVICE_RAM_H_
|
||||||
|
#define _DEVICE_RAM_H_
|
||||||
|
|
||||||
|
#include "device.h"
|
||||||
|
|
||||||
|
device_t * device_ram_init();
|
||||||
|
|
||||||
|
#endif /* _DEVICE_RAM_H_ */
|
Loading…
Reference in New Issue
Block a user