initial commit
This commit is contained in:
@@ -0,0 +1,353 @@
|
||||
#include "iecbus.h"
|
||||
#include <c64/cia.h>
|
||||
#include <c64/vic.h>
|
||||
|
||||
IEC_STATUS iec_status;
|
||||
char iec_queue;
|
||||
|
||||
#define CIA2B_ATNOUT 0x08
|
||||
#define CIA2B_CLKOUT 0x10
|
||||
#define CIA2B_DATAOUT 0x20
|
||||
|
||||
#define CIA2B_CLKIN 0x40
|
||||
#define CIA2B_DATAIN 0x80
|
||||
|
||||
#pragma optimize(push)
|
||||
#pragma optimize(1)
|
||||
|
||||
// multiples of 5us
|
||||
static void delay(char n)
|
||||
{
|
||||
__asm {
|
||||
ldx n
|
||||
l1:
|
||||
dex
|
||||
bne l1
|
||||
}
|
||||
}
|
||||
|
||||
static inline void data_true(void)
|
||||
{
|
||||
cia2.pra &= ~CIA2B_DATAOUT;
|
||||
}
|
||||
|
||||
static inline void data_false(void)
|
||||
{
|
||||
cia2.pra |= CIA2B_DATAOUT;
|
||||
}
|
||||
|
||||
static inline void clock_true(void)
|
||||
{
|
||||
cia2.pra &= ~CIA2B_CLKOUT;
|
||||
}
|
||||
|
||||
static inline void cdata_true(void)
|
||||
{
|
||||
cia2.pra &= ~(CIA2B_CLKOUT | CIA2B_DATAOUT);
|
||||
}
|
||||
|
||||
static inline void clock_false(void)
|
||||
{
|
||||
cia2.pra |= CIA2B_CLKOUT;
|
||||
}
|
||||
|
||||
static inline void atn_true(void)
|
||||
{
|
||||
cia2.pra &= ~CIA2B_ATNOUT;
|
||||
}
|
||||
|
||||
static inline void atn_false(void)
|
||||
{
|
||||
cia2.pra |= CIA2B_ATNOUT;
|
||||
}
|
||||
|
||||
static inline bool data_in(void)
|
||||
{
|
||||
return (cia2.pra & CIA2B_DATAIN) != 0;
|
||||
}
|
||||
|
||||
static inline bool clock_in(void)
|
||||
{
|
||||
return (cia2.pra & CIA2B_CLKIN) != 0;
|
||||
}
|
||||
|
||||
static bool data_check(void)
|
||||
{
|
||||
char cnt = 200;
|
||||
while (cnt > 0 && data_in())
|
||||
{
|
||||
delay(5);
|
||||
cnt--;
|
||||
}
|
||||
|
||||
if (cnt)
|
||||
return true;
|
||||
else
|
||||
{
|
||||
iec_status = IEC_DATA_CHECK;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool iec_eoib(void)
|
||||
{
|
||||
clock_true();
|
||||
|
||||
while (!data_in());
|
||||
|
||||
delay(40);
|
||||
|
||||
return data_check();
|
||||
}
|
||||
|
||||
static void iec_writeb(char b)
|
||||
{
|
||||
clock_true();
|
||||
|
||||
while (!data_in());
|
||||
|
||||
delay(5);
|
||||
for(char i=0; i<8; i++)
|
||||
{
|
||||
clock_false();
|
||||
delay(5);
|
||||
if (b & 1)
|
||||
data_true();
|
||||
else
|
||||
data_false();
|
||||
clock_true();
|
||||
b >>= 1;
|
||||
delay(5);
|
||||
}
|
||||
clock_false();
|
||||
data_true();
|
||||
}
|
||||
|
||||
bool iec_write(char b)
|
||||
{
|
||||
if (iec_status == IEC_QUEUED)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
php
|
||||
sei
|
||||
}
|
||||
|
||||
iec_status = IEC_OK;
|
||||
iec_writeb(iec_queue);
|
||||
|
||||
__asm
|
||||
{
|
||||
plp
|
||||
}
|
||||
|
||||
data_check();
|
||||
}
|
||||
if (iec_status < IEC_ERROR)
|
||||
{
|
||||
iec_queue = b;
|
||||
iec_status = IEC_QUEUED;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
char iec_read(void)
|
||||
{
|
||||
while (!clock_in());
|
||||
|
||||
__asm
|
||||
{
|
||||
php
|
||||
sei
|
||||
}
|
||||
|
||||
data_true();
|
||||
|
||||
char cnt = 100;
|
||||
while (cnt > 0 && clock_in())
|
||||
cnt--;
|
||||
|
||||
if (cnt == 0)
|
||||
{
|
||||
iec_status = IEC_EOF;
|
||||
data_false();
|
||||
delay(10);
|
||||
data_true();
|
||||
|
||||
cnt = 200;
|
||||
while (cnt > 0 && clock_in())
|
||||
cnt--;
|
||||
|
||||
if (cnt == 0)
|
||||
{
|
||||
iec_status = IEC_TIMEOUT;
|
||||
|
||||
__asm
|
||||
{
|
||||
plp
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
char b = 0;
|
||||
for(char i=0; i<8; i++)
|
||||
{
|
||||
char c;
|
||||
while (!((c = cia2.pra) & CIA2B_CLKIN))
|
||||
;
|
||||
|
||||
b >>= 1;
|
||||
b |= c & 0x80;
|
||||
|
||||
while (cia2.pra & CIA2B_CLKIN)
|
||||
;
|
||||
}
|
||||
|
||||
data_false();
|
||||
|
||||
__asm
|
||||
{
|
||||
plp
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
void iec_atn(char dev, char sec)
|
||||
{
|
||||
clock_true();
|
||||
data_true();
|
||||
atn_false();
|
||||
clock_false();
|
||||
|
||||
delay(200);
|
||||
|
||||
while (data_in());
|
||||
|
||||
iec_writeb(dev);
|
||||
data_check();
|
||||
if (sec != 0xff)
|
||||
{
|
||||
iec_writeb(sec);
|
||||
data_check();
|
||||
}
|
||||
|
||||
atn_true();
|
||||
}
|
||||
|
||||
|
||||
void iec_talk(char dev, char sec)
|
||||
{
|
||||
iec_status = IEC_OK;
|
||||
|
||||
iec_atn(dev | 0x40, sec | 0x60);
|
||||
data_false();
|
||||
|
||||
__asm
|
||||
{
|
||||
php
|
||||
sei
|
||||
}
|
||||
|
||||
clock_true();
|
||||
char cnt = 200;
|
||||
while (cnt > 0 && clock_in())
|
||||
cnt--;
|
||||
|
||||
__asm
|
||||
{
|
||||
plp
|
||||
}
|
||||
|
||||
delay(10);
|
||||
}
|
||||
|
||||
void iec_untalk(void)
|
||||
{
|
||||
iec_atn(0x5f, 0xff);
|
||||
}
|
||||
|
||||
void iec_listen(char dev, char sec)
|
||||
{
|
||||
iec_status = IEC_OK;
|
||||
|
||||
iec_atn(dev | 0x20, sec | 0x60);
|
||||
}
|
||||
|
||||
void iec_unlisten(void)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
php
|
||||
sei
|
||||
}
|
||||
|
||||
if (iec_status == IEC_QUEUED)
|
||||
{
|
||||
iec_status = IEC_OK;
|
||||
iec_eoib();
|
||||
iec_writeb(iec_queue);
|
||||
data_check();
|
||||
}
|
||||
|
||||
iec_atn(0x3f, 0xff);
|
||||
clock_true();
|
||||
|
||||
__asm
|
||||
{
|
||||
plp
|
||||
}
|
||||
}
|
||||
|
||||
void iec_open(char dev, char sec, const char * fname)
|
||||
{
|
||||
iec_status = IEC_OK;
|
||||
|
||||
iec_atn(dev | 0x20, sec | 0xf0);
|
||||
|
||||
char i = 0;
|
||||
while (fname[i])
|
||||
{
|
||||
iec_write(fname[i]);
|
||||
i++;
|
||||
}
|
||||
iec_unlisten();
|
||||
}
|
||||
|
||||
void iec_close(char dev, char sec)
|
||||
{
|
||||
iec_atn(dev | 0x20, sec | 0xe0);
|
||||
iec_unlisten();
|
||||
}
|
||||
|
||||
int iec_write_bytes(const char * data, int num)
|
||||
{
|
||||
for(int i=0; i<num; i++)
|
||||
{
|
||||
if (!iec_write(data[i]))
|
||||
return i;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
int iec_read_bytes(char * data, int num)
|
||||
{
|
||||
int i = 0;
|
||||
while (i < num)
|
||||
{
|
||||
char ch = iec_read();
|
||||
if (iec_status < IEC_ERROR)
|
||||
data[i++] = ch;
|
||||
if (iec_status != IEC_OK)
|
||||
return i;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
#pragma optimize(pop)
|
||||
|
||||
Reference in New Issue
Block a user