Skip to content

Commit

Permalink
Extremely early WIP PCMCIA
Browse files Browse the repository at this point in the history
  • Loading branch information
Cacodemon345 committed May 29, 2024
1 parent e61c620 commit 89ecdd6
Show file tree
Hide file tree
Showing 7 changed files with 364 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ endif()
add_executable(86Box 86box.c config.c log.c random.c timer.c io.c acpi.c apm.c
dma.c ddma.c nmi.c pic.c pit.c pit_fast.c port_6x.c port_92.c ppi.c pci.c
mca.c usb.c fifo.c fifo8.c device.c nvr.c nvr_at.c nvr_ps2.c
machine_status.c ini.c cJSON.c)
machine_status.c ini.c cJSON.c pcmcia.c)

if(CMAKE_SYSTEM_NAME MATCHES "Linux")
add_compile_definitions(_FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE=1 _LARGEFILE64_SOURCE=1)
Expand Down Expand Up @@ -78,7 +78,7 @@ if(INSTRUMENT)
endif()

target_link_libraries(86Box cpu chipset mch dev mem fdd game cdrom zip mo hdd
net print scsi sio snd vid voodoo plat ui)
net print scsi sio snd vid voodoo pcmcia plat ui)

if(WIN32 AND ARCH STREQUAL "i386")
if(MINGW)
Expand Down
27 changes: 27 additions & 0 deletions src/include/86box/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,35 @@
#ifndef EMU_IO_H
#define EMU_IO_H

typedef struct _io_range_ {
uint8_t (*inb)(uint16_t addr, void *priv);
uint16_t (*inw)(uint16_t addr, void *priv);
uint32_t (*inl)(uint16_t addr, void *priv);

void (*outb)(uint16_t addr, uint8_t val, void *priv);
void (*outw)(uint16_t addr, uint16_t val, void *priv);
void (*outl)(uint16_t addr, uint32_t val, void *priv);

void *priv;

uint16_t start;
uint16_t end;

uint8_t enable;
} io_range_t;

extern void io_init(void);

extern io_range_t* io_range_addhandler(uint16_t start, uint16_t end,
uint8_t (*inb)(uint16_t addr, void *priv),
uint16_t (*inw)(uint16_t addr, void *priv),
uint32_t (*inl)(uint16_t addr, void *priv),
void (*outb)(uint16_t addr, uint8_t val, void *priv),
void (*outw)(uint16_t addr, uint16_t val, void *priv),
void (*outl)(uint16_t addr, uint32_t val, void *priv),
uint8_t enable,
void *priv);

extern void io_sethandler_common(uint16_t base, int size,
uint8_t (*inb)(uint16_t addr, void *priv),
uint16_t (*inw)(uint16_t addr, void *priv),
Expand Down
46 changes: 46 additions & 0 deletions src/include/86box/pcmcia.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include <stdint.h>
#include <stdbool.h>

struct pcmcia_socket_t;
typedef struct pcmcia_socket_t pcmcia_socket_t;

struct pcmcia_socket_t {
/* Socket number (zero-based) */
uint8_t socket_num;

/* Card I/O Read and Write functions. */
uint8_t (*io_read)(uint16_t port, void* priv);
uint16_t (*io_readw)(uint16_t port, void* priv);
void (*io_write)(uint16_t port, uint8_t val, void* priv);
void (*io_writew)(uint16_t port, uint16_t val, void* priv);

/* Card Memory Read and Write functions. */
/* REG = 0: Access Attribute Memory. */
/* REG = 1: Access Common Memory. */
uint8_t (*mem_read)(uint32_t addr, int reg, void* priv);
uint16_t (*mem_readw)(uint32_t addr, int reg, void* priv);
void (*mem_write)(uint32_t addr, uint8_t val, int reg, void* priv);
void (*mem_writew)(uint32_t addr, uint16_t val, int reg, void* priv);

/* Signals power status change to the card. */
void (*power_status_change)(pcmcia_socket_t* socket);

/* Signals card insertion/removal to the socket. */
void (*card_inserted)(bool inserted, pcmcia_socket_t* socket);

/* Opaque pointer to card-specific information. */
void *card_priv;

/* Opaque pointer to socket-specific information. */
void *socket_priv;

/* Card power status. */
bool powered_on;
};

typedef struct pcmcia_socket_t pcmcia_socket_t;

bool pcmcia_socket_is_free(pcmcia_socket_t* socket);
pcmcia_socket_t* pcmcia_search_for_slots(void);
void pcmcia_socket_insert_card(pcmcia_socket_t* socket);

122 changes: 122 additions & 0 deletions src/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ int initialized = 0;
io_t *io[NPORTS];
io_t *io_last[NPORTS];

io_range_t io_ranges[256];
uint32_t io_ranges_num = 0;

#ifdef ENABLE_IO_LOG
int io_do_log = ENABLE_IO_LOG;

Expand All @@ -84,6 +87,8 @@ io_init(void)
io_t *p;
io_t *q;

io_ranges_num = 0;

if (!initialized) {
for (c = 0; c < NPORTS; c++)
io[c] = io_last[c] = NULL;
Expand All @@ -108,6 +113,35 @@ io_init(void)
}
}

io_range_t*
io_range_addhandler(uint16_t start, uint16_t end,
uint8_t (*inb)(uint16_t addr, void *priv),
uint16_t (*inw)(uint16_t addr, void *priv),
uint32_t (*inl)(uint16_t addr, void *priv),
void (*outb)(uint16_t addr, uint8_t val, void *priv),
void (*outw)(uint16_t addr, uint16_t val, void *priv),
void (*outl)(uint16_t addr, uint32_t val, void *priv),
uint8_t enable,
void *priv)
{
io_range_t* io_range = NULL;
if (io_ranges_num >= 256)
return NULL;

io_range = &io_ranges[io_ranges_num];
io_range->inb = inb;
io_range->inw = inw;
io_range->inl = inl;
io_range->outb = outb;
io_range->outw = outw;
io_range->outl = outl;
io_range->priv = priv;
io_range->enable = enable;
io_ranges_num++;

return io_range;
}

void
io_sethandler_common(uint16_t base, int size,
uint8_t (*inb)(uint16_t addr, void *priv),
Expand Down Expand Up @@ -359,6 +393,7 @@ inb(uint16_t port)
qfound = 1;
#endif
} else {
int i = 0;
p = io[port];
while (p) {
q = p->next;
Expand All @@ -371,6 +406,15 @@ inb(uint16_t port)
}
p = q;
}

if (UNLIKELY(io_ranges_num)) {
for (i = 0; i < io_ranges_num; i++) {
if (io_ranges[i].start >= port && port <= io_ranges[i].end && io_ranges[i].enable && io_ranges[i].inb) {
ret &= io_ranges[i].inb(port, io_ranges[i].priv);
found |= 1;
}
}
}
}

if (amstrad_latch & 0x80000000) {
Expand Down Expand Up @@ -435,6 +479,16 @@ outb(uint16_t port, uint8_t val)
}
p = q;
}

if (UNLIKELY(io_ranges_num)) {
int i = 0;
for (i = 0; i < io_ranges_num; i++) {
if (io_ranges[i].start >= port && port <= io_ranges[i].end && io_ranges[i].enable && io_ranges[i].outb) {
io_ranges[i].outb(port, val, io_ranges[i].priv);
found |= 1;
}
}
}
}

if (!found) {
Expand Down Expand Up @@ -509,6 +563,19 @@ inw(uint16_t port)
}
}
ret = (ret8[1] << 8) | ret8[0];

if (UNLIKELY(io_ranges_num)) {
int i = 0;
for (i = 0; i < io_ranges_num; i++) {
if (io_ranges[i].start >= port && port <= io_ranges[i].end && io_ranges[i].enable) {
if (io_ranges[i].inw)
ret &= io_ranges[i].inw(port, io_ranges[i].priv);
else
ret &= (io_ranges[i].inb(port, io_ranges[i].priv)) | (io_ranges[i].inb(port + 1, io_ranges[i].priv) << 8);
found |= 1;
}
}
}
}

if (amstrad_latch & 0x80000000) {
Expand Down Expand Up @@ -582,6 +649,21 @@ outw(uint16_t port, uint16_t val)
p = q;
}
}

if (UNLIKELY(io_ranges_num)) {
int i = 0;
for (i = 0; i < io_ranges_num; i++) {
if (io_ranges[i].start >= port && port <= io_ranges[i].end && io_ranges[i].enable) {
if (io_ranges[i].outw)
io_ranges[i].outw(port, val, io_ranges[i].priv);
else {
io_ranges[i].outb(port, val & 0xFF, io_ranges[i].priv);
io_ranges[i].outb(port + 1, val >> 8, io_ranges[i].priv);
}
found |= 1;
}
}
}
}

if (!found) {
Expand Down Expand Up @@ -688,6 +770,24 @@ inl(uint16_t port)
}
}
ret = (ret8[3] << 24) | (ret8[2] << 16) | (ret8[1] << 8) | ret8[0];

if (UNLIKELY(io_ranges_num)) {
int i = 0;
for (i = 0; i < io_ranges_num; i++) {
if (io_ranges[i].start >= port && port <= io_ranges[i].end && io_ranges[i].enable) {
if (io_ranges[i].inl)
ret &= io_ranges[i].inl(port, io_ranges[i].priv);
else if (io_ranges[i].inw)
ret &= io_ranges[i].inw(port, io_ranges[i].priv) | (io_ranges[i].inw(port + 2, io_ranges[i].priv) << 16);
else
ret &= io_ranges[i].inb(port, io_ranges[i].priv)
| (io_ranges[i].inb(port + 1, io_ranges[i].priv) << 8)
| (io_ranges[i].inb(port + 2, io_ranges[i].priv) << 16)
| (io_ranges[i].inb(port + 3, io_ranges[i].priv) << 24);
found |= 1;
}
}
}
}

if (amstrad_latch & 0x80000000) {
Expand Down Expand Up @@ -779,6 +879,28 @@ outl(uint16_t port, uint32_t val)
p = q;
}
}

if (UNLIKELY(io_ranges_num)) {
int i = 0;
for (i = 0; i < io_ranges_num; i++) {
if (io_ranges[i].start >= port && port <= io_ranges[i].end && io_ranges[i].enable) {
if (io_ranges[i].outl) {
io_ranges[i].outl(port, val, io_ranges[i].priv);
}
else if (io_ranges[i].outw) {
io_ranges[i].outw(port, val, io_ranges[i].priv);
io_ranges[i].outw(port + 2, val >> 16, io_ranges[i].priv);
}
else {
io_ranges[i].outb(port, val & 0xFF, io_ranges[i].priv);
io_ranges[i].outb(port + 1, val >> 8, io_ranges[i].priv);
io_ranges[i].outb(port + 2, val >> 16, io_ranges[i].priv);
io_ranges[i].outb(port + 3, val >> 24, io_ranges[i].priv);
}
found |= 1;
}
}
}
}

if (!found) {
Expand Down
39 changes: 39 additions & 0 deletions src/pcmcia.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include <stdarg.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/io.h>
#include <86box/timer.h>
#include <86box/pcmcia.h>

static pcmcia_socket_t pcmcia_sockets[4];
static uint8_t pcmcia_registered_sockets_num = 0;

bool pcmcia_socket_is_free(pcmcia_socket_t *socket)
{
return !socket->card_priv;
}

pcmcia_socket_t* pcmcia_search_for_slots(void)
{
for (int i = 0; i < pcmcia_registered_sockets_num; i++) {
if (!pcmcia_sockets[i].card_priv)
return &pcmcia_sockets[i];
}
return NULL;
}

void pcmcia_socket_insert_card(pcmcia_socket_t* socket)
{
if (!socket->card_inserted)
fatal("No PCMCIA socket insertion function!\n");

socket->card_priv = socket->card_priv;
socket->card_inserted(true, socket);
}

1 change: 1 addition & 0 deletions src/pcmcia/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add_library(pcmcia pcmcia_socket_pd6710.c)
Loading

0 comments on commit 89ecdd6

Please sign in to comment.