elks-enhanced
public
Read
Owner: themaster
Branch: master
Commits: 6893
Updated: 2026-04-19 00:15
Git CLI clone URL
git clone https://www.xt-emporium.com/git/elks-enhanced.git
Fullscreen desktop URL
Code
Commits
History
Branches
Bug Reports
Discussions
Compare
Settings
elks-enhanced
/
elks
/
arch
/
i86
/
drivers
/
block
/
spi-hw-necv25.S
File editor
.code16 /** * Low Level SD card SPI driver * for NEC V25 CPU using serial port 0 for hardware SPI in poll mode * driver only works with SPI Moe 3 (can't be changed) * SD cards require SPI Mode 3 but seem to work alos with Mode 3 * see https://elm-chan.org/docs/mmc/mmc_e.html on SPI Mode * * Uses special V25 opcodes set1 and clr1 * Adapted from the work of Santiago Hormazabal for 8018x CPUs * * 10. Nov. 2025 swausd * * Setup: * CS on Port 2.3 * serial has to be serial 0 * /SCK0 connected with /CTS0, Tx clock (out) to Rx clock (in) * configure baud rate by setting BR_PRSCLR to desired value * ************************************************************************** * Attention: Direction and functions of port pins have to be set in a * central position (BIOS or startup code). See definitions in necv25.h ************************************************************************** */ #include <arch/necv25.h> // pin definitions /* V25 Port pin: */ #define PIN_CS 3 /* P2.3 */ #define PIN_SCK0 6 /* P1.6 do not change! */ #define BR_PRSCLR BR_DIV2 /* baud rate prescaler = SPI clock */ .text // NEC V25 "set1" set bit instruction .macro set1 bit addr .word 0x1c0f // set1 $bit,(addr) .byte 0x06 .word \addr .byte \bit .endm // NEC V25 "clr1" clear bit instruction .macro clr1 bit addr .word 0x1a0f // clr1 $bit,(addr) .byte 0x06 .word \addr .byte \bit .endm .global spi_init_ll //void spi_init_ll(void) spi_init_ll: push %ds movw $NEC_HW_SEGMENT, %bx // load DS to access memmory mapped CPU registers movw %bx, %ds // prepare serial port 0 for synchronous mode with max baud rate movb $0x00, (NEC_SCM0) // SCM0: synchronous mode, disable Rx/Tx, external Rx clock movb $BR_PRSCLR, (NEC_SCC0) // SCM0: baud rat preselector fclk/2 = max clock movb $0x01, (NEC_BRG0) // BRG0: max Baud rate movb $0x47, (NEC_SEIC0) // SEIC0: clear Error flag movb $0x47, (NEC_SRIC0) // SRIC0: clear Rx ready flag movb $0x47, (NEC_STIC0) // STIC0: clear Tx ready flag movb $0xc0, (NEC_SCM0) // SCM0: synchronous mode, enable Rx/Tx, external Rx clock set1 PIN_CS, NEC_P2 // de-select SPI pop %ds ret .global spi_cs_0 //void spi_cs_0(void) spi_cs_0: push %ds movw $NEC_HW_SEGMENT, %bx // load DS to access memmory mapped CPU registers movw %bx, %ds clr1 PIN_CS, NEC_P2 pop %ds ret .global spi_cs_1 //void spi_cs_1(void) spi_cs_1: push %ds movw $NEC_HW_SEGMENT, %bx // load DS to access memmory mapped CPU registers movw %bx, %ds set1 PIN_CS, NEC_P2 pop %ds ret .global spi_transmit //void spi_transmit(uint8_t data) spi_transmit: mov %sp, %bx mov 2(%bx), %ax push %ds movw $NEC_HW_SEGMENT, %bx // load DS to access memmory mapped CPU registers movw %bx, %ds movb $BR_PRSCLR, (NEC_SCC0) // reset RX/TX buffers 1: testb $IRQFLAG, (NEC_STIC0) // wait for Tx ready jz 1b // clearing the Tx ready flag can be ignored movb %al, (NEC_TXB0) // send byte 2: testb $IRQFLAG, (NEC_SRIC0) // wait for byte ready jz 2b movb $(IRQMSK+IRQPRID), (NEC_SRIC0) // ignore received byte and clear Rx byte ready flag pop %ds ret .global spi_receive //uint8_t spi_receive(void) spi_receive: push %ds movw $NEC_HW_SEGMENT, %bx // load DS to access memmory mapped CPU registers movw %bx, %ds movb $BR_PRSCLR, (NEC_SCC0) // reset RX/TX buffers 1: // request byte from client by sending 0xff testb $IRQFLAG, (NEC_STIC0) // wait for Tx ready jz 1b // clearing the Tx ready flag can be ignored movb $0xff, (NEC_TXB0) // send 0xff to request answer 2: // receive byte testb $IRQFLAG, (NEC_SRIC0) // wait for byte ready jz 2b xorb %ah, %ah movb (NEC_RXB0), %al // get byte movb $(IRQMSK+IRQPRID), (NEC_SRIC0) // clear Rx byte ready flag pop %ds ret .global spi_send_ffs //void spi_send_ffs(uint16_t bytes) spi_send_ffs: mov %sp, %bx mov 2(%bx), %cx push %ds movw $NEC_HW_SEGMENT, %bx // load DS to access memmory mapped CPU registers movw %bx, %ds movb $BR_PRSCLR, (NEC_SCC0) // reset RX/TX buffers movb $0xff, %al 1: testb $IRQFLAG, (NEC_STIC0) // wait for Tx ready jz 1b // clearing the Tx ready flag can be ignored movb %al, (NEC_TXB0) // send 0xff byte 2: testb $IRQFLAG, (NEC_SRIC0) // wait for byte ready jz 2b movb $(IRQMSK+IRQPRID), (NEC_SRIC0) // ignore received byte and clear Rx byte ready flag loop 1b pop %ds ret .global spi_read_block //uint8_t spi_read_block(char *buf, ramdesc_t seg, uint16_t count) spi_read_block: mov %sp, %bx push %es push %di push %ds movw 6(%bx), %cx movw 4(%bx), %es movw 2(%bx), %di movw $NEC_HW_SEGMENT, %bx // load DS to access memmory mapped CPU registers movw %bx, %ds movb $BR_PRSCLR, (NEC_SCC0) // reset RX/TX buffers movb $IRQFLAG, %dl // setup some constant values movb $(IRQMSK+IRQPRID), %bh movb $0xff, %bl 1: // request byte from client by sending 0xff testb %dl, (NEC_STIC0) // wait for Tx ready, only for first byte in block jz 1b 2: // clearing the Tx ready flag can be ignored movb %bl, (NEC_TXB0) // send byte 3: // receive byte testb %dl, (NEC_SRIC0) // wait for byte ready jz 3b movb (NEC_RXB0), %al // get byte movb %al, %es:(%di) // store to buffer inc %di movb %bh, (NEC_SRIC0) // clear Rx byte ready flag loop 2b pop %ds pop %di pop %es ret .global spi_write_block //uint8_t spi_write_block(char *buf, ramdesc_t seg, uint16_t count) spi_write_block: mov %sp, %bx push %es push %di push %ds movw 6(%bx), %cx movw 4(%bx), %es movw 2(%bx), %di movw $NEC_HW_SEGMENT, %bx // load DS to access memmory mapped CPU registers movw %bx, %ds movb $BR_PRSCLR, (NEC_SCC0) // reset RX/TX buffers movb $IRQFLAG, %dl // setup some constant values movb $(IRQMSK+IRQPRID), %bh 1: testb %dl, (NEC_STIC0) // wait for Tx ready, only for first byte in block jz 1b 2: // clearing the Tx ready flag can be ignored movb %es:(%di), %al // get byte from buffer movb %al, (NEC_TXB0) // send byte inc %di 3: testb %dl, (NEC_SRIC0) // wait for byte ready jz 3b movb %bh, (NEC_SRIC0) // ignore received byte and clear Rx byte ready flag loop 2b pop %ds pop %di pop %es ret
Commit message
This repository is read-only for this account.
Repository snapshot
Current branch
master
Visibility
public
Your access
Read
Remote
Configured
File activity
View file history