#include "iecbus.h" #include #include 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