// license:BSD-3-Clause // copyright-holders:Kevin Thacker #include #include "oric_tap.h" #define ORIC_WAV_DEBUG 0 #define LOG(x) do { if (ORIC_WAV_DEBUG) printf x; } while (0) /* this code based heavily on tap2wav by Fabrice Frances */ #define ORIC_SYNC_BYTE 0x016 /* frequency of wave */ /* tapes use 1200Hz and 2400Hz samples */ #define ORIC_WAV_FREQUENCY 4800 /* 13 bits define a byte on the cassette */ /* 1 start bit, 8 data bits, 1 parity bit and 3 stop bits */ #define ORIC_BYTE_TO_BITS_ON_CASSETTE 13 #define ORIC_WAVESAMPLES_HEADER 3000 #define ORIC_WAVESAMPLES_TRAILER 1000 enum { ORIC_CASSETTE_SEARCHING_FOR_SYNC_BYTE, ORIC_CASSETTE_GOT_SYNC_BYTE, ORIC_CASSETTE_READ_HEADER, ORIC_CASSETTE_READ_FILENAME, ORIC_CASSETTE_WRITE_DATA }; #define WAVEENTRY_LOW -32768 #define WAVEENTRY_HIGH 32767 #define WAVEENTRY_NULL 0 #define ORIC_LEADER_LENGTH 512 struct oric_t { int cassette_state; int data_count; int data_length; int tap_size; }; static oric_t oric; /* to write a bit to the tape, the rom routines output either 4 periods at 1200 Hz for a 0 or 8 periods at 2400 Hz for a 1 */ /* 4800 is twice 2400Hz */ /* 8 periods at 2400Hz */ /* hi,lo, hi,lo, hi,lo, hi,lo */ static int16_t *oric_emit_level(int16_t *p, int count, int16_t wave_state) { int i; for (i=0; i leader 1 * data byte 0x024 -> sync byte 9 * data byte -> header delay (of last pulse written) x * data byte -> length header structure: 3 * ? -> ??? 1 * ? -> ??? 1 * x -> end address high byte 1 * x -> end address low byte 1 * x -> start address high byte 1 * x -> start address low byte 1 * ? -> ??? */ static int oric_calculate_byte_size_in_samples(uint8_t byte) { int count; int i; uint8_t parity; uint8_t data; count = 0; /* start bit */ count+=oric_get_bit_size_in_samples(0); /* set initial parity */ parity = 1; /* data bits, written bit 0, bit 1...bit 7 */ data = byte; for (i=0; i<8; i++) { uint8_t data_bit; data_bit = data & 0x01; parity = parity + data_bit; count+=oric_get_bit_size_in_samples(data_bit); data = data>>1; } /* parity */ count+=oric_get_bit_size_in_samples((parity & 0x01)); /* stop bits */ count+=oric_get_bit_size_in_samples(1); count+=oric_get_bit_size_in_samples(1); count+=oric_get_bit_size_in_samples(1); count+=oric_get_bit_size_in_samples(1); return count; } static int16_t *oric_output_byte(int16_t *p, uint8_t byte) { int i; uint8_t parity; uint8_t data; /* start bit */ p = oric_output_bit(p, 0); /* set initial parity */ parity = 1; /* data bits, written bit 0, bit 1...bit 7 */ data = byte; for (i=0; i<8; i++) { uint8_t data_bit; data_bit = data & 0x01; parity = parity + data_bit; p = oric_output_bit(p, data_bit); data = data>>1; } /* parity */ p = oric_output_bit(p, parity & 0x01); /* stop bits */ p = oric_output_bit(p, 1); p = oric_output_bit(p, 1); p = oric_output_bit(p, 1); p = oric_output_bit(p, 1); return p; } static int16_t *oric_fill_pause(int16_t *p, int sample_count) { int i; for (i=0; i