~vdupras/collapseos

f09aa0603cdfd44f821b80645dd7039355c6646b — Virgil Dupras 14 days ago 1ac7038
rc2014: separate SPI relay and SDC drivers

My intention is to reuse the SPI relay to program AVR MCUs from a
RC2014.
14 files changed, 49 insertions(+), 36 deletions(-)

M blk/580
A blk/595
R blk/{602 => 596}
M blk/600
M blk/603
M blk/604
M blk/607
M blk/608
M blk/609
M blk/610
M blk/612
M blk/614
M blk/618
M recipes/rc2014/sdcard/README.md
M blk/580 => blk/580 +2 -1
@@ 4,4 4,5 @@ Support code for the RC2014 recipe. Contains drivers for the
ACIA, SD card and AT28 EEPROM.

581 ACIA                       590 AT28 EEPROM
600 SD card                    618 Xcomp unit
595 SPI relay                  600 SD card
618 Xcomp unit

A blk/595 => blk/595 +12 -0
@@ 0,0 1,12 @@
SPI relay driver

This driver is designed for a ad-hoc adapter card that acts as a
SPI relay between the z80 bus and the SPI device. Sending any-  
thing on SPI_CSLOW and SPI_CSHIGH is expected to select/deselect
the device, and writing to SPI_DATA is expected to initiate a   
byte exchange. The result of the exchange is excpected to be re-
trieved by reading SPI_DATA.

Provides (spie) (enable), (spid) (disable), (spix) (xchange).

Load driver with "596 LOAD".

R blk/602 => blk/596 +6 -6
@@ 1,12 1,12 @@
( Initiate SPI exchange with the SD card. n is the data to
  send. )
CODE _sdcSR  ( n -- n )
CODE (spix) ( n -- n )
    HL POP,
    chkPS,
    A L LDrr,
    SDC_SPI OUTiA,
    NOP, NOP,
    SDC_SPI INAi,
    SPI_DATA OUTiA,
    NOP, NOP, ( let SPI relay breathe )
    SPI_DATA INAi,
    L A LDrr,
    HL PUSH,
;CODE
CODE (spie) SPI_CSLOW OUTiA, ;CODE
CODE (spid) SPI_CSHIGH OUTiA, ;CODE

M blk/600 => blk/600 +5 -7
@@ 1,13 1,11 @@
SD Card driver

Load range: 602-616
Load range: 603-616

This driver is designed for a ad-hoc adapter card that acts as a
SPI relay between the z80 bus and the SD card. That adapter is  
expected to pull CS low when something is written to SDC_CSLOW,
high on SDC_CSHIGH and to initiate a SPI exchange when a byte is
written to SDC_SPI, the result of that exchange being fetched   
with a read to SDC_SPI.
SPI relay between the z80 bus and the SD card. It requires a SPI
driver providing (spix), (spie) and (spid), which oh surprise!
is included in Collapse OS at B595.

Through that layer, this driver implements the SDC protocol     
Through that layer, this driver implements the SDC protocol
allowing it to provide BLK@ and BLK!.

M blk/603 => blk/603 +0 -2
@@ 1,5 1,3 @@
CODE _sdcSel SDC_CSLOW OUTiA, ;CODE
CODE _sdcDesel SDC_CSHIGH OUTiA, ;CODE
( Computes n into crc c with polynomial 0x1021 )
CODE _crc16  ( c n -- c )
    HL POP, ( n ) DE POP, ( c )

M blk/604 => blk/604 +2 -2
@@ 1,8 1,8 @@
( -- n )
: _idle 0xff _sdcSR ;
: _idle 0xff (spix) ;

( -- n )
( _sdcSR 0xff until the response is something else than 0xff
( spix 0xff until the response is something else than 0xff
  for a maximum of 20 times. Returns 0xff if no response. )
: _wait
    0  ( cnt )

M blk/607 => blk/607 +1 -1
@@ 1,3 1,3 @@
( send-and-crc7 )
( n c -- c )
: _s+crc SWAP DUP _sdcSR DROP _crc7 ;
: _s+crc SWAP DUP (spix) DROP _crc7 ;

M blk/608 => blk/608 +1 -1
@@ 11,6 11,6 @@
    SWAP 256 /MOD ROT ( h l crc )
    _s+crc _s+crc     ( crc )
    0x01 OR           ( ensure stop bit )
    _sdcSR DROP       ( send CRC )
    (spix) DROP       ( send CRC )
    _wait  ( wait for a valid response... )
;

M blk/609 => blk/609 +3 -3
@@ 1,15 1,15 @@
( cmd arg1 arg2 -- r )
( Send a command that expects a R1 response, handling CS. )
: SDCMDR1 _sdcSel _cmd _sdcDesel ;
: SDCMDR1 (spie) _cmd (spid) ;

( cmd arg1 arg2 -- r arg1 arg2 )
( Send a command that expects a R7 response, handling CS. A R7
  is a R1 followed by 4 bytes. arg1 contains bytes 0:1, arg2
  has 2:3 )
: SDCMDR7
    _sdcSel
    (spie)
    _cmd                 ( r )
    _idle 8 LSHIFT _idle +  ( r arg1 )
    _idle 8 LSHIFT _idle +  ( r arg1 arg2 )
    _sdcDesel
    (spid)
;

M blk/610 => blk/610 +1 -1
@@ 1,4 1,4 @@
: _err _sdcDesel ABORT" SDerr" ;
: _err (spid) ABORT" SDerr" ;

( Tight definition ahead, pre-comment.


M blk/612 => blk/612 +2 -2
@@ 1,5 1,5 @@
: _sdc@  ( dstaddr blkno -- )
    _sdcSel 0x51 ( CMD17 ) 0 ROT ( a cmd 0 blkno ) _cmd
    (spie) 0x51 ( CMD17 ) 0 ROT ( a cmd 0 blkno ) _cmd
    IF _err THEN
    _wait 0xfe = NOT IF _err THEN
    0 SWAP               ( crc a )


@@ 11,5 11,5 @@
    LOOP
    DROP                 ( crc1 )
    _idle 8 LSHIFT _idle +  ( crc2 )
    _wait DROP _sdcDesel
    _wait DROP (spid)
    = NOT IF _err THEN ;

M blk/614 => blk/614 +5 -5
@@ 1,16 1,16 @@
: _sdc!  ( srcaddr blkno -- )
    _sdcSel 0x58 ( CMD24 ) 0 ROT ( a cmd 0 blkno ) _cmd
    (spie) 0x58 ( CMD24 ) 0 ROT ( a cmd 0 blkno ) _cmd
    IF _err THEN
    _idle DROP 0xfe _sdcSR DROP
    _idle DROP 0xfe (spix) DROP
    0 SWAP           ( crc a )
    512 0 DO         ( crc a )
        C@+          ( crc a+1 n )
        ROT OVER     ( a n crc n )
        _crc16       ( a n crc )
        SWAP         ( a crc n )
        _sdcSR DROP  ( a crc )
        (spix) DROP  ( a crc )
        SWAP         ( crc a )
    LOOP
    DROP ( crc ) 256 /MOD ( lsb msb )
    _sdcSR DROP _sdcSR DROP
    _wait DROP _sdcDesel ;
    (spix) DROP (spix) DROP
    _wait DROP (spid) ;

M blk/618 => blk/618 +0 -2
@@ 1,8 1,6 @@
0xff00 CONSTANT RS_ADDR        0xfffa CONSTANT PS_ADDR
RS_ADDR 0x80 - CONSTANT SYSVARS
0x8000 CONSTANT HERESTART
4      CONSTANT SDC_SPI
5      CONSTANT SDC_CSLOW      6      CONSTANT SDC_CSHIGH
582 LOAD  ( acia decl )
212 LOAD  ( z80 assembler )
262 LOAD  ( xcomp )            282 LOAD  ( boot.z80.decl )

M recipes/rc2014/sdcard/README.md => recipes/rc2014/sdcard/README.md +9 -3
@@ 71,11 71,17 @@ instead.
## Building your binary

The binary built in the base recipe doesn't have SDC drivers. Using the same
instructions as in the `eeprom` recipe, you'll need to insert those drivers.
instructions as in the `eeprom` recipe, you'll need to assemble a binary with
those drivers. First, we need drivers for the SPI relay. This is done by
declaring `SPI_DATA`, `SPI_CSLOW` and `SPI_CSHIGH`, which are respectively `4`,
`5` and `6` in our relay design. You can then load the driver with `596 LOAD`.
This driver provides `(spix)`, `(spie)` and `(spid)` which are then used in the
SDC driver.

The SDC driver is at B600. It gives you a load range. This means that what
you need to insert in `xcomp` will look like:

    602 616 LOADR  ( sdc )
    603 616 LOADR  ( sdc )

You also need to add `BLK$` to the init sequence.



@@ 104,7 110,7 @@ If there is no error message, we're fine. Then, we need to hook `BLK@*` and

And thats it! You have full access to disk block mechanism:

    102 LOAD
    105 LOAD
    BROWSE

(at this moment, the driver is a bit slow though...)