Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix DCD-floppy contention #689

Merged
merged 5 commits into from
Dec 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pico/mac/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ add_executable(commands commands.c)

# by default the header is generated into the build dir
pico_generate_pio_header(commands ${CMAKE_CURRENT_LIST_DIR}/commands.pio)
pico_generate_pio_header(commands ${CMAKE_CURRENT_LIST_DIR}/enand.pio)
pico_generate_pio_header(commands ${CMAKE_CURRENT_LIST_DIR}/echo.pio)
pico_generate_pio_header(commands ${CMAKE_CURRENT_LIST_DIR}/latch.pio)
pico_generate_pio_header(commands ${CMAKE_CURRENT_LIST_DIR}/mux.pio)
Expand Down
79 changes: 54 additions & 25 deletions pico/mac/commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#include "commands.pio.h"
#include "echo.pio.h"
#include "enand.pio.h"
#include "latch.pio.h"
#include "mux.pio.h"

Expand All @@ -34,14 +35,16 @@
// define GPIO pins
#define UART_TX_PIN 4
#define UART_RX_PIN 5
#define ENABLE 7
#define MCI_CA0 8
#define EN0
#define EN1
#define ENABLE 11 // was 7 - swap order of CA and EN
#define MCI_CA0 6 // was 8 - move CA down to EN
#define MCI_WR 15
#define ECHO_IN 21
#define TACH_OUT 21
#define ECHO_OUT 18
#define ECHO_OUT 19
#define MUX_OUT 18
#define LATCH_OUT 20
#define LATCH_OUT 18

/**
* HERE STARTS PIO DEFINITIONS AND HEADERS
Expand All @@ -68,14 +71,12 @@ void pio_commands(PIO pio, uint sm, uint offset, uint pin);
void pio_echo(PIO pio, uint sm, uint offset, uint in_pin, uint out_pin, uint num_pins);
// void pio_latch(PIO pio, uint sm, uint offset, uint in_pin, uint out_pin);
void pio_mux(PIO pio, uint sm, uint offset, uint in_pin, uint mux_pin);

void pio_enand(PIO pio, uint sm, uint offset, uint in_pin, uint out_pin);
void pio_dcd_commands(PIO pio, uint sm, uint offset, uint pin);
void pio_dcd_read(PIO pio, uint sm, uint offset, uint pin);
void pio_dcd_write(PIO pio, uint sm, uint offset, uint pin);
void set_num_dcd();



/**
* HERE IS UART SETUP
*/
Expand Down Expand Up @@ -503,6 +504,25 @@ void esp_loop()
break;
}
}

if (!pio_sm_is_rx_fifo_empty(pioblk_rw, SM_MUX))
{
int m = pio_sm_get_blocking(pioblk_rw, SM_MUX);
// printf("m%dm",m);
if (m != 0)
{
active_disk_number = num_dcd_drives + 'A' - m;
printf("%c", active_disk_number);
uart_putc_raw(UART_ID, active_disk_number);
}
else
{
// if (!latch_val(CSTIN))
// pio_sm_put_blocking(pioblk_rw, SM_LATCH, get_latch()); // send the register word to the PIO
if (disk_mode != FPY)
disk_mode = TO_FPY;
}
}
}

void floppy_loop()
Expand Down Expand Up @@ -653,24 +673,24 @@ void dcd_loop()
return;
}

if (!pio_sm_is_rx_fifo_empty(pioblk_rw, SM_MUX))
{
int m = pio_sm_get_blocking(pioblk_rw, SM_MUX);
// printf("m%dm",m);
if (m != 0)
{
active_disk_number = num_dcd_drives + 'A' - m;
printf("%c", active_disk_number);
uart_putc_raw(UART_ID, active_disk_number);
}
else
{
// if (!latch_val(CSTIN))
// pio_sm_put_blocking(pioblk_rw, SM_LATCH, get_latch()); // send the register word to the PIO
disk_mode = TO_FPY;
return;
}
}
// if (!pio_sm_is_rx_fifo_empty(pioblk_rw, SM_MUX))
// {
// int m = pio_sm_get_blocking(pioblk_rw, SM_MUX);
// // printf("m%dm",m);
// if (m != 0)
// {
// active_disk_number = num_dcd_drives + 'A' - m;
// printf("%c", active_disk_number);
// uart_putc_raw(UART_ID, active_disk_number);
// }
// else
// {
// // if (!latch_val(CSTIN))
// // pio_sm_put_blocking(pioblk_rw, SM_LATCH, get_latch()); // send the register word to the PIO
// disk_mode = TO_FPY;
// return;
// }
// }

if (!pio_sm_is_rx_fifo_empty(pioblk_read_only, SM_DCD_CMD))
{
Expand Down Expand Up @@ -1266,6 +1286,11 @@ void pio_echo(PIO pio, uint sm, uint offset, uint in_pin, uint out_pin, uint num
pio_sm_set_enabled(pio, sm, true);
}

void pio_enand(PIO pio, uint sm, uint offset, uint in_pin, uint out_pin)
{
enand_program_init(pio, sm, offset, in_pin, out_pin);
pio_sm_set_enabled(pio, sm, true);
}

void pio_mux(PIO pio, uint sm, uint offset, uint in_pin, uint mux_pin)
{
Expand All @@ -1282,6 +1307,10 @@ void pio_dcd_commands(PIO pio, uint sm, uint offset, uint pin)
void pio_dcd_read(PIO pio, uint sm, uint offset, uint pin)
{
dcd_read_program_init(pio, sm, offset, pin);
// set y, 0 side 0 ; initial state is always 0
// set x, 7 side 0 ; bit counter
pio_sm_exec_wait_blocking(pio, sm, pio_encode_set(pio_y, 0));
pio_sm_exec_wait_blocking(pio, sm, pio_encode_set(pio_x, 7));
}

void pio_dcd_write(PIO pio, uint sm, uint offset, uint pin)
Expand Down
2 changes: 1 addition & 1 deletion pico/mac/commands.pio
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
;

.define public LSTRB 13
.define ENABLE 7
.define public ENABLE 11

.program commands
start:
Expand Down
2 changes: 1 addition & 1 deletion pico/mac/dcd_commands.pio
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
; sends the phases to the PICO when the state changes
;

.define ENABLE 7
.define public ENABLE 11

.program dcd_commands
start:
Expand Down
10 changes: 6 additions & 4 deletions pico/mac/dcd_read.pio
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,20 @@
; Vintage Macintosh Microfloppy Controller Interface
; Read NRZI stream
;
;

.define public T0 10

.program dcd_read
.side_set 1
set y, 0 side 0 ; initial state is always 0
set x, 7 side 0 ; bit counter
; manually exec the following two statements after init before enable
; set y, 0 side 0 ; initial state is always 0
; set x, 7 side 0 ; bit counter
reset:
wait 1 pin 0 side 1 ; wait for rising edge on write line from mac to start reading byte
jmp loop1 side 1 ;
loop:
nop side 1 [T0/2-2] ; wait for 1/2 bit width
.wrap_target
loop1:
wait 0 gpio 9 side 1 ; block on CA1 at the end of the transmission
jmp pin high side 0 ; need T0 cycles from jmp to jmp
Expand All @@ -34,7 +35,8 @@ sync:
set x, 7 side 1 ; reset the bit counter
jmp !y reset side 0 ; go to top if y was 0
wait 0 pin 0 side 1 ; otherwise wait for falling edge to sync to next back
jmp loop1 side 1 ; start reading byte again
.wrap
; jmp loop1 side 1 ; start reading byte again



Expand Down
4 changes: 1 addition & 3 deletions pico/mac/dcd_write.pio
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@
; logic analyzer looks like 0.4 us pulses in 2.1 us periods
; floppy emulator successfuly works with 0.5 us pulses in 2.0 us periods

; DOES NOT HAVE HOLDOFF IMPLEMENTED
; CAN SIMPLIFY WITH AUTOPULL, REMOVE WAIT ENABLE, USE WRAPPING
; IF USE SIDESET, THEN CAN ADD 15 CLK DELAY - total 16 clk max
; Using Sideset, cAN ADD 15 CLK DELAY - total 16 clk max
; so would like 16 clks = 1.5 us - maybe make the clock cycle = 0.1 us, so 5=0.5 us pulse and 15 = 1.5 us blank
; but dont want to do fractional divide ... instead clk/13 = 9.6154 MHZ
; 1 tick = 0.104 us
Expand Down
45 changes: 45 additions & 0 deletions pico/mac/enand.pio
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
;
; FujiNet Project
;
; Vintage Macintosh Microfloppy Controller Interface
;
; "AND" the two /ENABLE lines by nor-ing the inverted inputs
; input ~in out
; ----- ----- ---
; 0 0 1 1 0
; 0 1 1 0 0
; 1 0 0 1 0
; 1 1 0 0 1
;
; do this
;

.program enand
.side_set 1 opt
loop:
; put the two ENABLE lines in x, inverting them
mov osr, ~pins
out x, 2
jmp !x out1
jmp loop side 0
out1:
jmp loop side 1
; jmp to output 1 if both are 0 (i.e., because original values are 1 & 1)
; otherwise output a 0 (because at least one of them is 1 - original value of 0)

% c-sdk {
// this is a raw helper function for use by the user which sets up the GPIO input and output, and configures the SM to output on a particular pin

void enand_program_init(PIO pio, uint sm, uint offset, uint in_pin, uint out_pin) {
// configure a SM
pio_sm_config c = enand_program_get_default_config(offset);
// config side set
sm_config_set_sideset_pins(&c, out_pin);
sm_config_set_in_pins(&c, in_pin);
sm_config_set_out_shift(&c, true, false, 0);
pio_gpio_init(pio, out_pin);
pio_sm_set_consecutive_pindirs(pio, sm, out_pin, 1, true);
// initialize
pio_sm_init(pio, sm, offset, &c);
}
%}
38 changes: 22 additions & 16 deletions pico/mac/mux.pio
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
; selects output pins between RMT, TACH and LATCH
;
;

.define MCI_CA0 6
.define public LSTRB 13
.define public ENABLE 7
.define public DISKFLAG 12
.define public ENABLE 11
.define public DISKFLAG 10

; The DCD mux will really control the RD line direction.
; It will ...
Expand All @@ -30,7 +30,6 @@ start:
set x, 0 side 0b000 ; put the number of DCD devices in X (0xf020 - last digit is number of DCDs)
wait 0 gpio ENABLE ; don't do anything until we're enabled
.wrap_target
entry:
in x, 32 ; push X to the FIFO to tell the program a certain drive is selected
wait 0 gpio LSTRB ; wait for strobe to deassert
jmp x-- dcd ; if X>0, then count down to next drive
Expand All @@ -41,23 +40,23 @@ floppy:
out x, 4 ; copy to X
set y, 0b0100 ; RDDATA (head 0)
jmp x!=y next1
jmp floppy side 0b010
jmp floppy side 0b100
next1:
set y, 0b1100 ; RDDATA (head 1)
jmp x!=y next2
jmp floppy side 0b010
jmp floppy side 0b100
next2:
set y, 0b1011 ; TACH
jmp x!=y next3
jmp floppy side 0b001
jmp floppy side 0b010
next3: ; LATCH
jmp floppy side 0b100
jmp floppy side 0b001
dcd:
; now we need to wait to be strobed or to be disabled
set pins, 1 ; say to latch we're in DCD mode
jmp pin start ; disabled so go back to the beginning!
mov osr, pins side 0b100 ; get LSTRB value into osr
out null, 5 ; have to blow some into null first
mov osr, pins side 0b001 ; get LSTRB value into osr
out null, (LSTRB-MCI_CA0) ; have to blow some into null first - LSTRB-MCI_CA0 - sort of violates the coding scheme to pass the in_pin
out y, 1 ; stick it in Y
jmp !Y dcd ; not strobing loop
.wrap
Expand All @@ -67,21 +66,28 @@ dcd:
// this is a raw helper function for use by the user which sets up the GPIO input and output, and configures the SM to output on a particular pin
void mux_program_init(PIO pio, uint sm, uint offset, uint in_pin, uint mux_pin)
{
// configure a SM

pio_sm_config c = mux_program_get_default_config(offset);
// config side set
sm_config_set_sideset_pins(&c, mux_pin);
sm_config_set_in_pins(&c, in_pin);
sm_config_set_jmp_pin(&c, ENABLE);
// there are 4 wires to read for latch mux, shift to the right, no autopull

sm_config_set_sideset_pins(&c, mux_pin);
sm_config_set_set_pins(&c, DISKFLAG, 1); // todo: update with a parameter

sm_config_set_in_pins(&c, in_pin);

sm_config_set_jmp_pin(&c, ENABLE);

sm_config_set_out_shift(&c, true, false, 0);

sm_config_set_in_shift(&c, true, true, 32);
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX);

//output GPIO's
for (int i=0; i<3; i++)
pio_gpio_init(pio, mux_pin + i);
pio_sm_set_consecutive_pindirs(pio, sm, mux_pin, 3, false);
pio_gpio_init(pio, DISKFLAG);
pio_sm_set_consecutive_pindirs(pio, sm, DISKFLAG, 1, true);

// initialize
pio_sm_init(pio, sm, offset, &c);
}
Expand Down
Loading