;---------------------------------------------------------------------------
;mem                    interfacciamento con memoria SRAM
;      MEM_WE,flag  = 1 scrittura in memoria
;                     0 lettura da memoria
;      MEM_DIR,flag = 1 accesso diretto, scrive il byte a in mem
;                     0 scrive dati da RAM uP  (resettato a fine routine)
;      v = off_set byte da inizio riga
;      w = numero bytes (1 riga = NO_BYTES(20))
;      y = indirizzo di partenza uP, in modo diretto contiene byte dato tx
;      x = numero riga in mem
;      used: stack1= off-set (v)
;            stack2= n.bytes (w)
;            stack3= n.riga  (x)
;            stack4= add uP  (y)
;               CE      WE      E1      E2      MEM
;                0       0       0       0      write
;                0       1       0       0      read
;                1       0       0       1      data 8-12
;                1       1       1       0      data 0-7
;        ;-------- scrittura in SRAM -------
;        set     MEM_TX,flag     ;scrittura in ram
;        res     MEM_DIR,flag   ;preleva dati da RAM
;        ldi     v,0             ;dal byte n.0 della riga
;        ldi     w,NO_RIGA       ;di 20 bytes
;        ldi     y,ADD_BUFD      ;inizio buffer uP
;        ldi     x,0             ;numero riga in mem
;        call    mem
;        ;----------------------------------
;---------------------------------------------------------------------------
mem:
        down
        ld      baka,a                  ;push a       dato

        ld      a,v
        ld      bakv,a                  ;push v       off-set (0 inizio riga)
        ld      stack1,a

        ld      a,w
        ld      bakw,a                  ;push w       n. bytes NO_BYTES (20)
        ld      stack2,a

        ld      a,x
        ld      bakx,a                  ;push x       n. riga mem
        ld      stack3,a                

        ld      a,y
        ld      baky,a                  ;push y       inizio buffer up
        ld      stack4,a
        ;ld      add_up,a@
mem2
        down
        ;------------- CALCOLO INDIRIZZO MEMORIA --------------
        ;stack3 = numero riga mem        x
        ;stack1 = numero byte nella riga v off-set
        ;NO_RIGA = numero byte in una riga display
        clr     y
        clr     x
        ld      a,stack3
        cpi     a,0             ;numero di riga rx 
        jrnz    mem_add           ;indirizzo per riga0 = 0
        jp      mem_addoff
mem_add
        ld      w,a             ;contatore
        clr     a
mem_addloop
        addi    a,NO_RIGA       ;n. caratteri per riga display LSB
        jrnc    mem_addnooverfl
        inc     y               ;overflow, incrementa MSB
mem_addnooverfl
        dec     w
        jrnz    mem_addloop
        ld      x,a             ;yx contengono indirizzo mem
mem_addoff
        ;--- aggiunta off-set ---
        ld      a,x
        add     a,stack1
        jrnc    mem_okadd
        inc     y               ;overflow, incrementa y
mem_okadd
        ld      x,a
        ;------------------------
        ; y,x indirizzo numerico mem

        ;----- composizione indirizzo reale (linee scombinate) ------

        ;------------------------------------------------------------------
        ;y   7   6   5   4   3   2   1   0  x  7   6   5   4   3   2   1   0
        ;A              12  11  10   9   8     7   6   5   4   3   2   1   0
        ;
        ;Bus             3   6   7   5   4     0   1   2   3   4   5   6   7
        ;A  10  11   9   8  12                 0   1   2   3   4   5   6   7
        ;es: A8 arriver… dalla linea 4 del bus (e non dalla 0) bit 0 di y
        ;deve essere trasferito in bit 4
        ;------------------------------------------------------------------

        ;----- inversione di x -----
        ;--------------------------------------------------------------------------
        ; La seguente routine inverte lo stato dell'accumulatore, per garantire la
        ; compatibilita`.
        ; v= temporaneo in cui si compone l'uscita
        ; w= contatore
        ; x= dato in
        ; a= accumulatore
        ;--------------------------------------------------------------------------
        ld      a,x
reverse ldi w,1                         ; maschera
        clr v
        ld x,a
lrev    ld a,x
        rlc a
        ld x,a
        jrnc breset
        ld a,v
        add a,w
        ld v,a
breset  ld a,w
        sla a
        ld w,a
        jrnc lrev
        ld a,v
        ld      x,a
        ;--------- composizione di y ---------
        clr     w
        jrr     0,y,mem_0yr
        set     4,v                     ;se 0,y =1 allora 4,v =1 (A8)
mem_0yr   ;---------
        jrr     1,y,mem_1yr
        set     5,v                     ;se 1,y =1 allora 5,v =1 (A9)
mem_1yr   ;---------
        jrr     2,y,mem_2yr
        set     7,v                     ;se 2,y =1 allora 7,v =1 (A10)
mem_2yr   ;---------
        jrr     3,y,mem_3yr
        set     6,v                     ;se 3,y =1 allora 6,v =1 (A11)
mem_3yr   ;---------
        jrr     4,y,mem_4yr
        set     3,v                     ;se 4,y =1 allora 3,v =1 (A12)
mem_4yr   ;---------
        ld      a,v
        ld      y,a
mem_add0end
        ;       y,x indirizzo reale mem
        ;       a,w,v compromessi
        ;----------- FINE CALCOLO INDIRIZZO MEMORIA ----------



        ;----------- scrittura indirizzo (comune a tx e rx) -----------
        ;------- settaggio indirizzo ---------
        ;----------
        res     DATA,bk_pa                      ;___
        ld      a,bk_pa                         ;   |   CE=1 WE=0 add 8-12
        ld      dra,a                           ;   |___
        ;----------
        ld      a,y
        ld      drb,a                           ;invio A 8-12
        ;----------
        set     DATA,bk_pa                      ;    ___
        ld      a,bk_pa                         ;   |
        ld      dra,a                           ;___|   CE=1 WE=1 add 0-7
        ;----------
        ld      a,x
        ld      drb,a                           ;invio A 0-7
        ;----------
        ;----- abilitazione memoria ------
        res     CS_MEM,bk_pa                    ;___
        ld      a,bk_pa                         ;   |
        ld      dra,a                           ;   |___ CE=0 WE=1 : read

        ;-------- riconoscimento lettura o scrittura -----------
        jrs     MEM_TX,flag,mem_wr
        jp      mem_rd
mem_wr
        ;------------- tx ---------------
        ;--- leggi dato da tx ---
        ld      a,baka
        jrs     MEM_DIR,flag,mem_wrcl
        ld      a,stack4
        ld      x,a                             ;carica indirizzo uP
        ld      a,(x)
mem_wrcl
        ;---- invio dato alla mem ----
        ld      drb,a
        ;----- abilitazione memoria ------ CS_MEM=0 WE=1
        res     DATA,bk_pa                      ;___
        ld      a,bk_pa                         ;   |   CE=0 WE=0 write
        ld      dra,a                           ;   |___
        ;---------------------------------
        set     DATA,bk_pb                      ;    ___
        ld      a,bk_pa                         ;   |
        ld      dra,a                           ;___|   CE=0 WE=1 read
        ;---------------------------------
        set     CS_MEM,bk_pa                    ;    ___
        ld      a,bk_pa                         ;   |
        ld      dra,a                           ;___|   CE=1 WE=1 add 8-12
        ;---------------------------------
        res     DATA,bk_pa                      ;___
        ld      a,bk_pa                         ;   |   CE=1 WE=0 add 0-7
        ld      dra,a                           ;   |___
        ;---------------------------------
        jp      endmem
mem_rd
        ;-------------- rx -------------
        ;----------------- lettura in mem -----------------
        ;------ drb in ricezione --------
        ldi      orb,00000000b                  ;7-0 = bus display, tasti
        ldi     ddrb,00000000b                  ;I/O port.B setup
        ldi      drb,00000000b
        ldi    bk_pb,00000000b
        ;----- acquisizione dato ----
        ld      a,drb
        ;--- acquisisci dato rx ---
        ld      baka,a                          ;salva dato rx in caso di dir
        jrs     MEM_DIR,flag,mem_cdir
        ld      a,stack4
        ld      x,a
        ld      a,baka                          ;pop a
        ld      (x),a                           ;salva in ram uP
mem_cdir
        ;----- disabilitazione memoria ------
        set     CS_MEM,bk_pa                    ;    ___
        ld      a,bk_pa                         ;   |
        ld      dra,a                           ;___|   CE=1 WE=1 add 8-12
        ;---------------------------------
        res     DATA,bk_pa                      ;___
        ld      a,bk_pa                         ;   |   CE=1 WE=0 add 0-7
        ld      dra,a                           ;   |___
        ;---------------------------------
        ;------ ripristino drb --------
        ldi     ddrb,11111111b                  ;I/O port.B setup
        ldi      orb,11111111b                  ;7-0 = bus display, tasti
        ldi      drb,00000000b                  ;
        ldi    bk_pb,00000000b                  ;
endmem
        ;---- controllo ripetizione tx ----
        dec     stack2                  ;decrementa contatore numero bytes
        jrz     enddmem
        inc     stack1                  ;inc n. byte nella riga, no overfl
        inc     stack4                  ;incrementa l'indirizzo riferim. uP
        jp      mem2
enddmem
        ;---- fine controllo ripetizione ----

        ld      a,bakx
        ld      x,a                             ;pop x
        ld      a,baky
        ld      y,a                             ;pop y
        ld      a,bakw
        ld      w,a                             ;pop w
        ld      a,bakv
        ld      v,a                             ;pop v
        ld      a,baka                          ;pop a or rx mem

        ret
