Peek und Poke in Assembler

Fragen zu Programmiersprachen und Software für den Hive und die Propellerchips
Antworten
DJLinux

Peek und Poke in Assembler

Beitrag von DJLinux »

Theoretisch kann man größere Blöcke im eRAM recht flott verschieben oder füllen
aber das Byte weise Schreiben Poke(adresse,wert) und Lesen wert=Peek(adresse)
von Spin aus geht mit PASM nur um den Faktor 2.3 schneller.

Letzendlich findet der Datentransfer zwischen eRAM und Regnatix,Administra und Bellatrix
immer über den Byte Datenbus statt das Protokoll für RAM Zugriffe plus dem Protokoll für den Bustranfer und dem Spin "Overhead" bremst alles so sehr aus das meine Entscheidung ein HiVe OS in Assembler zu schreiben nicht nur richtig ist sondern auch eigentlich notwendig.

Man denke nur an Sounds vom eRAM zu Administra oder Grafik (Bilder, Sprites, Geometrie Daten) für Bellatrix.

Wenn ein OS in Assembler diese "Services" anbietet und kein IOS Spin Code "AUF DEM BUS"
dazwischen funkt sind wohl 20 bis 30 fache Geschwindigskeitssteigerungen realistisch.

Wenn das OS schnelle "Services" anbietet sind natürlich auch z.B. flotte Spiele in Spin möglich.

Was soll's ich habe seit gestern Urlaub und eh kein Geld zum Verreisen da heist es ein OS Proggen. ;)

Grüsse Joshy

PS. Der Testcode für Peek und Poke macht keinen Unterschied zwischen
RAM Bank 1 und Bank 2 der Addressraum ist daher durchgängig von $00000-$FFFFF.

Code: Alles auswählen

{{

Hive-Computer-Projekt

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

Beschreibung    : Beide RAM-Bänke werden mit Zufallszahlen beschrieben und folgend verglichen.
                  Bei Ungleichheit wird eine Fehlermeldung augewiesen.
}}
OBJ
  ios: "ios"
        
CON

_CLKMODE     = XTAL1 + PLL16X
_XINFREQ     = 5_000_000

#0,JOB_NONE,JOB_POKE,JOB_PEEK

VAR
  long CogNr
  long JobNr     ' 3 continue params 
  long Address
  long Value
  
PRI poke(adr,val)
  Address := adr
  Value   := val
  
  dira:=0
  JobNr  := JOB_POKE
  repeat until JobNr == JOB_NONE 
  dira := IOS#DB_IN  
  
PRI peek(adr) : w
  Address := adr
  dira    := 0
  JobNr   := JOB_PEEK          
  repeat until JobNr == JOB_NONE
  dira   := IOS#DB_IN
  w := Value
          
PRI Start
  CogNr := cognew(@cog_loop,@JobNr)
  
PRI Stop
  if CogNr==-1
    return
  cogstop(CogNr)
  CogNr:=-1
      
PUB main | tast
  CogNr:=-1  
  ios.start
  
  ios.startram ' nur zum direktem Starten
  
  ios.print(string("Test für RAM Zugriffe in PASM."))
  ios.printnl
  ios.print(string("ACHTUNG: eRam wird komplett überschrieben!"))
  ios.printnl
  ios.print(string("Eingabe */<a>bbruch : "))
  tast := ios.keywait
  if tast <> "a"
     Start ' run peek/poke cog
          
     if RamTest==0
       ios.print(string("Alles OK. "))
     else
       ios.print(string("Achtung Speicher Fehler!"))
     Stop  ' stop peek/poke cog     
     
  ios.printnl
  ios.print(string("Fertig. "))
  tast := ios.keywait
  ios.stop

PUB ramtest : errors | adr1,adr2,wert,tast,t1,t2,x,y,flag

{{ramtest2 - zufallswerte werden gleichzeitig in beide rambänke geschrieben und im zweiten
schritt miteinander verglichen}}
  ios.print(string("RAM Test",$0D))
  
  ios.CurOff
  ios.SetColor(5)
  repeat y from 0 to 7
    ios.CurSetY(y+5)
    repeat x from 0 to 15
      ios.CurSetX(x+14)
      ios.print(@punkt)
      
  ios.SetColor(0) 
  ios.CurSetX(11)
  ios.CurSetY(3)
  ios.print(string("Speicher beschreiben...",$0D))

  adr1 := 0
  adr2 := ios#ERAM/2     
  ios.SetColor(4)    
  repeat y from 0 to 7
    ios.CurSetY(y+5)
    repeat x from 0 to 15
      ios.CurSetX(x+14)
      repeat 4096
        wert:=adr1 & $FF 
        poke(adr1,wert)
        poke(adr2,wert) ' second ram chip
        adr1+=1
        adr2+=1
      ios.print(@punkt)
       
  ios.SetColor(0)    
  ios.CurSetX(11)
  ios.CurSetY(3)    
  ios.print(string("Speicher vergleichen... ",$0D))
  ios.SetColor(3) 
  adr1 := 0
  adr2 := ios#ERAM/2  
  repeat y from 0 to 7
    ios.CurSetY(y+5)
    repeat x from 0 to 15
      ios.CurSetX(x+14)
      repeat 4096
        wert:=adr1 & $FF
        if peek(adr1)<>wert or peek(adr2)<>wert
          errors+=1
          ios.SetColor(2)
          flag:=1
        adr1+=1
        adr2+=1
      ios.Print(@punkt)
      if flag
        ios.SetColor(3)
        flag:=0      
    
  ios.CurOn
  ios.SetColor(0) 
  ios.CurSetX(0)
  ios.CurSetY(17)


DAT                     ORG 0

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

                        cmp     _job,#JOB_PEEK wz
              if_z      jmp     #cog_peek
              
                        ' ignore unknow job
                        jmp     #cog_loop

                        
cog_ready               mov     _ptr,par
                        mov     _job,#JOB_NONE
                        wrlong  _job,_ptr
                        jmp     #cog_loop
                                      
cog_poke                mov     _ptr,par        ' pointer of params
                        add     _ptr,#4         ' move to param 1
                        rdlong  _adr,_ptr       ' get address
                        add     _ptr,#4         ' move to param 2
                        rdlong  _val,_ptr       ' get value
                        
                        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
                        ' 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
                        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
                        mov     outa,_tmp       ' BUS + A10-A0 + D7-D0
                        
                        mov     dira,#0
                        jmp     #cog_ready
                        
cog_peek                mov     _ptr,par        ' pointer of params
                        add     _ptr,#4         ' move to param 1
                        rdlong  _adr,_ptr       ' get address
                                                
                        mov     _tmp,_adr       ' make a copy 
                        ' BUS
                        mov     outa,_BUS_INIT  ' all de-selected 
                        mov     dira,_DIR_IN    ' D7..D0 as input
                        ' 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
                        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
                        mov     outa,_adr       ' /RAMx + A10-A0
                        add     _ptr,#4         ' next param
                        mov     _tmp,ina
                        and     _tmp,#$FF       ' only D7-D0
                        wrlong  _tmp,_ptr
                        
                        mov     dira,#0
                        jmp     #cog_ready


'                       __    ____    
'                       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 %00000100_01111000_00000000_00000000
_BUS_AL_HI    long %00000100_11111000_00000000_00000000
_BUS_AL_LO    long %00000100_01111000_11111111_00000000
_BUS_WR_R1    long %00000000_01110111_11111111_11111111
_BUS_WR_R2    long %00000000_01101111_11111111_11111111
_BUS_WR_OFF   long %00000100_01111111_11111111_11111111
_BUS_RD_R1    long %00000100_01110000_00000000_00000000
_BUS_RD_R2    long %00000100_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

punkt         byte "•",0
_job          res 1
_ptr          res 1
_adr          res 1
_val          res 1
_tmp          res 1
Zuletzt geändert von DJLinux am Mi 26. Aug 2009, 22:07, insgesamt 3-mal geändert.
DJLinux

Re: Peek und Poke in Assembler

Beitrag von DJLinux »

RAM Fehler (nur simuliert)
Dateianhänge
So sollte es nicht aussehen ;-)
So sollte es nicht aussehen ;-)
Zuletzt geändert von DJLinux am Mi 26. Aug 2009, 14:44, insgesamt 2-mal geändert.
Janaha
Beiträge: 213
Registriert: Fr 29. Mai 2009, 08:30

Re: Peek und Poke in Assembler

Beitrag von Janaha »

Saubere Sache, ich freue mich schon richtig darauf auch in die Softwareentwicklung mit einsteigen zu können. Leider ist mein Gehäuse noch nicht so weit und die Hardeware steht auch noch nicht 100%ig. Hoffe deine Erweiterungen werden ihren weg in das "offizielle" Betriebssystem finden.

Grüße
Janaha
DJLinux

Re: Peek und Poke in Assembler

Beitrag von DJLinux »

Janaha hat geschrieben:Saubere Sache, ich freue mich schon richtig darauf auch in die Softwareentwicklung mit einsteigen zu können. Leider ist mein Gehäuse noch nicht so weit und die Hardeware steht auch noch nicht 100%ig. Hoffe deine Erweiterungen werden ihren weg in das "offizielle" Betriebssystem finden.

Grüße
Janaha
Mein OS wird sowas von "offiziell" und dann bastel ich einen Virus der von Cog zu Cog hüpft und "schweinische" Sachen macht.
Der "offizielle" Virenscanner dazu kostet dann nur 9,99 € monatlich bei einer mindest Vertragslaufzeit von lepperlichen 24 Monate.

:lol: :lol: :lol: :lol:
Benutzeravatar
Rainer
Beiträge: 510
Registriert: Fr 29. Mai 2009, 16:11

Re: Peek und Poke in Assembler

Beitrag von Rainer »

DJLinux hat geschrieben:
Janaha hat geschrieben:Saubere Sache, ich freue mich schon richtig darauf auch in die Softwareentwicklung mit einsteigen zu können. Leider ist mein Gehäuse noch nicht so weit und die Hardeware steht auch noch nicht 100%ig. Hoffe deine Erweiterungen werden ihren weg in das "offizielle" Betriebssystem finden.

Grüße
Janaha
Mein OS wird sowas von "offiziell" und dann bastel ich einen Virus der von Cog zu Cog hüpft und "schweinische" Sachen macht.
Der "offizielle" Virenscanner dazu kostet dann nur 9,99 € monatlich bei einer mindest Vertragslaufzeit von lepperlichen 24 Monate.

:lol: :lol: :lol: :lol:
Klau mir nicht meine Vermarktungsstrategie .. ich wollte Bubble Shooter im Jamba-Spar-Abo verticken .. nur 3,99 EUR/Monat bei 23 Jahren Vertragsbindung :)
"Wer andauernd begreift, was er tut, bleibt unter seinem Niveau."
Benutzeravatar
drohne235
Administrator
Beiträge: 2284
Registriert: So 24. Mai 2009, 10:35
Wohnort: Lutherstadt Wittenberg
Kontaktdaten:

Re: Peek und Poke in Assembler

Beitrag von drohne235 »

Jo, bei einem reinen Bytetransfer sieht es zeitlich nicht so toll aus bei PASM, aber das liegt einfach daran, dass es dabei halt ganz wenig PASM mit ganz viel Spin drumrum ist. Gegenüber der eigentlichen reinen SPIN-Routine ersetzt man ja nur wenige SPIN durch PASM und hat auch noch die Parameterübergabe auszugleichen. Aber mir fällt dazu trotzdem noch folgendes ein:

1. Parameterübergabe: Schau dir mal den Quelltext zu der vecdem1-Spielerei an die ich in einem anderen Thread gepostet hab. Die dort enthaltenen Grafikroutinen von ??? verwenden eine absolut trickreiche Parameterübergabe zwischen Spin und PASM. Normalerweise sieht dasja so aus:

Code: Alles auswählen

pub poke(adr,wert)
  para1 := adr
  para2 := wert
  pasm-funktion triggern
  ...

In den dortigen Routinen greift der Autor aber direkt auf die an poke übergebenen Parameter zu, d.h. man muß sie nicht erst in ein parameterfeld schreiben. Sieht dann so aus:

Code: Alles auswählen

pub poke(adr,wert)
  pasm-funktion triggern
Fand ich erstmal tricky, kann aber nicht sagen wie viel Zeitgewinn das bringt.

2. Warteschleife: Bei einer einfachen Byte/Word/Long Speicherfunktion kann man vielleicht recht gut das Timing abschätzen, d.h. vielleicht kann man die Warteschleife auf Beendigung der Operation einfach weglassen oder durch ein Spin-NOP ersetzen.

4. Zugriff auf kontinuierliche Speicherbereiche: Wenn man auf zusammenhängende Speicherbereiche zugreift könnte nach dem setzen des Adresszählers die PASM-Routine die Folgeadresse gleich mit einem Autoincrement selbst berechnen. Spart schon wieder ein paar SPIN-Operationen. Solche Fälle das man auf einen zusammenhängenden SPeicherblock zugreift hat man ja öfter, könnte man in eine PASM-Speicherengine eh fest integrieren.

3. Blocktransfer: Der Ramtest ist ja eigentlich genau jene Aufgabe bei, welcher Blockoperationen in PASM echt Sinn ergeben. Wenn man Spin dann nur noch diese Blockoperationen handeln und verwalten lässt spielt PASM wirklich mal mit den Muskeln.
"Ob Sie denken, dass Sie es können, oder ob Sie denken, dass Sie es nicht können - in beiden Fällen haben Sie recht." Henry Ford
Antworten