{{

Hive-Computer-Projekt

Name            : Peek and Poke
Chip            : Regnatix-Code (ramtest)
Version         : 0.1
Dateien         : ram_pasm.spin

Beschreibung    :
}}
CON

_CLKMODE     = XTAL1 + PLL16X
_XINFREQ     = 5_000_000
DB_IN        = %00000111_11111111_11111111_00000000  'maske: dbus-eingabe

#0,JOB_NONE,JOB_POKE,JOB_PEEK,JOB_FILL,JOB_WRLONG,JOB_RDLONG,JOB_WRWORD,JOB_RDWORD,DO_READ,DO_WRITE,PUT_BYTE,GET_BYTE
VAR
  long CogNr
  long JobNr     ' 3 continue params
  long Address
  long Value
  long Anzahl
  long Werte
pub rd_value(adr,m):w
    Address := adr
    Value   := m
    dira    := 0
    JobNr   := DO_READ
    repeat until JobNr == JOB_NONE
    dira   := DB_IN
    w := Werte

pub wr_value(adr,val,m)
  Address := adr
  Value   := val
  Anzahl   := m
  dira    := 0
  JobNr   := DO_WRITE
  repeat until JobNr == JOB_NONE
  dira := DB_IN

{pub get_value(chip,m):w
    Address := chip
    Value   := m
    dira    := 0
    JobNr   := GET_BYTE
    repeat until JobNr == JOB_NONE
    dira   := DB_IN
    w := Werte

pub put_value(chip,m)
    Address := chip
    Value   := m
    dira    := 0
    JobNr   := PUT_BYTE
    repeat until JobNr == JOB_NONE
    dira   := DB_IN
}
pub ram_fill(adr,anz,wert)

    Address:=adr
    Value  :=wert
    Anzahl :=anz
    dira   :=0
    JobNr  :=JOB_FILL
    repeat until JobNr==JOB_NONE
    dira:=DB_IN


Pub Start
  CogNr := cognew(@cog_loop,@JobNr)

Pub Stop
  if CogNr==-1
    return
  cogstop(CogNr)
  CogNr:=-1
DAT                     ORG 0

cog_loop                rdlong  _job,par wz   ' get job id
              if_z      jmp     #cog_loop

                        cmp     _job,#DO_WRITE wz
              if_z      jmp     #cog_write

                        cmp     _job,#DO_READ wz
              if_z      jmp     #cog_read

                        cmp     _job,#JOB_FILL wz
              if_z      jmp     #cog_fill

{                        cmp     _job,#PUT_BYTE wz
              if_z      jmp     #cog_put

                        cmp     _job,#GET_BYTE wz
              if_z      jmp     #cog_get
}
                        jmp     #cog_loop


'**************************************************************************************

cog_ready               mov     _ptr,par
                        mov     _job,#JOB_NONE
                        wrlong  _job,_ptr

                        jmp     #cog_loop
'######################################################################################
'######################################################################################
{cog_get                 call    #sub_param
                        cmp     _adr,#1      wz
             if_z       jmp     #adm_get


cog_put                 call    #sub_param
                        cmp     _adr,#1      wz
             if_z       jmp     #adm_put
             '           cmp     _adr,#2      wz
             'if_z       jmp     #bel_put
             '           cmp     _adr,#3      wz
             'if_z       jmp     #ven_put

adm_put
                       ' zeichen zu administra senden
                       ' waitpeq _hs,_hs           ' warte auf hs=1 (slave bereit)
                        and     _val,#$ff        ' wert maskieren
                        or      _val,_a1         ' + bel=0 wr=0 clk=0
                        mov     outa,_val        ' daten + signale ausgeben
                        mov     dira,_DIR_OUT    ' bus auf ausgabe schalten
                        or      outa,_a2          ' clk=0 --> clk=1
                        waitpeq _zero,_hs         ' warte auf hs=0
                        mov     dira,_DIR_IN      ' bus auf eingabe schalten
                        mov     outa,_s1          ' bussignale inaktiv
                        jmp     #cog_ready

adm_get                 ' zeichen von administra empfangen
                        waitpeq _hs,_hs           ' warte auf hs=1 (slave bereit)
                        mov     outa,_a3          ' bel=0 wr=1 clk=1
                        waitpeq _zero,_hs         ' warte auf hs=0
                        mov     _val,ina         ' daten einlesen
                        and     _val,#$ff        ' wert maskieren
                        mov     outa,_s1          ' bussignale inaktiv
                        mov     _tmp,_val
                        jmp     cog_subpeek

}
'######################################################################################
{  outa := %00001001_01011000_00000000_00000000          'prop1=0, wr=0
  dira := db_out                                        'datenbus auf ausgabe stellen
  outa[7..0] := c                                       'daten --> dbus
  outa[busclk] := 1                                     'busclk=1
  waitpeq(%00000000_00000000_00000000_00000000,%00001000_00000000_00000000_00000000,0) 'hs=0?
  dira := db_in                                         'bus freigeben
  outa := %00001101_01111000_00000000_00000000           'wr=1, prop1=1, busclk=0
}
'######################################################################################

'**************************************************************************************

cog_subpeek             add     _ptr,#4         ' Ergebnis nach Werte übergeben next param
                        wrlong  _tmp,_ptr

                        jmp     #cog_ready
'**************************************************************************************
             '########## Parameterfeld (3-Parameter) einlesen###############
sub_param               mov     _ptr,par        ' pointer of params
                        add     _ptr,#4         ' move to param 1
                        rdlong  _adr,_ptr       ' get address1
                        add     _ptr,#4         ' move to param 2
                        rdlong  _val,_ptr       ' wert
                        add     _ptr,#4         ' move to param 3
                        rdlong  _count,_ptr     ' lese Jobnummer
sub_param_ret           ret

'**************************************************************************************

cog_fill                call    #sub_param
                        mov     _ftemp,_adr     ' adresse merken

loop_fill               call    #sub_poke       ' schreiben
                        add     _ftemp, #1      'adr := adr + 1
                        mov     _adr,_ftemp     'adresse zurueckschreiben
                        djnz    _count, #loop_fill        'nächste zelle bis _count = 0

                        jmp     #cog_ready
'**************************************************************************************
cog_write               call    #sub_param
                        mov     _ftemp,_adr     ' adresse merken
                        mov     _RegA,_val      ' wert merken
                        mov     _RegB,#8        ' shiftwert
                        mov     _RegC,#3        ' Zaehlerschleifenwert
                        call    #sub_poke

                        cmp     _count,#JOB_POKE wz 'wenn nur poke hier aussteigen
              if_z      jmp     #cog_ready

loop_wrlong             mov     _val,_RegA
                        shr     _val,_RegB      'wert>>8
                        add     _RegB,#8        'shiftwert um 8 erhoehen
                        add     _ftemp, #1      'adr := adr + 1
                        mov     _adr,_ftemp     'adresse zurueckschreiben
                        call    #sub_poke

                        cmp     _count,#JOB_WRWORD wz 'wenn wrword hier aussteigen
              if_z      jmp     #cog_ready

                        djnz    _RegC,#loop_wrlong

                        jmp     #cog_ready

'**************************************************************************************
cog_read                call   #sub_param

                        mov     _ftemp,_adr     ' adresse merken
                        mov     _RegA,#8        ' shiftwert
                        mov     _RegC,#3        ' Schleifenzaehler

                        call    #sub_peek

                        cmp     _val,#JOB_PEEK wz 'wenn nur peek hier aussteigen
              if_z      jmp     #cog_subpeek

                        call    #rd_wr

loop_rd                 call    #sub_peek
                        shl     _tmp,_RegA
                        add     _tmp,_RegB
                        call    #rd_wr

                        cmp     _val,#JOB_RDWORD wz 'wenn rdword, dann hier raus
              if_z      jmp     #cog_subrdword

                        add     _regA,#8
                        djnz    _RegC,#loop_rd

cog_subrdword           add     _ptr,#4         ' next param
                        wrlong  _RegB,_ptr

                        jmp     #cog_ready


'**************************************************************************************
rd_wr                   mov     _RegB,_tmp
                        add     _ftemp,#1        'adresse+1
                        mov     _adr,_ftemp      'adresse zurueckschreiben
rd_wr_ret               ret
'**************************************************************************************

'**************************************************************************************
sub_poke                mov     _tmp,_adr       ' make a copy
                        and     _val,#$FF       ' only D7-D0
                        ' BUS
                        mov     outa,_BUS_INIT  ' all de-selected
                        mov     dira,_DIR_OUT   ' D7..D0 as output
                        call     #setadr

                        or      _adr,_val       ' D7-D0
                        or      _adr,_BUS_INIT  ' BUS
                        and     _tmp,_m_A19 wz  ' MSB of address
                        mov     _tmp,_adr
              if_z      and     _adr,_BUS_WR_R1 ' address <= $07FFFF
              if_nz     and     _adr,_BUS_WR_R2 ' address >= $800000
                        mov     outa,_adr       ' /WR+/RAMx + A10-A0 + D7-D0
                        nop
                        nop
                        mov     outa,_tmp       ' BUS + A10-A0 + D7-D0
                        nop
                        mov     dira,#0

sub_poke_ret            ret
'**************************************************************************************

sub_peek                mov     _tmp,_adr       ' make a copy

                        ' BUS

                        mov     outa,_BUS_INIT  ' all de-selected
                        mov     dira,_DIR_IN    ' D7..D0 as input
                        call    #setadr
                        and     _tmp,_m_A19 wz  ' MSB of address
                        mov     _tmp,_adr
              if_z      or      _adr,_BUS_RD_R1 ' address <= $07FFFF
              if_nz     or      _adr,_BUS_RD_R2 ' address >= $800000
                        nop
                        mov     outa,_adr       ' /RAMx + A10-A0
                        nop
                        nop
                        mov     _tmp,ina
                        nop
                        and     _tmp,#$FF       ' only D7-D0
                        mov     dira,#0
sub_peek_ret            ret
'**************************************************************************************

setadr                  ' ADR HI
                        and     _adr,_m_A18_A11 ' hi part
                        shr     _adr,#3         ' move to latch port
                        or      _adr,_BUS_AL_HI ' BUS + AL hi
                        mov     outa,_adr       ' BUS + AL hi + ADR
                        and     _adr,_BUS_AL_LO
                        mov     outa,_adr       ' BUS + AL lo + LATCH
                        ' ADR LO
                        mov     _adr,_tmp       ' from copy
                        and     _adr,_m_A10_A00 ' lo part
                        shl     _adr,#8         ' mov to address port
setadr_ret              ret
'**************************************************************************************

'                       __    ____
'                       HWCL ACBRR    Latch
'                       SRLE LSEAA    A18-A11
'                         kD  ALMMAAA AAAAAAAA DDDDDDDD
'                               21098 76543210 76543210

_DIR_OUT      long %00000111_11111111_11111111_11111111
_DIR_IN       long %00000111_11111111_11111111_00000000
_BUS_INIT     long %00000101_01111000_00000000_00000000
_BUS_AL_HI    long %00000101_11111000_00000000_00000000
_BUS_AL_LO    long %00000101_01111000_11111111_00000000
_BUS_WR_R1    long %00000001_01110111_11111111_11111111
_BUS_WR_R2    long %00000001_01101111_11111111_11111111
_BUS_RD_R1    long %00000101_01110000_00000000_00000000
_BUS_RD_R2    long %00000101_01101000_00000000_00000000
_m_A19        long %00000100_00001000_00000000_00000000
_m_A18_A11    long %00000000_00000111_11111000_00000000
_m_A10_A00    long %00000000_00000000_00000111_11111111
                          '|_________________________________ HBEAT


_job          res 1
_ptr          res 1
_adr          res 1
_val          res 1
_count        res 1
_tmp          res 22
_ftemp        res 1
_regA         res 1
_RegB         res 1
_RegC         res 1

                                                       fit 496
