Stabiler Raster - ein paar generelle Fragen...


  • Mnemonic
  • 4567 Aufrufe 61 Antworten

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • RE: stabiler Raster - paar generelle Fragen...

    Originally posted by Roland
    Original von Fröhn
    Oder im 2. IRQ einfach drei mal PLA.


    Ehm...sind 6 PLAs (wenn der IRQ über $0314/0315 - also dem Kernal - geht).

    Kernal? Wer benutzt denn sowas?

    Originally posted by Oliver_A
    Wobei ich sagen würde, dass die CIA Methode leichter als die Lightpen methode ist. Frage ist auch: welcher Anfänger möchte die X-Position auslesen. ;)

    Beide Methoden sind aber nichts für Anfänger. Die Doppel-IRQ-Methode ist eigentlich die einfachste.
  • Hallo zusammen,

    erstmal sorry, dass ich den Thread nochmal aufwärme... :rotwerd:

    Ich hab' mich endlich mal in Ruhe mit dem Beispiel von Roland beschäftigen können, und hab' mir das mal ein bisschen angepasst, klappt soweit auch wunderbar. So sieht das jetzt mal aus...


    Quellcode

    1. * = $2000
    2. SEI
    3. LDA #$01
    4. STA $D01A
    5. STA $DC0D
    6. LDA #$1B
    7. STA $D011
    8. LDA #$3c
    9. STA $D012
    10. LDA #<STABLE
    11. STA $0314
    12. LDA #>STABLE
    13. STA $0315
    14. JSR INIT
    15. CLI
    16. SCHLEIFE :
    17. JMP SCHLEIFE
    18. STABLE :
    19. LDA #$3D
    20. STA $D012
    21. LDA #<INTMAIN1
    22. STA $0314
    23. NOP (2 Zyklen)
    24. NOP (2 Zyklen)
    25. ASL $D019 (6 Zyklen)
    26. CLI
    27. NOPLOOP :
    28. NOP
    29. NOP
    30. NOP
    31. NOP
    32. NOP
    33. NOP
    34. NOP
    35. NOP
    36. PLA
    37. TAY
    38. PLA
    39. TAX
    40. PLA
    41. RTI
    42. INTMAIN1 :
    43. NOP
    44. NOP
    45. NOP
    46. BIT $00
    47. LDA #<STABLE
    48. STA $0314
    49. LDA #>STABLE
    50. STA $0315
    51. LDA $D012
    52. CMP #$3D
    53. BEQ NEXT
    54. NEXT :
    55. LDA #$3C
    56. STA $D012
    57. LDX #$04
    58. WAIT :
    59. DEX
    60. BNE WAIT
    61. INC $D021
    62. JSR $1003
    63. DEC $D021
    64. ASL $D019
    65. PLA
    66. TAY
    67. PLA
    68. TAX
    69. PLA
    70. RTI
    71. INIT :
    72. LDA #$00
    73. TAX
    74. TAY
    75. JSR $1000
    76. RTS
    Alles anzeigen


    Jetzt wollte ich aber im unter "STABLE" nicht nur das Low-Byte für den nächsten Interrupt "INTMAIN1" setzen, sondern auch das High-Byte, da mein Code ja durchaus auch einmal an einer Pagegrenze liegen kann und sich das High-Byte dann ändert.

    Ich habe dann die zwei NOP's und das ASL $D019 (zusammen 10 Zyklen) durch Befehle mit dem gleichen Zyklenverbrauch ersetzt, etwa so...

    Quellcode

    1. * = $2000
    2. SEI
    3. LDA #$01
    4. STA $D01A
    5. STA $DC0D
    6. LDA #$1B
    7. STA $D011
    8. LDA #$3c
    9. STA $D012
    10. LDA #<STABLE
    11. STA $0314
    12. LDA #>STABLE
    13. STA $0315
    14. JSR INIT
    15. CLI
    16. SCHLEIFE :
    17. JMP SCHLEIFE
    18. STABLE :
    19. LDA #$3D
    20. STA $D012
    21. LDA #<INTMAIN1
    22. STA $0314
    23. LDA #>INTMAIN1 (2 Zyklen)
    24. STA $0315 (4 Zyklen)
    25. STA $D019 (4 Zyklen)
    26. CLI
    27. NOPLOOP :
    28. NOP
    29. NOP
    30. NOP
    31. NOP
    32. NOP
    33. NOP
    34. NOP
    35. NOP
    36. PLA
    37. TAY
    38. PLA
    39. TAX
    40. PLA
    41. RTI
    42. INTMAIN1 :
    43. NOP
    44. NOP
    45. NOP
    46. BIT $00
    47. LDA #<STABLE
    48. STA $0314
    49. LDA #>STABLE
    50. STA $0315
    51. LDA $D012
    52. CMP #$3D
    53. BEQ NEXT
    54. NEXT :
    55. LDA #$3C
    56. STA $D012
    57. LDX #$04
    58. WAIT :
    59. DEX
    60. BNE WAIT
    61. INC $D021
    62. JSR $1003
    63. DEC $D021
    64. ASL $D019
    65. PLA
    66. TAY
    67. PLA
    68. TAX
    69. PLA
    70. RTI
    71. INIT :
    72. LDA #$00
    73. TAX
    74. TAY
    75. JSR $1000
    76. RTS
    Alles anzeigen


    Sind also an der Stelle ebenfalls 10 Zyklen, aber mein IRQ flattert dann um 1 Zyklus. O.k., die Befehle haben zwar genau 1 Byte mehr, aber das kann doch net angehen, oder? Ich dachte, es kommt nur auf die verbrauchten Zyklen an, damit das stabil wird und bleibt...?!? :nixwiss:

    Ich bin jetzt echt ein bisschen ratlos. Hat da jemand noch ein paar Tips für mich? Ich hab' beide Beispiele mal mit angehängt.

    Gruß,

    Mnemonic
    Dateien
    • RASTER1.PRG

      (4,22 kB, 14 mal heruntergeladen, zuletzt: )
    • RASTER2.PRG

      (4,23 kB, 12 mal heruntergeladen, zuletzt: )
    Alle alphabetisch angeordnet einem in Satz sein sollten Worte.
  • Eventuell war das vorher auch gar nicht richtig stabil. Ersetze doch mal deine "SCHLEIFE" durch eine Abfolge von Befehlen mit möglichst unterschiedlicher Ausführungszeit, statt nur dem einen JMP. Es kann sein, dass sich das vorher so ergeben hat, dass es stabil erschien. Absolut wichtig ist, dass das Timing des Vergleichs für "NEXT" genau stimmt (hab ich jetzt nicht nachgeguckt). Zähl doch nochmal die Zyklen nach.
  • nein... das problem ist, dass der neue IRQ einfach zu spät mit dem CLI wieder freigegeben wird.
    Der erste IRQ verbraucht ja durch die Kernal-Routine auf $FF48 bis er dann über ($0314) auf den ersten IRQ Teil springt einiges an Zyklen.
    Wenn du dann noch 6 weitere Zyklen für das LDA #$xx STA $0315 vor dem ASL $D019 CLI einbaust, hat die neue Rasterzeile in der
    der zweite IRQ starten soll evtl. schon angefangen.
    Das bringt natürlich das Timing durcheinander....
    ...d.h. dass die erste Routine aber wohl auch nicht ganz korrekt ist (mit den 2 NOPs und dem ASL $D019...) ... da ist wenn du mit dem Kernal IRQ über $0314 arbeitest wirklich sehr wenig Zeit...für das umsetzen von $0314 UND $0315 reichts glaube ich nicht.
    ....müsste aber um ganz sicher zu sein das nochmal ganz genau anschauen...
  • @sauhund: Hm, also in den angehängten Beispielen läuft ja 'ne Musikroutine, und die ist echt nicht grade "rund". ;)

    Beim ersten Beispiel ist es damit wirklich absolut stabil, hatte auch noch andere Sachen in den Beispielen drin vorher, so dass die sich wirklich nur in den 2 NOP's + ASL $D019 bzw. LDA #>INTMAIN1 + STA $0315 + STA $D019 unterschieden haben. Das zweite "flattert" halt um einen Zyklus.

    @roland: Die NOP's in der ersten Routine sind nur da um zu testen, wieviel "Overhead" ich da noch habe, sind wohl genau diese vier Zyklen. Damit bzw. weniger ist es auch komplett stabil.

    Ich wollte halt jetzt diese vier "freien" Zyklen zusammen mit den 6 Zyklen vom ASL $D019 (10 insgesamt) dafür verwenden, um auch das High-Byte zu setzen, d.h. 2 Zyklen für das LDA #>INTMAIN1, 4 für das STA $D015 und 4 für das STA $D019 als Ersatz für das ASL $D019 mit 6 Zyklen. Meine Idee ist halt, das ASL $D019 durch ein STA $D019 zu ersetzen, um zwei Zyklen freizukriegen für das Setzen des High-Byte.

    Sind in beiden Varianten exakt 10 Zyklen, hab' ich auch im Monitor vom CCS64 verfolgen können. Deshalb verstehe ich halt nicht wirklich, wieso es im zweiten Beispiel flattert, trotz der exakt gleichen Anzahl an Taktzyklen. :nixwiss:

    Ratloser Gruß,

    Mnemonic
    Alle alphabetisch angeordnet einem in Satz sein sollten Worte.
  • Du solltest die Musikroutine aber außerhalb des IRQ einbinden (also innerhalb der SCHLEIFE im Hauptprogramm), um eventuelle Unstimmigkeiten beim IRQ-Timing zu entdecken. Das klingt dann zwar nicht mehr so schön, aber das ist ja beim Debuggen erstmal egal :D
  • Hm, aber der Schreibzugriff auf das VIC-Register ist in beiden Fällen im gleichen Zyklus. Natürlich kommt's drauf an, was man da so in das Register schreibt. :) Bei ASL wird Bit 0 immer cleared, und dieses Bit ist ja für den Raster-IRQ zuständig.
  • Kann man denn überhaupt den Rasterlatch löschen, wenn man da einfach irgendwas reinschreibt wie in obigem Programm? Ich hab bisher immer gedacht, man muss wenigstens die Bits für den IRQ-Auslöser zurückschreiben (sprich Bit#0).
    Ein kurzer Test mit CCS64 scheint zu bestätigen, dass n Wert wie $20 nicht geht, aber aufm echten Cevi hab ich bisher immer nur entweder den Registerinhalt zurückgeschrieben oder LSR oder ähnliche RMW-Befehle probiert (und bin auch jetzt zu faul das auszuprobieren...)
  • @roland: Ja, hab' ich mir eben auch nochmal so angeschaut... wenn das so ist, dann war's wohl nix mit meiner Idee, einfach den Inhalt des Akkus, wo ja ohnehin was drinsteht, in $D019 zu pusten, um beim Löschen des IRQ-Latch zwei Zyklen zu sparen. :(

    Auf die Idee, dass der STA-Befehl auf $D019 den VIC evtl. erst zu 'nem anderen Zeitpunkt wieder freigibt als der ASL, wär' ich wohl im Leben net gekommen...

    Dann werd' ich mal versuchen, mir das mit den IRQ's ohne Kernel draufzuschaffen und probier's dann mal damit... obwohl's mir da jetzt auch schon wieder vor dem austimen graut. :cursing: Aber was hilft's, da muss ich dann jetzt halt auch durch.

    Danke für Eure Mühe und ein schönes Wochenende,

    Mnemonic
    Alle alphabetisch angeordnet einem in Satz sein sollten Worte.

  • Bei ASL wird Bit 0 immer cleared, und dieses Bit ist ja für den Raster-IRQ zuständig.

    aber vorher kommt noch der dummy write der den original wert zurückschreibt.... wenn das nicht so wäre würde das garnicht funktionieren :)
  • Damit dürfte dann auch klar sein warum das 2. Programmbeispiel nicht geht: Der Interrupt-Latch wird nicht richtig geklärt und der 2. Irq springt sofort nach dem CLI an, egal ob nu Rasterzeile 3c oder 3d ist...
  • @sauhund,
    OK, dann macht auch die Registerbeschreibung aus AAY64/Mapping the 64 wieder Sinn... (Bits auf 1 setzen, um zu schreiben). Wann passiert denn dieser Write bei ASL & Co?
  • Ehm....pass mal auf. Kleiner Trick ;)
    Dreh einfach mal das LDA #$45 STA $0314 LDA #$20 STA $0315 um.... also: LDA #$20 STA $0315 LDA #$45 STA $0314 ....
    wichtig ist halt, dass BIT 0 geschrieben wird.
    Oder du setzt das LDA #$3D STA $D012 nach hinten (direkt vor den STA $D019).
    Ob bei ganz ungünstiger Zyklenverteilung der neue IRQ allerdings noch rechtzeitig freigegeben wird bin ich mir nicht sicher...

  • OK, dann macht auch die Registerbeschreibung aus AAY64/Mapping the 64 wieder Sinn... (Bits auf 1 setzen, um zu schreiben). Wann passiert denn dieser Write bei ASL & Co?


    die RMW befehle sind eigentlich alle RWMW (vereinfacht, passt aber in der praxis eigentlich immer =P)
  • @roland: Schade, geht beides nur bei graden Werten bzw. Adressen im Akku, sonst flackert's wieder.

    Naja, dann werde ich mich mal auf die IRQ's ohne Kernel stürzen (seufz)... dann hab' ich wenigsten genügend Zyklen für die Befehle.

    Gruß und Danke an alle,

    Mnemonic
    Alle alphabetisch angeordnet einem in Satz sein sollten Worte.
  • Du kannst ja n "Hybrid"-IRQ, d.h. den ersten mit und den zweiten ohne Kernal machen, der sich vom Timing her vom ersten Programmbeispiel nicht unterscheiden sollte, aber evtl. Murks produziert, wenn der stabilisierende IRQ über die Nop-schleife hinausgeht:

    Quellcode

    1. * = $2000
    2. SEI
    3. LDA #$01
    4. STA $D01A
    5. STA $DC0D
    6. LDA #$1B
    7. STA $D011
    8. LDA #$3c
    9. STA $D012
    10. LDA #<STABLE
    11. STA $0314
    12. LDA #>STABLE
    13. STA $0315
    14. LDA #<INTMAIN1 ;stabilen Irq-Vector direkt an passender Stelle unter das Kernal schreiben
    15. STA $fffe
    16. LDA #>INTMAIN1
    17. STA $ffff
    18. JSR INIT
    19. CLI
    20. SCHLEIFE :
    21. JMP SCHLEIFE
    22. STABLE :
    23. LDA #$3D
    24. STA $D012
    25. LDA #$35 ;Kernal/Basic aus
    26. STA $01 ;da fehlt jetzt ein Cycle im Vergleich zum alten Timing
    27. TSX ;Stackptr retten (auch 2 Zyklen)
    28. ASL $D019 (6 Zyklen)
    29. CLI
    30. NOPLOOP :
    31. NOP ;Extra-Nop wg. fehlendem Cycle
    32. NOP
    33. NOP
    34. NOP
    35. NOP
    36. NOP
    37. NOP
    38. NOP
    39. NOP
    40. PLA ;falls der Loop bis hier durchkommt gibts bestimmt Murks, wenn der Kernal aus ist
    41. TAY ;daher lieber wegmachen und durch jede Menge Nops + jmp noploop ersetzen
    42. PLA
    43. TAX
    44. PLA
    45. RTI
    46. INTMAIN1 :
    47. TXS ;Stackptr wiederherstellen (auch 2 Zyklen)
    48. NOP
    49. LDA #$37 ;Kernal wieder an, alles wie vorher
    50. STA $01
    51. LDA #<STABLE ;eigentlich überflüssig, aber zwecks Timingerhalts dringelassen :-)
    52. STA $0314
    53. LDA #>STABLE
    54. STA $0315
    55. LDA $D012
    56. CMP #$3D
    57. BEQ NEXT
    58. NEXT :
    59. LDA #$3C
    60. STA $D012
    61. LDX #$04
    62. WAIT :
    63. DEX
    64. BNE WAIT
    65. INC $D021
    66. JSR $1003
    67. DEC $D021
    68. ASL $D019
    69. PLA
    70. TAY
    71. PLA
    72. TAX
    73. PLA
    74. RTI
    Alles anzeigen


    Wenn ich mich da nicht irgendwo furchtbar vertan hab (was nicht ungewöhlich wär) sollte das eigentlich so gehen.
  • Hi...ich hab hier eine Variante, die GANZ OHNE Umsetzen der $0314 / $0315 Adressen auskommt ;)

    Quellcode

    1. .C:2000 78 SEI
    2. .C:2001 A9 01 LDA #$01
    3. .C:2003 8D 1A D0 STA $D01A
    4. .C:2006 8D 0D DC STA $DC0D
    5. .C:2009 A9 1B LDA #$1B
    6. .C:200b 8D 11 D0 STA $D011
    7. .C:200e A9 3C LDA #$3C
    8. .C:2010 8D 12 D0 STA $D012
    9. .C:2013 A9 24 LDA #$24
    10. .C:2015 8D 14 03 STA $0314
    11. .C:2018 A9 20 LDA #$20
    12. .C:201a 8D 15 03 STA $0315
    13. .C:201d 20 6B 20 JSR $206B
    14. .C:2020 58 CLI
    15. .C:2021 4C 21 20 JMP $2021
    16. .C:2024 EE 19 D0 INC $D019
    17. .C:2027 A9 3D LDA #$3D
    18. .C:2029 8D 12 D0 STA $D012
    19. .C:202c CD 12 D0 CMP $D012
    20. .C:202f F0 0F BEQ $2040
    21. .C:2031 58 CLI
    22. .C:2032 EA NOP
    23. .C:2033 EA NOP
    24. .C:2034 EA NOP
    25. .C:2035 EA NOP
    26. .C:2036 EA NOP
    27. .C:2037 EA NOP
    28. .C:2038 EA NOP
    29. .C:2039 EA NOP
    30. .C:203a EA NOP
    31. .C:203b EA NOP
    32. .C:203c EA NOP
    33. .C:203d 4C 81 EA JMP $EA81
    34. .C:2040 EA NOP
    35. .C:2041 CD 12 D0 CMP $D012
    36. .C:2044 F0 00 BEQ $2046
    37. .C:2046 A9 3C LDA #$3C
    38. .C:2048 8D 12 D0 STA $D012
    39. .C:204b A2 03 LDX #$03
    40. .C:204d CA DEX
    41. .C:204e D0 FD BNE $204D
    42. .C:2050 EE 21 D0 INC $D021
    43. .C:2053 20 03 10 JSR $1003
    44. .C:2056 CE 21 D0 DEC $D021
    45. .C:2059 4C 81 EA JMP $EA81
    46. .C:205c EA NOP
    47. .C:205d D0 FD BNE $205C
    48. .C:205f EE 21 D0 INC $D021
    49. .C:2062 20 03 10 JSR $1003
    50. .C:2065 CE 21 D0 DEC $D021
    51. .C:2068 4C 81 EA JMP $EA81
    52. .C:206b A9 00 LDA #$00
    53. .C:206d AA TAX
    54. .C:206e A8 TAY
    55. .C:206f 4C 00 10 JMP $1000
    Alles anzeigen