#include "bus.h" #include #include static device_vtable_t const bus_vtable = { bus_read, bus_write, #ifdef WITH_GUI bus_draw, #endif bus_deinit }; void bus_init( bus_t *bus ) { device_init( &bus->base, "bus" ); ((device_t *)bus)->vtable = (device_vtable_t *)&bus_vtable; bus->nof_devices = 0; } void bus_register( bus_t *bus, device_t *device, uint16_t from, uint16_t to ) { if( bus->nof_devices < MAX_NOF_DEVICES ) { registered_device_t *reg = &bus->devices[bus->nof_devices]; reg->device = device; reg->from = from; reg->to = to; bus->nof_devices++; } else { fprintf( stderr, "ERROR: too many devices on bus\n" ); exit( EXIT_FAILURE ); } } uint8_t bus_read( void *obj, uint16_t addr ) { bus_t *bus = (bus_t *)obj; for( int i = 0; i < bus->nof_devices; i++ ) { registered_device_t *reg = &bus->devices[i]; if( reg->from <= addr && addr <= reg->to ) { return reg->device->vtable->read( reg->device, addr ); } } fprintf( stderr, "ERROR: illegal bus access reading from address %04X\n", addr ); return 0; } void bus_write( void *obj, uint16_t addr, uint8_t data ) { bus_t *bus = (bus_t *)obj; for( int i = 0; i < bus->nof_devices; i++ ) { registered_device_t *reg = &bus->devices[i]; if( reg->from <= addr && addr <= reg->to ) { reg->device->vtable->write( reg->device, addr, data ); return; } } fprintf( stderr, "ERROR: illegal bus access writing to address %04X\n", addr ); } #ifdef WITH_GUI void bus_draw( void *obj, SDL_Renderer *renderer ) { bus_t *bus = (bus_t *)obj; for( int i = 0; i < bus->nof_devices; i++ ) { device_t *device = bus->devices[i].device; device->vtable->draw( device, renderer ); } } #endif void bus_deinit( void *obj ) { bus_t *bus = (bus_t *)obj; for( int i = bus->nof_devices - 1; i >= 0; i-- ) { registered_device_t *reg = &bus->devices[i]; reg->device->vtable->deinit( reg->device ); } bus->nof_devices = 0; device_deinit( &bus->base ); }