DEC Attack: Die kleine Problem-Ecke

Es gibt 88 Antworten in diesem Thema, welches 11.660 mal aufgerufen wurde. Der letzte Beitrag (5. Mai 2024 um 22:32) ist von goloMAK.

  • Heute mal ein Problem, das ich schon gelöst habe. Finde es aber trotzdem ganz interessant.

    In dem Buch "Assembler Workshop" von Bruce Smith gibt es ein Programm namens "Wedge Operating System". Im Prinzip eine einfache Befehlserweiterung über einen Wedge.

    Das Programm führt drei Kommandos ein: @cls, @low und @up. Wenn man z.B. "@hallo" eingibt, landet man ohne weiteren Kommentar wieder beim READY-Prompt. So weit, so gut.

    Im Code fand ich folgende Passage:

    Code
    prompt     jsr printReady
               lda #$00
               sec
               bcs .normal
    [...]
    .normal    cmp #$3a   
               bcs .exit    

    Und ich so: Was soll das denn mit dem sec/bcs? Das Carry-Bit wird doch in .normal sowieso wieder neu bestimmt?

    Also mache ich daraus folgende, etwas kürzere Version:

    Code
    prompt     jsr printReady
               lda #$00
               beq .normal
    [...]
    .normal    cmp #$3a   
               bcs .exit 

    Das sollte doch gehen.... ODER?

    Nein, jetzt stürzt das Programm bei der Eingabe von "@hallo" ab!

    :gruebel

    Eine Merkwürdigkeit, die mir dabei im Programm auffiel, war die Befehlstabelle:

    Code
    names:
    !pet "cls",0
    !pet "low",0
    !pet "up",0
    
    init       lda #<msg
               ldy #>msg
               jsr strout
    [...]

    Ich habe mich die ganze Zeit gefragt, woher das Programm denn weiß, dass die Tabelle zuende ist?

    Und natürlich weiß es das eben gar nicht. Es sucht nach dem Ende der Tabelle einfach munter weiter im Programmcode nach irgendwelchen Kommandos. Durch einen dummen Zufall hat meine Änderung dieses Problem aufgedeckt.

    Die nötige Korrektur liegt auf der Hand: Führe eine Markierung für das Ende der Tabelle ein und prüfe sie ab. Ich weiß ja nicht, wieso Herr Smith nicht auf diese faszinierende Idee gekommen ist.

    Generell bin ich ein bisschen frustriert über die Qualität einiger Assembler-Bücher, mit denen ich mich derzeit beschäftige. Andererseits kann man natürlich auch dazulernen, wenn man solchen Problemen begegnet.

    Da ich das Programm schon mal hier habe, lade ich auch mal die (gefixte) Version hier hoch.

  • Hallo! :)

    Heute habe ich euch wieder ein kleines Problem mitgebracht!

    Aufgabe: Eine BASIC-Integervariable soll gefunden und ihr Wert ausgegeben werden. Falls sie nicht existiert, gibt es eine kurze Fehlermeldung.

    Ich habe folgenden Code, der auch funktioniert, aber doch recht laaaaaang ist. Frage: Geht das nicht irgendwie kürzer, u.U. auch unter Zugriff auf ROM-Routinen? Ich meine jetzt nicht, dass man z.B. noch ein CLC einsparen kann, sondern grundsätzlich (= wesentlich) kürzer?

    BASIC-Loader mit Beispielanwendung:

    Dateien

    Bitte melde dich an, um diesen Link zu sehen. - Ratespiel • Bitte melde dich an, um diesen Link zu sehen. - BASIC-Erweiterung • Bitte melde dich an, um diesen Link zu sehen. - Sprite-Editor • Bitte melde dich an, um diesen Link zu sehen. - Zeichensatz-Editor Bitte melde dich an, um diesen Link zu sehen. - 2048 Blöcke

    Einmal editiert, zuletzt von goloMAK (12. Februar 2024 um 19:26)

  • Gibt es dafür nicht was im ROM? Variable suchen muss doch ne Standard-Aufgabe sein.

  • Gibt es dafür nicht was im ROM? Variable suchen muss doch ne Standard-Aufgabe sein.

    fndvar ($b08b), benutzt aber chrget ($0073), um den Variablennamen einzulesen. Dann müsste ich erstmal den Textpointer ($7a/$7b) irgendwo hinsetzen, wo der Variablenname steht? Und nachher wiederherstellen? Klingt auch recht umständlich (und wurschtelig).

    Vielleicht kann man den Namen auch direkt "laden" und dann geschickt in die Routine reinspringen, aber ich weiß nicht genau, wie und wo. :|

    Bitte melde dich an, um diesen Link zu sehen. - Ratespiel • Bitte melde dich an, um diesen Link zu sehen. - BASIC-Erweiterung • Bitte melde dich an, um diesen Link zu sehen. - Sprite-Editor • Bitte melde dich an, um diesen Link zu sehen. - Zeichensatz-Editor Bitte melde dich an, um diesen Link zu sehen. - 2048 Blöcke

  • Da der 6502 keine echten Zeiger hat, wird man um den Umweg mit 0073 nicht rumkommen. Scheint mir aber der einfachste Weg zu sein. Da ist IMO auch noch was mit 0079, oder?

    Aber ein oder zwei Zeiger sichern, dann Routine aufrufen und die zeiger wieder herstellen, klingt jetzt auch nicht SO übertrieben umständlich.Wenn ich mir die Funktion im Intern ansehe, dann wird es wohl eher schwieriger wenn du das selbst machst.

  • Ok, ich habe eine Möglichkeit ohne chrget ($0073) gefunden: Die beiden Zeichen des Namens selber shiften, an $45/$46 ablegen und dann wie ein Irrer mitten in die OS-Routine reinspringen!

    (Das eigentliche Programm sind nur die oberen 5 Zeilen, der Rest dient nur der Kontrolle...)

    So ist es nun "ein bisschen" kürzer als meine Original-Fassung. :whistling:

    Bitte melde dich an, um diesen Link zu sehen. - Ratespiel • Bitte melde dich an, um diesen Link zu sehen. - BASIC-Erweiterung • Bitte melde dich an, um diesen Link zu sehen. - Sprite-Editor • Bitte melde dich an, um diesen Link zu sehen. - Zeichensatz-Editor Bitte melde dich an, um diesen Link zu sehen. - 2048 Blöcke

    3 Mal editiert, zuletzt von goloMAK (14. Februar 2024 um 22:50)

  • Die LOAD-Routine und der IMAIN-Vektor

    In der 64'er (06/84) lese ich, dass LOAD ($FFD5) nach Beendigung den Vektor $0302/$0303 anspringt, der normalerweise zurück zu BASIC führt. Man kann den Vektor aber auch woanders hinbiegen, damit nach LOAD dann automatisch ein selbstdefiniertes Programm aufgerufen wird.

    Das klappt in meinem Test auch. Problem: Ich komme aus diesem selbstgemachten Programm nicht mehr zurück ins BASIC!

    Ich habe mal versucht, das Problem in ein möglichst kurzes Programm zu packen. Das Programm lädt das Directory absolut (es erscheint Gewurschtel am oberen Bildschirmrand, ist aber unwichtig) und soll dann nur noch den Befehl "INC $D020" aufrufen und dann wieder zu BASIC zurückkehren.

    Aber genau diese Rückkehr klappt nicht. Wer hat eine Empfehlung? Was muss man hier noch tun? ?(

    Dateien

    Bitte melde dich an, um diesen Link zu sehen. - Ratespiel • Bitte melde dich an, um diesen Link zu sehen. - BASIC-Erweiterung • Bitte melde dich an, um diesen Link zu sehen. - Sprite-Editor • Bitte melde dich an, um diesen Link zu sehen. - Zeichensatz-Editor Bitte melde dich an, um diesen Link zu sehen. - 2048 Blöcke

    Einmal editiert, zuletzt von goloMAK (5. Mai 2024 um 21:46)

  • Aber genau diese Rückkehr klappt nicht. Wer hat eine Empfehlung? Was muss man hier noch tun? ?(

    Code
    test      inc $d020  ; Dummy
              rts        ; ==> Nirvana

    Du musst den originalen Vector $0302/$0303 retten (irgendwo abspeichern) und danach dorthin springen!

    Also z.B.:

    Code
        lda $0302
        sta vectorsave
        lda $0303
        sta vectorsave+1
    
    und dann
    
    test    inc $d020
        jmp (vectorsave)

    (du musst natürlich irgendwo Platz für vectorsave deklarieren)

    Du kannst es natürlich auch selbst-modifierend schreiben, dann wird das zu:

    Code
        lda $0302
        sta testret+1
        lda $0303
        sta testret+2
    
    und dann
    
    test    inc $d020
    testret    jmp $ffff

    EDIT: Das "ret" bei dir erwartet ja die Adresse zum Fortsetzen auf dem Stack; dort liegt aber keine, weil es gar kein JSR gab. Damit verabschiedet sich der Prozessor im Nirvana (oder in einer anderen Routine, wo es jedenfalls nicht passt) Deshalb musst du den originalen Vektor retten und dorthin springen.

  • Du musst den originalen Vector $0302/$0303 retten (irgendwo abspeichern) und danach dorthin springen!

    Phantastisch! Es löppt! :drink::thnks:

    Hier der entscheidende Teil:

    Bitte melde dich an, um diesen Link zu sehen. - Ratespiel • Bitte melde dich an, um diesen Link zu sehen. - BASIC-Erweiterung • Bitte melde dich an, um diesen Link zu sehen. - Sprite-Editor • Bitte melde dich an, um diesen Link zu sehen. - Zeichensatz-Editor Bitte melde dich an, um diesen Link zu sehen. - 2048 Blöcke