From a4025507c8c742334b4db76145504a0b1fea7434 Mon Sep 17 00:00:00 2001 From: Jeff Piepmeier Date: Tue, 21 Nov 2023 16:26:37 -0500 Subject: [PATCH 1/8] latch stored in a lut --- pico/mac/commands.c | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/pico/mac/commands.c b/pico/mac/commands.c index 1ead5fa02..cdd999375 100644 --- a/pico/mac/commands.c +++ b/pico/mac/commands.c @@ -178,21 +178,31 @@ enum latch_bits { REVISED // f REVISED This status line is used to indicate that the interface definition of the connected external drive. When REVISED is a one, the drive Part No. will be 699-0326 or when REVISED is a zero, the drive Part No. will be 699-0285. }; -uint16_t latch; -uint8_t dcd_latch; +__aligned(32) bool latch_lut[24]; -inline uint16_t get_latch() { return latch; } -inline uint16_t dcd_get_latch() { return ((dcd_latch << 8) + dcd_latch); } - -void set_latch(enum latch_bits s) { latch |= (1u << s); } +uint16_t get_latch() +{ + int latch = 0; + for (int i=0; i<16; i++) + latch |= ((int)latch_lut[i] << i); + return (uint16_t)(latch & 0xffff); +} -void dcd_set_latch(uint8_t s) { dcd_latch |= (1u << s); } +uint8_t dcd_get_latch() +{ + int latch = 0; + for (int i=0; i<8; i++) + latch |= ((int)latch_lut[16 + i] << i); + return (uint8_t)(latch & 0xff); +} -void clr_latch(enum latch_bits c) { latch &= ~(1u << c); } +void set_latch(enum latch_bits s) { latch_lut[s] = true; } +void clr_latch(enum latch_bits c) { latch_lut[c] = false; } +bool latch_val(enum latch_bits s) { return latch_lut[s]; } -void dcd_clr_latch(uint8_t c) { dcd_latch &= ~(1u << c); } +void dcd_set_latch(uint8_t s) { latch_lut[16 + s] = true; } +void dcd_clr_latch(uint8_t c) { latch_lut[16 + c] = false; } -bool latch_val(enum latch_bits s) { return latch & (1u << s); } void dcd_assert_hshk() { // State CA2 CA1 CA0 HOST HOFF RESET RD Function @@ -210,8 +220,13 @@ void dcd_deassert_hshk() void preset_latch() { + for (int i = 0; i < 16; i++) + { + // latch_lut[i] = true; + set_latch(i); + } // set up like an empty floppy - latch =-1; + // latch =-1; // clr_latch(DIRTN); // set_latch(STEP); // set_latch(MOTORON); @@ -226,11 +241,12 @@ void preset_latch() // set_latch(REVISED); // my mac plus revised looks set // for (int i=0; i<16; i++) // printf("\nlatch bit %02d = %d",i, latch_val(i)); + printf("\nFloppy Latch: %04x", get_latch()); } void dcd_preset_latch() { - dcd_latch = 0; + // dcd_latch = 0; // State CA2 CA1 CA0 HOST HOFF RESET RD Function dcd_clr_latch(0); // 0 Low Low Low High High Low Data dcd_clr_latch(1); // 1 Low Low High High Low Low Data @@ -240,6 +256,7 @@ void dcd_preset_latch() dcd_clr_latch(5); // 5 High Low High Low Low Low Drive Low dcd_set_latch(6); // 6 High High Low Low Low Low Drive High dcd_set_latch(7); // 7 High High High Low Low Low Drive High + printf("\nDCD Latch: %02x", dcd_get_latch()); } void set_tach_freq(char c) @@ -638,7 +655,7 @@ void dcd_loop() else { // if (!latch_val(CSTIN)) - pio_sm_put_blocking(pioblk_rw, SM_LATCH, latch); // send the register word to the PIO + pio_sm_put_blocking(pioblk_rw, SM_LATCH, get_latch()); // send the register word to the PIO disk_mode = TO_FPY; return; } From 0fbc5b2834c5767d0b86d2b94088741e0e221ac4 Mon Sep 17 00:00:00 2001 From: Jeff Piepmeier Date: Tue, 21 Nov 2023 16:31:30 -0500 Subject: [PATCH 2/8] make DCD and Floppy MUX sideset the same --- pico/mac/commands.c | 6 +++--- pico/mac/dcd_mux.pio | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pico/mac/commands.c b/pico/mac/commands.c index cdd999375..2453e7040 100644 --- a/pico/mac/commands.c +++ b/pico/mac/commands.c @@ -312,7 +312,7 @@ void switch_to_dcd() // mux pio_remove_program(pioblk_rw, &mux_program, pio_mux_offset); pio_add_program_at_offset(pioblk_rw, &dcd_mux_program, pio_mux_offset); - pio_dcd_mux(pioblk_rw, SM_MUX, pio_mux_offset, LATCH_OUT); + pio_dcd_mux(pioblk_rw, SM_MUX, pio_mux_offset, ECHO_OUT); set_num_dcd(); // echo @@ -328,7 +328,7 @@ void set_num_dcd() uint32_t save = hw_claim_lock(); pioblk_rw->instr_mem[pio_mux_offset] = pio_encode_set(pio_x, num_dcd_drives) | pio_encode_sideset_opt(1, 0); hw_claim_unlock(save); - pio_dcd_mux(pioblk_rw, SM_MUX, pio_mux_offset, LATCH_OUT); + pio_dcd_mux(pioblk_rw, SM_MUX, pio_mux_offset, ECHO_OUT); } void setup() @@ -387,7 +387,7 @@ void setup() pio_mux_offset = pio_add_program(pioblk_rw, &dcd_mux_program); printf("Loaded DCD mux program at %d\n", pio_mux_offset); - pio_dcd_mux(pioblk_rw, SM_MUX, pio_mux_offset, LATCH_OUT); + pio_dcd_mux(pioblk_rw, SM_MUX, pio_mux_offset, ECHO_OUT); // pio_mux_offset = pio_add_program(pioblk_rw, &mux_program); // printf("Loaded Floppy mux program at %d\n", pio_mux_offset); diff --git a/pico/mac/dcd_mux.pio b/pico/mac/dcd_mux.pio index e359d7e3e..f51751d95 100644 --- a/pico/mac/dcd_mux.pio +++ b/pico/mac/dcd_mux.pio @@ -16,18 +16,18 @@ ; probably at some point should push the strobe counter so the FN can decide which disk image to use .program dcd_mux -.side_set 1 opt pindirs +.side_set 3 opt pindirs ; initial state is RD is hi-z and we have 2 DCDs ; we wait to be enabled then RD goes to output .wrap_target start: - set x, 0 side 0 ; put the number of DCD devices in X (0xf020 - last digit is number of DCDs) + 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 in x, 32 ; say we are at the first DCD jmp x-- cont ; decrement X to wait for the next strobe cont: ; now we need to wait to be strobed or to be disabled - jmp pin start side 1 ; disabled so go back to the beginning! + jmp pin start side 0b100 ; disabled so go back to the beginning! mov osr, pins ; get LSTRB value into osr out y, 1 ; stick it in Y jmp !Y cont ; not strobing loop From 547f23b13a3c7ca8c222d5ed1dd4f8040729cbae Mon Sep 17 00:00:00 2001 From: Jeff Piepmeier Date: Tue, 21 Nov 2023 16:43:39 -0500 Subject: [PATCH 3/8] move WR from GPIO 14 to 15 --- pico/mac/commands.c | 46 +++++++++++-------------------------------- pico/mac/dcd_read.pio | 23 +++++++--------------- 2 files changed, 19 insertions(+), 50 deletions(-) diff --git a/pico/mac/commands.c b/pico/mac/commands.c index 2453e7040..a462bdad2 100644 --- a/pico/mac/commands.c +++ b/pico/mac/commands.c @@ -35,13 +35,14 @@ // define GPIO pins #define UART_TX_PIN 4 #define UART_RX_PIN 5 -#define ENABLE 7 -#define MCI_CA0 8 -#define MCI_WR 14 -#define ECHO_IN 21 -#define TACH_OUT 21 -#define ECHO_OUT 18 -#define LATCH_OUT 20 +#define ENABLE 7 +#define MCI_CA0 8 +#define MCI_WR 15 +#define ECHO_IN 21 +#define TACH_OUT 21 +#define ECHO_OUT 18 +#define MUX_OUT 18 +#define LATCH_OUT 20 /** * HERE STARTS PIO DEFINITIONS AND HEADERS @@ -288,7 +289,7 @@ void switch_to_floppy() // mux pio_remove_program(pioblk_rw, &dcd_mux_program, pio_mux_offset); pio_add_program_at_offset(pioblk_rw, &mux_program, pio_mux_offset); - pio_mux(pioblk_rw, SM_MUX, pio_mux_offset, MCI_CA0, ECHO_OUT); + pio_mux(pioblk_rw, SM_MUX, pio_mux_offset, MCI_CA0, MUX_OUT); // commands while (gpio_get(LSTRB)); @@ -312,7 +313,7 @@ void switch_to_dcd() // mux pio_remove_program(pioblk_rw, &mux_program, pio_mux_offset); pio_add_program_at_offset(pioblk_rw, &dcd_mux_program, pio_mux_offset); - pio_dcd_mux(pioblk_rw, SM_MUX, pio_mux_offset, ECHO_OUT); + pio_dcd_mux(pioblk_rw, SM_MUX, pio_mux_offset, MUX_OUT); set_num_dcd(); // echo @@ -328,7 +329,7 @@ void set_num_dcd() uint32_t save = hw_claim_lock(); pioblk_rw->instr_mem[pio_mux_offset] = pio_encode_set(pio_x, num_dcd_drives) | pio_encode_sideset_opt(1, 0); hw_claim_unlock(save); - pio_dcd_mux(pioblk_rw, SM_MUX, pio_mux_offset, ECHO_OUT); + pio_dcd_mux(pioblk_rw, SM_MUX, pio_mux_offset, MUX_OUT); } void setup() @@ -387,34 +388,11 @@ void setup() pio_mux_offset = pio_add_program(pioblk_rw, &dcd_mux_program); printf("Loaded DCD mux program at %d\n", pio_mux_offset); - pio_dcd_mux(pioblk_rw, SM_MUX, pio_mux_offset, ECHO_OUT); + pio_dcd_mux(pioblk_rw, SM_MUX, pio_mux_offset, MUX_OUT); // pio_mux_offset = pio_add_program(pioblk_rw, &mux_program); // printf("Loaded Floppy mux program at %d\n", pio_mux_offset); // pio_mux(pioblk_rw, SM_MUX, pio_mux_offset, MCI_CA0, ECHO_OUT); - -#ifdef FLOPPY - set_tach_freq(0); // start TACH clock - preset_latch(); - - offset = pio_add_program(pio_floppy, &commands_program); - printf("\nLoaded cmd program at %d\n", offset); - pio_commands(pio_floppy, SM_FPY_CMD, offset, MCI_CA0); // read phases starting on pin 8 - - offset = pio_add_program(pio_floppy, &echo_program); - printf("Loaded echo program at %d\n", offset); - pio_echo(pio_floppy, SM_FPY_ECHO, offset, ECHO_IN, ECHO_OUT, 2); - - offset = pio_add_program(pio_floppy, &latch_program); - printf("Loaded latch program at %d\n", offset); - pio_latch(pio_floppy, SM_LATCH, offset, MCI_CA0, LATCH_OUT); - pio_sm_put_blocking(pio_floppy, SM_LATCH, get_latch()); // send the register word to the PIO - - offset = pio_add_program(pio_floppy, &mux_program); - printf("Loaded mux program at %d\n", offset); - pio_mux(pio_floppy, SM_MUX, offset, MCI_CA0, ECHO_OUT); - -#endif // FLOPPY } void dcd_loop(); diff --git a/pico/mac/dcd_read.pio b/pico/mac/dcd_read.pio index 0cfff4fbf..b15deb1dc 100644 --- a/pico/mac/dcd_read.pio +++ b/pico/mac/dcd_read.pio @@ -2,16 +2,14 @@ ; FujiNet Project ; ; Vintage Macintosh Microfloppy Controller Interface -; sRead NRZI stream +; Read NRZI stream ; ; -.define ENABLE 7 .define public T0 10 .program dcd_read .side_set 1 - ; wait 0 gpio ENABLE side 1 ; removed if SM was triggered by main program set y, 0 side 0 ; initial state is always 0 set x, 7 side 0 ; bit counter reset: @@ -25,7 +23,7 @@ loop1: low: in y, 1 side 0 [1] ; shift in the decoded value, which is equal to the previous state y set y, 0 side 0 ; previous state is now low (zero) - jmp x-- loop side 1 ; check to see if we're at the last bit? + jmp x-- loop side 1 ; check to see if we are at the last bit? jmp sync side 1 ; if so, then wait for the next byte to start high: mov y, ~y side 0 @@ -47,22 +45,15 @@ void dcd_read_program_init(PIO pio, uint sm, uint offset, uint in_pin) { // configure a SM pio_sm_config c = dcd_read_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, in_pin); - // sm_config_set_sideset_pins(&c, 15); // TEMPORARY FOR DEBUGGING - // sm_config_set_out_shift(&c, true, false, 1); sm_config_set_in_shift(&c, false, true, 8); sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX); - - pio_gpio_init(pio, in_pin); - pio_sm_set_consecutive_pindirs(pio, sm, in_pin, 1, false); -// pio_gpio_init(pio, 15); -// pio_sm_set_consecutive_pindirs(pio, sm, 15, 1, true); // TEMPORARY FOR DEBUG OUTPUT (EXTRA) - pio_gpio_init(pio, 9); - pio_sm_set_consecutive_pindirs(pio, sm, 9, 1, false); // for blocking on CA1 - + + // sm_config_set_sideset_pins(&c, 16); // TEMPORARY FOR DEBUGGING + // pio_gpio_init(pio, 16); + // pio_sm_set_consecutive_pindirs(pio, sm, 16, 1, true); // TEMPORARY FOR DEBUG OUTPUT (EXTRA) + // initialize float cycles_per_bit = T0; float div = clock_get_hz(clk_sys) / (500.0e3 * cycles_per_bit); // 125MHz/500kHz = 250 From a449419a9056a313f81cd9572c8a1d15133f8cdb Mon Sep 17 00:00:00 2001 From: Jeff Piepmeier Date: Tue, 21 Nov 2023 16:54:40 -0500 Subject: [PATCH 4/8] moved LSTRB to GPIO13 --- pico/mac/commands.pio | 2 +- pico/mac/dcd_latch.pio | 1 - pico/mac/dcd_mux.pio | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/pico/mac/commands.pio b/pico/mac/commands.pio index 49eea5bda..caeb0bbee 100644 --- a/pico/mac/commands.pio +++ b/pico/mac/commands.pio @@ -5,7 +5,7 @@ ; sends the phases to the PICO when the strobe sets ; -.define public LSTRB 12 +.define public LSTRB 13 .define ENABLE 7 .program commands diff --git a/pico/mac/dcd_latch.pio b/pico/mac/dcd_latch.pio index 28e16e54b..a9b3ec98c 100644 --- a/pico/mac/dcd_latch.pio +++ b/pico/mac/dcd_latch.pio @@ -6,7 +6,6 @@ ; .define ENABLE 7 -.define LSTRB 12 .program dcd_latch start: diff --git a/pico/mac/dcd_mux.pio b/pico/mac/dcd_mux.pio index f51751d95..71aa85177 100644 --- a/pico/mac/dcd_mux.pio +++ b/pico/mac/dcd_mux.pio @@ -6,7 +6,7 @@ ; ; -.define public LSTRB 12 +.define public LSTRB 13 .define public ENABLE 7 ; The DCD mux will really control the RD line direction. From 8a5e3496dfa156060981d501303edbcf76549735 Mon Sep 17 00:00:00 2001 From: Jeff Piepmeier Date: Tue, 21 Nov 2023 17:25:34 -0500 Subject: [PATCH 5/8] add the drive type GPIO to dcd_mux --- pico/mac/CMakeLists.txt | 1 - pico/mac/commands.c | 6 ------ pico/mac/dcd_latch.pio | 45 ----------------------------------------- pico/mac/dcd_mux.pio | 17 +++++++++------- 4 files changed, 10 insertions(+), 59 deletions(-) delete mode 100644 pico/mac/dcd_latch.pio diff --git a/pico/mac/CMakeLists.txt b/pico/mac/CMakeLists.txt index e82d8a2f3..2def4b2ae 100644 --- a/pico/mac/CMakeLists.txt +++ b/pico/mac/CMakeLists.txt @@ -31,7 +31,6 @@ pico_generate_pio_header(commands ${CMAKE_CURRENT_LIST_DIR}/commands.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) -pico_generate_pio_header(commands ${CMAKE_CURRENT_LIST_DIR}/dcd_latch.pio) pico_generate_pio_header(commands ${CMAKE_CURRENT_LIST_DIR}/dcd_commands.pio) pico_generate_pio_header(commands ${CMAKE_CURRENT_LIST_DIR}/dcd_mux.pio) pico_generate_pio_header(commands ${CMAKE_CURRENT_LIST_DIR}/dcd_read.pio) diff --git a/pico/mac/commands.c b/pico/mac/commands.c index a462bdad2..76edcdcf6 100644 --- a/pico/mac/commands.c +++ b/pico/mac/commands.c @@ -1245,12 +1245,6 @@ void pio_mux(PIO pio, uint sm, uint offset, uint in_pin, uint mux_pin) pio_sm_set_enabled(pio, sm, true); } -// void pio_dcd_latch(PIO pio, uint sm, uint offset, uint in_pin, uint out_pin) -// { -// latch_program_init(pio, sm, offset, in_pin, out_pin); -// pio_sm_set_enabled(pio, sm, true); -// } - void pio_dcd_commands(PIO pio, uint sm, uint offset, uint pin) { dcd_commands_program_init(pio, sm, offset, pin); diff --git a/pico/mac/dcd_latch.pio b/pico/mac/dcd_latch.pio deleted file mode 100644 index a9b3ec98c..000000000 --- a/pico/mac/dcd_latch.pio +++ /dev/null @@ -1,45 +0,0 @@ -; -; FujiNet Project -; -; Vintage Macintosh Microfloppy Controller Interface -; Reads the drive phases and output a dcd_latch bit -; - -.define ENABLE 7 - -.program dcd_latch -start: - wait 0 gpio ENABLE - mov osr, pins ; read the GPIO's into the output shift register - out y, 3 ; shift the 3 LSBs into Y - pull noblock ; get the dcd_latch word into OSR, if no new word in FIFO, get it from X - mov x, osr ; put the osr back into X in case it's new -.wrap_target - jmp y-- loop ; if y>0 goto to loop and decrement y - out pins, 1 ; output the desired bit - jmp start ; do it again -loop: - out null, 1 ; get rid of a bit -.wrap - - -% 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 dcd_latch_program_init(PIO pio, uint sm, uint offset, uint in_pin, uint out_pin) { - // configure a SM - pio_sm_config c = dcd_latch_program_get_default_config(offset); - // set the out pin to out_pin - sm_config_set_out_pins(&c, out_pin, 1); - // start at in_pin to read in the phases - sm_config_set_in_pins(&c, in_pin); - // get 8 bit dcd_latch values through the OSR from the main program - sm_config_set_out_shift(&c, true, false, 8); - // set out_pin as a GPIO output connected to this SM - pio_gpio_init(pio, out_pin); - pio_sm_set_consecutive_pindirs(pio, sm, out_pin, 1, true); // TODO change back - manually set output for now - // sm_config_set_set_pins(&c, pin, 1); - // initialize - pio_sm_init(pio, sm, offset, &c); -} -%} \ No newline at end of file diff --git a/pico/mac/dcd_mux.pio b/pico/mac/dcd_mux.pio index 71aa85177..4b2f21b10 100644 --- a/pico/mac/dcd_mux.pio +++ b/pico/mac/dcd_mux.pio @@ -23,6 +23,7 @@ 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 + set pins, 1 in x, 32 ; say we are at the first DCD jmp x-- cont ; decrement X to wait for the next strobe cont: @@ -34,28 +35,30 @@ cont: in x, 32 ; push X to the FIFO to tell the program a certain drive is selected wait 0 gpio LSTRB jmp x-- cont + set pins, 0 wait 1 gpio ENABLE ; side 0 .wrap - nop ; need to pad a couple instructions to make it same length as floppy mux - nop % 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 // #define LSTRB 12 // #define ENABLE 7 -void dcd_mux_program_init(PIO pio, uint sm, uint offset, uint set_pin) { +void dcd_mux_program_init(PIO pio, uint sm, uint offset, uint mux_pin) { // configure a SM pio_sm_config c = dcd_mux_program_get_default_config(offset); // config side set - sm_config_set_sideset_pins(&c, set_pin); + sm_config_set_sideset_pins(&c, mux_pin); sm_config_set_in_pins(&c, LSTRB); 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_set_pins(&c, set_pin, 1); + sm_config_set_set_pins(&c, 12, 1); // todo: update with a parameter sm_config_set_out_shift(&c, true, false, 1); sm_config_set_in_shift(&c, true, true, 32); - pio_gpio_init(pio, set_pin); - pio_sm_set_consecutive_pindirs(pio, sm, set_pin, 1, false); + 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, 12); + pio_sm_set_consecutive_pindirs(pio, sm, 12, 1, true); // initialize pio_sm_init(pio, sm, offset, &c); } From c5327d1aead001eeeccf813f43012946d4970b88 Mon Sep 17 00:00:00 2001 From: Jeff Piepmeier Date: Tue, 21 Nov 2023 20:27:51 -0500 Subject: [PATCH 6/8] latch is now by DMA! --- pico/mac/CMakeLists.txt | 2 +- pico/mac/commands.c | 74 +++++++++++++++++++++++++++++++---------- pico/mac/latch.pio | 41 +++++++++++++---------- 3 files changed, 82 insertions(+), 35 deletions(-) diff --git a/pico/mac/CMakeLists.txt b/pico/mac/CMakeLists.txt index 2def4b2ae..1bc705b4c 100644 --- a/pico/mac/CMakeLists.txt +++ b/pico/mac/CMakeLists.txt @@ -40,7 +40,7 @@ pico_generate_pio_header(commands ${CMAKE_CURRENT_LIST_DIR}/dcd_write.pio) # target_sources(pio_and PRIVATE pio_and.c) -target_link_libraries(commands pico_stdlib hardware_pio) +target_link_libraries(commands pico_stdlib hardware_pio hardware_dma) # Add the standard include files to the build target_include_directories(commands PRIVATE diff --git a/pico/mac/commands.c b/pico/mac/commands.c index 76edcdcf6..754749074 100644 --- a/pico/mac/commands.c +++ b/pico/mac/commands.c @@ -15,6 +15,7 @@ #include "hardware/uart.h" #include "hardware/clocks.h" #include "hardware/claim.h" +#include "hardware/dma.h" #include "hardware/pio.h" #include "hardware/pio_instructions.h" @@ -26,7 +27,6 @@ #include "latch.pio.h" #include "mux.pio.h" -// #include "dcd_latch.pio.h" #include "dcd_commands.pio.h" #include "dcd_mux.pio.h" #include "dcd_read.pio.h" @@ -67,7 +67,7 @@ uint pio_dcd_cmd_offset; 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_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_dcd_latch(PIO pio, uint sm, uint offset, uint in_pin, uint out_pin); @@ -209,14 +209,14 @@ void dcd_assert_hshk() { // State CA2 CA1 CA0 HOST HOFF RESET RD Function dcd_clr_latch(2); // 2 Low High Low Low Low Low !HSHK dcd_clr_latch(3); // 3 Low High High High Low Low !HSHK - pio_sm_put_blocking(pioblk_rw, SM_LATCH, dcd_get_latch()); // send the register word to the PIO + // pio_sm_put_blocking(pioblk_rw, SM_LATCH, dcd_get_latch()); // send the register word to the PIO } void dcd_deassert_hshk() { // State CA2 CA1 CA0 HOST HOFF RESET RD Function dcd_set_latch(2); // 2 Low High Low Low Low Low !HSHK dcd_set_latch(3); // 3 Low High High High Low Low !HSHK - pio_sm_put_blocking(pioblk_rw, SM_LATCH, dcd_get_latch()); // send the register word to the PIO + // pio_sm_put_blocking(pioblk_rw, SM_LATCH, dcd_get_latch()); // send the register word to the PIO } void preset_latch() @@ -284,7 +284,7 @@ void set_tach_freq(char c) void switch_to_floppy() { // latch - pio_sm_put_blocking(pioblk_rw, SM_LATCH, get_latch()); // send the register word to the PIO + // pio_sm_put_blocking(pioblk_rw, SM_LATCH, get_latch()); // send the register word to the PIO // mux pio_remove_program(pioblk_rw, &dcd_mux_program, pio_mux_offset); @@ -304,7 +304,7 @@ void switch_to_floppy() void switch_to_dcd() { // latch - pio_sm_put_blocking(pioblk_rw, SM_LATCH, dcd_get_latch()); // send the register word to the PIO + // pio_sm_put_blocking(pioblk_rw, SM_LATCH, dcd_get_latch()); // send the register word to the PIO // commands pio_sm_set_enabled(pioblk_read_only, SM_FPY_CMD, false); // stop the floppy command interpreter @@ -332,6 +332,9 @@ void set_num_dcd() pio_dcd_mux(pioblk_rw, SM_MUX, pio_mux_offset, MUX_OUT); } +int chan_latch_addr, chan_latch_data; +dma_channel_config cfg_latch_addr, cfg_latch_data; + void setup() { uint offset; @@ -375,8 +378,50 @@ void setup() */ offset = pio_add_program(pioblk_rw, &latch_program); printf("\nLoaded latch program at %d\n", offset); - pio_latch(pioblk_rw, SM_LATCH, offset, MCI_CA0, LATCH_OUT); - pio_sm_put_blocking(pioblk_rw, SM_LATCH, dcd_get_latch()); // send the register word to the PIO + latch_program_init(pioblk_rw, SM_LATCH, offset, MCI_CA0, LATCH_OUT); + pio_sm_put(pioblk_rw, SM_LATCH, (uintptr_t)latch_lut >> 5); + pio_sm_exec_wait_blocking(pioblk_rw, SM_LATCH, pio_encode_pull(false, true)); + pio_sm_exec_wait_blocking(pioblk_rw, SM_LATCH, pio_encode_mov(pio_y, pio_osr)); + pio_sm_exec_wait_blocking(pioblk_rw, SM_LATCH, pio_encode_out(pio_null, 1)); + pio_sm_set_enabled(pioblk_rw, SM_LATCH, true); + + chan_latch_addr = dma_claim_unused_channel(true); + cfg_latch_addr = dma_channel_get_default_config(chan_latch_addr); + + chan_latch_data = dma_claim_unused_channel(true); + cfg_latch_data = dma_channel_get_default_config(chan_latch_data); + + channel_config_set_read_increment(&cfg_latch_data,false); + channel_config_set_write_increment(&cfg_latch_data,false); + channel_config_set_dreq(&cfg_latch_data, pio_get_dreq(pioblk_rw, SM_LATCH, true)); // mux PIO + channel_config_set_chain_to(&cfg_latch_data, chan_latch_addr); + channel_config_set_transfer_data_size(&cfg_latch_data, DMA_SIZE_8); + channel_config_set_irq_quiet(&cfg_latch_data, true); + channel_config_set_enable(&cfg_latch_data, true); + dma_channel_configure( + chan_latch_data, // Channel to be configured + &cfg_latch_data, // The configuration we just created + &pioblk_rw->txf[SM_LATCH], // The initial write address + latch_lut, // The initial read address + 1, // Number of transfers; in this case each is 1 byte. + false // do not Start immediately. + ); + + channel_config_set_read_increment(&cfg_latch_addr,false); + channel_config_set_write_increment(&cfg_latch_addr,false); + channel_config_set_dreq(&cfg_latch_addr, pio_get_dreq(pioblk_rw, SM_LATCH, false)); // mux PIO + channel_config_set_chain_to(&cfg_latch_addr, chan_latch_data); + channel_config_set_transfer_data_size(&cfg_latch_addr, DMA_SIZE_32); + channel_config_set_irq_quiet(&cfg_latch_addr, true); + channel_config_set_enable(&cfg_latch_addr, true); + dma_channel_configure( + chan_latch_addr, // Channel to be configured + &cfg_latch_addr, // The configuration we just created + &dma_channel_hw_addr(chan_latch_data)->read_addr, // The initial write address + &pioblk_rw->rxf[SM_LATCH], // The initial read address + 1, // Number of transfers; in this case each is 1 byte. + true // do not Start immediately. + ); offset = pio_add_program(pioblk_rw, &echo_program); printf("Loaded floppy echo program at %d\n", offset); @@ -475,7 +520,7 @@ void floppy_loop() if (gpio_get(ENABLE) && (num_dcd_drives > 0)) { - pio_sm_put_blocking(pioblk_rw, SM_LATCH, dcd_get_latch()); // send the register word to the PIO + // pio_sm_put_blocking(pioblk_rw, SM_LATCH, dcd_get_latch()); // send the register word to the PIO disk_mode = TO_DCD; return; } @@ -541,7 +586,7 @@ void floppy_loop() printf("\nUNKNOWN PHASE COMMAND"); break; } - pio_sm_put_blocking(pioblk_rw, SM_LATCH, get_latch()); // send the register word to the PIO + // pio_sm_put_blocking(pioblk_rw, SM_LATCH, get_latch()); // send the register word to the PIO uart_putc_raw(UART_ID, (char)(a + '0')); } @@ -595,7 +640,7 @@ void floppy_loop() break; } // printf("latch %04x", get_latch()); - pio_sm_put_blocking(pioblk_rw, SM_LATCH, get_latch()); // send the register word to the PIO + // pio_sm_put_blocking(pioblk_rw, SM_LATCH, get_latch()); // send the register word to the PIO c = 0; // clear c because processed it and don't want infinite loop } // to do: read both enable lines and indicate which drive is active when sending single char to esp32 @@ -633,7 +678,7 @@ void dcd_loop() else { // if (!latch_val(CSTIN)) - pio_sm_put_blocking(pioblk_rw, SM_LATCH, get_latch()); // send the register word to the PIO + // pio_sm_put_blocking(pioblk_rw, SM_LATCH, get_latch()); // send the register word to the PIO disk_mode = TO_FPY; return; } @@ -1233,11 +1278,6 @@ 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_latch(PIO pio, uint sm, uint offset, uint in_pin, uint out_pin) -{ - latch_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) { diff --git a/pico/mac/latch.pio b/pico/mac/latch.pio index 5a6228da8..6f751cdcd 100644 --- a/pico/mac/latch.pio +++ b/pico/mac/latch.pio @@ -6,22 +6,25 @@ ; for DCD, the 8-bit latch register should be copied into upper and lower bytes of the value pulled by the SM ; -.define ENABLE 7 +; .define ENABLE 7 .program latch -start: - wait 0 gpio ENABLE - mov osr, pins ; read the GPIO's into the output shift register - out y, 4 ; shift the 4 LSBs into Y - pull noblock ; get the latch word into OSR, if no new word in FIFO, get it from X - mov x, osr ; put the osr back into X in case it's new -.wrap_target - jmp y-- loop ; if y>0 goto to loop and decrement y - out pins, 1 ; output the desired bit - jmp start ; do it again -loop: - out null, 1 ; get rid of a bit -.wrap + mov isr, y ; put the base address in ISR + in pins, 5 ; copy the pin combination into the ISR (auto push) + out pins, 1 ; output the latch bit value +; start: +; wait 0 gpio ENABLE +; mov osr, pins ; read the GPIO's into the output shift register +; out y, 4 ; shift the 4 LSBs into Y +; pull noblock ; get the latch word into OSR, if no new word in FIFO, get it from X +; mov x, osr ; put the osr back into X in case it's new +; .wrap_target +; jmp y-- loop ; if y>0 goto to loop and decrement y +; out pins, 1 ; output the desired bit +; jmp start ; do it again +; loop: +; out null, 1 ; get rid of a bit +; .wrap % c-sdk { @@ -30,15 +33,19 @@ loop: void latch_program_init(PIO pio, uint sm, uint offset, uint in_pin, uint out_pin) { // configure a SM pio_sm_config c = latch_program_get_default_config(offset); + // set the out pin to out_pin sm_config_set_out_pins(&c, out_pin, 1); + // get 1 bit latch values through the OSR from the main program + sm_config_set_out_shift(&c, true, true, 1); + // start at in_pin to read in the phases sm_config_set_in_pins(&c, in_pin); - // get 16 bit latch values through the OSR from the main program - sm_config_set_out_shift(&c, true, false, 16); + sm_config_set_in_shift(&c, false, true, 5); + // set out_pin as a GPIO output connected to this SM pio_gpio_init(pio, out_pin); -// pio_sm_set_consecutive_pindirs(pio, sm, out_pin, 1, true); + pio_sm_set_consecutive_pindirs(pio, sm, out_pin, 1, true); // sm_config_set_set_pins(&c, pin, 1); // initialize pio_sm_init(pio, sm, offset, &c); From 1e1ae8b086ef7deedf36dd4ee1b7724291a78a9a Mon Sep 17 00:00:00 2001 From: Jeff Piepmeier Date: Tue, 21 Nov 2023 20:55:27 -0500 Subject: [PATCH 7/8] optimize dcd mux before combining with mux --- pico/mac/combined_mux.pio | 112 ++++++++++++++++++++++++++++++++++++++ pico/mac/dcd_mux.pio | 7 ++- pico/mac/latch.pio | 36 +++++------- 3 files changed, 131 insertions(+), 24 deletions(-) create mode 100644 pico/mac/combined_mux.pio diff --git a/pico/mac/combined_mux.pio b/pico/mac/combined_mux.pio new file mode 100644 index 000000000..4881bf0ba --- /dev/null +++ b/pico/mac/combined_mux.pio @@ -0,0 +1,112 @@ +; +; FujiNet Project +; +; Vintage Macintosh Microfloppy Controller Interface +; selects output pins between RMT, TACH and LATCH +; +; + +.define public LSTRB 13 +.define public ENABLE 7 + +; The DCD mux will really control the RD line direction. +; It will ... +; count the number of strobes and disable RD after 1, 2, or 3 of them +; it will reset the counter when disable goes high +; probably at some point should push the strobe counter so the FN can decide which disk image to use + +.program mux +.side_set 3 opt pindirs + ; initial state is RD is hi-z and we have 2 DCDs + ; we wait to be enabled then RD goes to output +.wrap_target +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 + set pins, 1 + in x, 32 ; say we are at the first DCD + jmp x-- cont ; decrement X to wait for the next strobe +cont: + ; now we need to wait to be strobed or to be disabled + jmp pin start side 0b100 ; disabled so go back to the beginning! + mov osr, pins ; get LSTRB value into osr + out y, 1 ; stick it in Y + jmp !Y cont ; not strobing loop + in x, 32 ; push X to the FIFO to tell the program a certain drive is selected + wait 0 gpio LSTRB + jmp x-- cont + set pins, 0 + wait 1 gpio ENABLE ; side 0 +.wrap + +.program mux +.side_set 3 opt pindirs +start: + jmp pin next4 + mov osr, pins ; get the input phases + out x, 4 ; copy to X + set y, 0b0100 ; RDDATA (head 0) + jmp x!=y next1 + jmp start side 0b010 +next1: + set y, 0b1100 ; RDDATA (head 1) + jmp x!=y next2 + jmp start side 0b010 +next2: + set y, 0b1011 ; TACH + jmp x!=y next3 + jmp start side 0b001 +next3: ; LATCH + jmp start side 0b100 +next4: + jmp start side 0b000 ; enable high (not enabled) + + +% 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 +// #define LSTRB 12 +// #define ENABLE 7 +void dcd_mux_program_init(PIO pio, uint sm, uint offset, uint mux_pin) { + // configure a SM + pio_sm_config c = dcd_mux_program_get_default_config(offset); + // config side set + sm_config_set_sideset_pins(&c, mux_pin); + sm_config_set_in_pins(&c, LSTRB); + 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_set_pins(&c, 12, 1); // todo: update with a parameter + sm_config_set_out_shift(&c, true, false, 1); + sm_config_set_in_shift(&c, true, true, 32); + 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, 12); + pio_sm_set_consecutive_pindirs(pio, sm, 12, 1, true); + // initialize + pio_sm_init(pio, sm, offset, &c); +} +%} + + + + + +% 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 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, in_pin-1); + // there are 4 wires to read for latch mux, shift to the right, no autopull + sm_config_set_out_shift(&c, true, false, 4); + 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); + // initialize + pio_sm_init(pio, sm, offset, &c); +} +%} \ No newline at end of file diff --git a/pico/mac/dcd_mux.pio b/pico/mac/dcd_mux.pio index 4b2f21b10..370bdf0a9 100644 --- a/pico/mac/dcd_mux.pio +++ b/pico/mac/dcd_mux.pio @@ -24,21 +24,22 @@ 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 set pins, 1 - in x, 32 ; say we are at the first DCD - jmp x-- cont ; decrement X to wait for the next strobe + jmp entry cont: ; now we need to wait to be strobed or to be disabled jmp pin start side 0b100 ; disabled so go back to the beginning! mov osr, pins ; get LSTRB value into osr out y, 1 ; stick it in Y jmp !Y cont ; not strobing loop +entry: in x, 32 ; push X to the FIFO to tell the program a certain drive is selected wait 0 gpio LSTRB jmp x-- cont set pins, 0 wait 1 gpio ENABLE ; side 0 .wrap - + nop + % 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 // #define LSTRB 12 diff --git a/pico/mac/latch.pio b/pico/mac/latch.pio index 6f751cdcd..a1dc358d4 100644 --- a/pico/mac/latch.pio +++ b/pico/mac/latch.pio @@ -2,30 +2,25 @@ ; FujiNet Project ; ; Vintage Macintosh Microfloppy Controller Interface -; Reads the drive phases and output a latch bit -; for DCD, the 8-bit latch register should be copied into upper and lower bytes of the value pulled by the SM +; Reads the drive phases (pushed to RX FIFO) and output a latch bit (pulled to TX_FIFO) +; Uses 2 DMA channels to read the desired latch bit ; - -; .define ENABLE 7 +; the Y register is set prior to enabling the SM using + ; put LUT address into the FIFO + ; pull + ; mov y, osr + ; out null, 1 + ; + ; or using c code: + ; pio_sm_put(pioblk_rw, SM_LATCH, (uintptr_t)latch_lut >> 5); + ; pio_sm_exec_wait_blocking(pioblk_rw, SM_LATCH, pio_encode_pull(false, true)); + ; pio_sm_exec_wait_blocking(pioblk_rw, SM_LATCH, pio_encode_mov(pio_y, pio_osr)); + ; pio_sm_exec_wait_blocking(pioblk_rw, SM_LATCH, pio_encode_out(pio_null, 1)); .program latch mov isr, y ; put the base address in ISR in pins, 5 ; copy the pin combination into the ISR (auto push) out pins, 1 ; output the latch bit value -; start: -; wait 0 gpio ENABLE -; mov osr, pins ; read the GPIO's into the output shift register -; out y, 4 ; shift the 4 LSBs into Y -; pull noblock ; get the latch word into OSR, if no new word in FIFO, get it from X -; mov x, osr ; put the osr back into X in case it's new -; .wrap_target -; jmp y-- loop ; if y>0 goto to loop and decrement y -; out pins, 1 ; output the desired bit -; jmp start ; do it again -; loop: -; out null, 1 ; get rid of a bit -; .wrap - % 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 @@ -34,12 +29,11 @@ void latch_program_init(PIO pio, uint sm, uint offset, uint in_pin, uint out_pin // configure a SM pio_sm_config c = latch_program_get_default_config(offset); - // set the out pin to out_pin + // get 1 bit latch values through the OSR and output on out_pin sm_config_set_out_pins(&c, out_pin, 1); - // get 1 bit latch values through the OSR from the main program sm_config_set_out_shift(&c, true, true, 1); - // start at in_pin to read in the phases + // start at in_pin to read in the phases and push to the FIFO sm_config_set_in_pins(&c, in_pin); sm_config_set_in_shift(&c, false, true, 5); From 9707fa0b488965835389705491920eccb2c237bd Mon Sep 17 00:00:00 2001 From: Jeff Piepmeier Date: Wed, 22 Nov 2023 14:34:12 -0500 Subject: [PATCH 8/8] combined mux SM - works with 1 DCD and 1 Floppy --- pico/mac/CMakeLists.txt | 1 - pico/mac/combined_mux.pio | 112 ---------------------- pico/mac/commands.c | 56 ++--------- pico/mac/{dcd_mux.pio => dcd_mux.pio.old} | 0 pico/mac/mux.pio | 74 ++++++++++---- pico/mac/mux.pio.old | 49 ++++++++++ 6 files changed, 113 insertions(+), 179 deletions(-) delete mode 100644 pico/mac/combined_mux.pio rename pico/mac/{dcd_mux.pio => dcd_mux.pio.old} (100%) create mode 100644 pico/mac/mux.pio.old diff --git a/pico/mac/CMakeLists.txt b/pico/mac/CMakeLists.txt index 1bc705b4c..3ec818bd2 100644 --- a/pico/mac/CMakeLists.txt +++ b/pico/mac/CMakeLists.txt @@ -32,7 +32,6 @@ 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) pico_generate_pio_header(commands ${CMAKE_CURRENT_LIST_DIR}/dcd_commands.pio) -pico_generate_pio_header(commands ${CMAKE_CURRENT_LIST_DIR}/dcd_mux.pio) pico_generate_pio_header(commands ${CMAKE_CURRENT_LIST_DIR}/dcd_read.pio) pico_generate_pio_header(commands ${CMAKE_CURRENT_LIST_DIR}/dcd_write.pio) # however, alternatively you can choose to generate it somewhere else (in this case in the source tree for check in) diff --git a/pico/mac/combined_mux.pio b/pico/mac/combined_mux.pio deleted file mode 100644 index 4881bf0ba..000000000 --- a/pico/mac/combined_mux.pio +++ /dev/null @@ -1,112 +0,0 @@ -; -; FujiNet Project -; -; Vintage Macintosh Microfloppy Controller Interface -; selects output pins between RMT, TACH and LATCH -; -; - -.define public LSTRB 13 -.define public ENABLE 7 - -; The DCD mux will really control the RD line direction. -; It will ... -; count the number of strobes and disable RD after 1, 2, or 3 of them -; it will reset the counter when disable goes high -; probably at some point should push the strobe counter so the FN can decide which disk image to use - -.program mux -.side_set 3 opt pindirs - ; initial state is RD is hi-z and we have 2 DCDs - ; we wait to be enabled then RD goes to output -.wrap_target -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 - set pins, 1 - in x, 32 ; say we are at the first DCD - jmp x-- cont ; decrement X to wait for the next strobe -cont: - ; now we need to wait to be strobed or to be disabled - jmp pin start side 0b100 ; disabled so go back to the beginning! - mov osr, pins ; get LSTRB value into osr - out y, 1 ; stick it in Y - jmp !Y cont ; not strobing loop - in x, 32 ; push X to the FIFO to tell the program a certain drive is selected - wait 0 gpio LSTRB - jmp x-- cont - set pins, 0 - wait 1 gpio ENABLE ; side 0 -.wrap - -.program mux -.side_set 3 opt pindirs -start: - jmp pin next4 - mov osr, pins ; get the input phases - out x, 4 ; copy to X - set y, 0b0100 ; RDDATA (head 0) - jmp x!=y next1 - jmp start side 0b010 -next1: - set y, 0b1100 ; RDDATA (head 1) - jmp x!=y next2 - jmp start side 0b010 -next2: - set y, 0b1011 ; TACH - jmp x!=y next3 - jmp start side 0b001 -next3: ; LATCH - jmp start side 0b100 -next4: - jmp start side 0b000 ; enable high (not enabled) - - -% 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 -// #define LSTRB 12 -// #define ENABLE 7 -void dcd_mux_program_init(PIO pio, uint sm, uint offset, uint mux_pin) { - // configure a SM - pio_sm_config c = dcd_mux_program_get_default_config(offset); - // config side set - sm_config_set_sideset_pins(&c, mux_pin); - sm_config_set_in_pins(&c, LSTRB); - 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_set_pins(&c, 12, 1); // todo: update with a parameter - sm_config_set_out_shift(&c, true, false, 1); - sm_config_set_in_shift(&c, true, true, 32); - 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, 12); - pio_sm_set_consecutive_pindirs(pio, sm, 12, 1, true); - // initialize - pio_sm_init(pio, sm, offset, &c); -} -%} - - - - - -% 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 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, in_pin-1); - // there are 4 wires to read for latch mux, shift to the right, no autopull - sm_config_set_out_shift(&c, true, false, 4); - 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); - // initialize - pio_sm_init(pio, sm, offset, &c); -} -%} \ No newline at end of file diff --git a/pico/mac/commands.c b/pico/mac/commands.c index 754749074..c226c68c9 100644 --- a/pico/mac/commands.c +++ b/pico/mac/commands.c @@ -28,7 +28,6 @@ #include "mux.pio.h" #include "dcd_commands.pio.h" -#include "dcd_mux.pio.h" #include "dcd_read.pio.h" #include "dcd_write.pio.h" @@ -70,9 +69,7 @@ void pio_echo(PIO pio, uint sm, uint offset, uint in_pin, uint out_pin, uint num // 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_dcd_latch(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_mux(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(); @@ -283,42 +280,17 @@ void set_tach_freq(char c) void switch_to_floppy() { - // latch - // pio_sm_put_blocking(pioblk_rw, SM_LATCH, get_latch()); // send the register word to the PIO - - // mux - pio_remove_program(pioblk_rw, &dcd_mux_program, pio_mux_offset); - pio_add_program_at_offset(pioblk_rw, &mux_program, pio_mux_offset); - pio_mux(pioblk_rw, SM_MUX, pio_mux_offset, MCI_CA0, MUX_OUT); - // commands while (gpio_get(LSTRB)); pio_sm_set_enabled(pioblk_read_only, SM_DCD_CMD, false); // stop the DCD command interpreter pio_commands(pioblk_read_only, SM_FPY_CMD, pio_floppy_cmd_offset, MCI_CA0); // read phases starting on pin 8 - - // echo - // pio_sm_set_enabled(pioblk_rw, SM_FPY_ECHO, true); - } void switch_to_dcd() { - // latch - // pio_sm_put_blocking(pioblk_rw, SM_LATCH, dcd_get_latch()); // send the register word to the PIO - // commands pio_sm_set_enabled(pioblk_read_only, SM_FPY_CMD, false); // stop the floppy command interpreter pio_dcd_commands(pioblk_read_only, SM_DCD_CMD, pio_dcd_cmd_offset, MCI_CA0); // read phases starting on pin 8 - - // mux - pio_remove_program(pioblk_rw, &mux_program, pio_mux_offset); - pio_add_program_at_offset(pioblk_rw, &dcd_mux_program, pio_mux_offset); - pio_dcd_mux(pioblk_rw, SM_MUX, pio_mux_offset, MUX_OUT); - set_num_dcd(); - - // echo - // pio_sm_set_enabled(pioblk_rw, SM_FPY_ECHO, false); - } void set_num_dcd() @@ -327,9 +299,9 @@ void set_num_dcd() // pause the machine, change the instruction, move the PC, resume pio_sm_set_enabled(pioblk_rw, SM_MUX, false); uint32_t save = hw_claim_lock(); - pioblk_rw->instr_mem[pio_mux_offset] = pio_encode_set(pio_x, num_dcd_drives) | pio_encode_sideset_opt(1, 0); + pioblk_rw->instr_mem[pio_mux_offset] = pio_encode_set(pio_x, num_dcd_drives) | pio_encode_sideset_opt(3, 0); hw_claim_unlock(save); - pio_dcd_mux(pioblk_rw, SM_MUX, pio_mux_offset, MUX_OUT); + pio_mux(pioblk_rw, SM_MUX, pio_mux_offset, MCI_CA0, MUX_OUT); } int chan_latch_addr, chan_latch_data; @@ -431,13 +403,9 @@ void setup() printf("Loaded DCD write program at %d\n", pio_write_offset); pio_dcd_write(pioblk_rw, SM_DCD_WRITE, pio_write_offset, LATCH_OUT); - pio_mux_offset = pio_add_program(pioblk_rw, &dcd_mux_program); - printf("Loaded DCD mux program at %d\n", pio_mux_offset); - pio_dcd_mux(pioblk_rw, SM_MUX, pio_mux_offset, MUX_OUT); - - // pio_mux_offset = pio_add_program(pioblk_rw, &mux_program); - // printf("Loaded Floppy mux program at %d\n", pio_mux_offset); - // pio_mux(pioblk_rw, SM_MUX, pio_mux_offset, MCI_CA0, ECHO_OUT); + pio_mux_offset = pio_add_program(pioblk_rw, &mux_program); + printf("Loaded mux program at %d\n", pio_mux_offset); + pio_mux(pioblk_rw, SM_MUX, pio_mux_offset, MCI_CA0, MUX_OUT); } void dcd_loop(); @@ -490,8 +458,7 @@ void esp_loop() case 'h': // harddisk is mounted/unmounted num_dcd_drives = uart_getc(UART_ID); printf("\nNumber of DCD's mounted: %d", num_dcd_drives); - if (disk_mode == DCD) - set_num_dcd(); + set_num_dcd(); // tell SM_MUX how many DCD's and restart it c = 0; // need to clear c so not picked up by floppy loop although it would never respond to 'h' break; case 's': @@ -520,7 +487,6 @@ void floppy_loop() if (gpio_get(ENABLE) && (num_dcd_drives > 0)) { - // pio_sm_put_blocking(pioblk_rw, SM_LATCH, dcd_get_latch()); // send the register word to the PIO disk_mode = TO_DCD; return; } @@ -586,7 +552,6 @@ void floppy_loop() printf("\nUNKNOWN PHASE COMMAND"); break; } - // pio_sm_put_blocking(pioblk_rw, SM_LATCH, get_latch()); // send the register word to the PIO uart_putc_raw(UART_ID, (char)(a + '0')); } @@ -640,7 +605,6 @@ void floppy_loop() break; } // printf("latch %04x", get_latch()); - // pio_sm_put_blocking(pioblk_rw, SM_LATCH, get_latch()); // send the register word to the PIO c = 0; // clear c because processed it and don't want infinite loop } // to do: read both enable lines and indicate which drive is active when sending single char to esp32 @@ -729,7 +693,7 @@ void dcd_loop() dcd_deassert_hshk(); pio_sm_set_enabled(pioblk_rw, SM_DCD_WRITE, false); pio_sm_set_enabled(pioblk_rw, SM_LATCH, true); - pio_sm_exec(pioblk_rw, SM_MUX, pio_encode_set(pio_pindirs, 0)); + pio_sm_exec(pioblk_rw, SM_MUX, pio_encode_set(pio_pindirs, 0)); // to do - does this do anything because out pins not set? break; default: host = false; @@ -1291,12 +1255,6 @@ void pio_dcd_commands(PIO pio, uint sm, uint offset, uint pin) pio_sm_set_enabled(pio, sm, true); } -void pio_dcd_mux(PIO pio, uint sm, uint offset, uint pin) -{ - dcd_mux_program_init(pio, sm, offset, pin); - pio_sm_set_enabled(pio, sm, true); -} - void pio_dcd_read(PIO pio, uint sm, uint offset, uint pin) { dcd_read_program_init(pio, sm, offset, pin); diff --git a/pico/mac/dcd_mux.pio b/pico/mac/dcd_mux.pio.old similarity index 100% rename from pico/mac/dcd_mux.pio rename to pico/mac/dcd_mux.pio.old diff --git a/pico/mac/mux.pio b/pico/mac/mux.pio index ada87928f..b6d2caa80 100644 --- a/pico/mac/mux.pio +++ b/pico/mac/mux.pio @@ -6,44 +6,84 @@ ; ; +.define public LSTRB 13 +.define public ENABLE 7 +.define public DISKFLAG 12 + +; The DCD mux will really control the RD line direction. +; It will ... +; count the number of strobes and disable RD after 1, 2, or 3 of them +; it will reset the counter when disable goes high +; probably at some point should push the strobe counter so the FN can decide which disk image to use +; +; combining with Floppy MUX: +; when disabled, should be in hi-z and waiting for enable +; when disabled should go back to DCD mode +; when drive counter == 0 should go to floppy mode + .program mux -.side_set 3 opt pindirs -start: - jmp pin next4 - mov osr, pins ; get the input phases +.side_set 3 opt pindirs + ; initial state is RD is hi-z and we have 2 DCDs + ; we wait to be enabled then RD goes to output + +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 +floppy: + set pins, 0 ; otherwise we're in floppy mode! + jmp pin start ; if not ENABLED then go back to the beginning + mov osr, pins ; otherwise get the input phases out x, 4 ; copy to X set y, 0b0100 ; RDDATA (head 0) jmp x!=y next1 - jmp start side 0b010 + jmp floppy side 0b010 next1: set y, 0b1100 ; RDDATA (head 1) jmp x!=y next2 - jmp start side 0b010 + jmp floppy side 0b010 next2: set y, 0b1011 ; TACH jmp x!=y next3 - jmp start side 0b001 + jmp floppy side 0b001 next3: ; LATCH - jmp start side 0b100 -next4: - jmp start side 0b000 ; enable high (not enabled) + jmp floppy side 0b100 +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 + out y, 1 ; stick it in Y + jmp !Y dcd ; not strobing loop +.wrap + % 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 mux_program_init(PIO pio, uint sm, uint offset, uint in_pin, uint mux_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, in_pin-1); + 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_out_shift(&c, true, false, 4); + sm_config_set_set_pins(&c, DISKFLAG, 1); // todo: update with a parameter + sm_config_set_out_shift(&c, true, false, 0); + sm_config_set_in_shift(&c, true, true, 32); 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); } -%} \ No newline at end of file +%} + diff --git a/pico/mac/mux.pio.old b/pico/mac/mux.pio.old new file mode 100644 index 000000000..ada87928f --- /dev/null +++ b/pico/mac/mux.pio.old @@ -0,0 +1,49 @@ +; +; FujiNet Project +; +; Vintage Macintosh Microfloppy Controller Interface +; selects output pins between RMT, TACH and LATCH +; +; + +.program mux +.side_set 3 opt pindirs +start: + jmp pin next4 + mov osr, pins ; get the input phases + out x, 4 ; copy to X + set y, 0b0100 ; RDDATA (head 0) + jmp x!=y next1 + jmp start side 0b010 +next1: + set y, 0b1100 ; RDDATA (head 1) + jmp x!=y next2 + jmp start side 0b010 +next2: + set y, 0b1011 ; TACH + jmp x!=y next3 + jmp start side 0b001 +next3: ; LATCH + jmp start side 0b100 +next4: + jmp start side 0b000 ; enable high (not enabled) + +% 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 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, in_pin-1); + // there are 4 wires to read for latch mux, shift to the right, no autopull + sm_config_set_out_shift(&c, true, false, 4); + 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); + // initialize + pio_sm_init(pio, sm, offset, &c); +} +%} \ No newline at end of file