Hello, Guest the thread was viewed1.3k times and contains 14 replies

last post from BernhardAusdemWald at the

RAM unter BASIC ROM nutzen für BASIC?

  • Mir kam die irre Idee in das RAM unter dem BASIC ROM Grafikdaten abzulegen und die mit Assembler Code zu holen von BASIC aus.


    Das klappt auch fast...

    Dazu SYS in den Assembler Teil, BASIC off in $01, kopieren, BASIC an, rts


    In Assembler kann man problemlos unter das BASIC ROM laden, ohne überhaupt was zu tun. Der Proz. sieht da ja nur RAM. Lesen geht dann nicht, ist klar, dazu ROM aus.

    Das klappt auch prima, auch das ein/ausschalten.


    Aber nachdem einmal der code unten aufgerufen wurde, hängt die Kiste bei Aufruf einer Kernal Routine (z.B. LOAD in $FFD5) oder rts ins Basic.

    Jemand eine Idee? In Docs habe ich dazu wenig gefunden, entweder ist es so völlig einfach oder totaler Unfug dass ich dazu kaum was finde...


    Code hier:


    ;BASIC OFF

    seilda #$36

    sta $0001


    ; send test data to screen

    ldx #$00

    copy1

    lda $A000,x

    sta $0478,x

    inx

    cpx #$33

    bne copy1


    ; BASIC ONlda #$37

    sta $0001

    cli

  • Grafikdaten kannst Du eigentlich auch unter den ROMs lassen, der VIC sieht ja nur das RAM (und ggf. das Charrom), egal wie $01 konfiguriert ist.


    Das im anderen Thread schon erwähnte Crank the PRINT kann PRINT-Strings unter die ROMs verlagern, ganz ohne dass man das BASIC-Programm verandern muss.


    Was Dein Crash-Problem angeht, schau doch einfach im Emulator nach, was genau passiert. VICE hat da den netten Befehl "cpuhist", mit dem man sich u.a. bei einem Crash die zuletzt ausgeführten Befehle ansehen kann, womit man dann (häufig) sehen kann, wie/warum der Crash passiert ist.

  • Ich gehe mal davon aus, das am Ende noch ein RTS in der Routine steht.


    Aber nachdem einmal der code unten aufgerufen wurde, hängt die Kiste bei Aufruf einer Kernal Routine (z.B. LOAD in $FFD5) oder rts ins Basic.

    Jemand eine Idee? In Docs habe ich dazu wenig gefunden, entweder ist es so völlig einfach oder totaler Unfug dass ich dazu kaum was finde...

    An der Routine selber kann es nicht liegen, vielleicht wird die Routine vom Basic-Programm überschrieben.


    Musst Du nicht noch den Interrupt abschalten?

    Hat er doch und den könnte man sogar an lassen.


  • Ja, das ist ein Teil des startprogramms, zum rts kommt es gar nicht mehr. Ein call in LOAD zB kommt nicht dahin, eine Ausgabe auf den Screen wird nicht mehr ausgeführt.


    Der code steht ab $C000 im Speicher, nicht im BASIC Teil. AB $A000 liegen nur Daten die kopiert werden sollen.


    ich spring an dem Punkt nicht mal zurück ins BASIC, gleich der nächste Kernal call in Assembler macht das System dicht.

    Ich blicks nicht. Hatte schon überlegt ob irgendwas an den Werten für $1 noch anders sein muss, ggf. PLA auf Ausgang oder so etwas. Ich finde aber dazu kaum was außer den Hinweis:


    "To use these control lines, they must be configured as outputs, i.e. the same three least significant bits in the port's directional data register (at address 0) must be set to 1. This is the default upon power-up, but a programmer may want to make certain of this before bank switching."

    (aus dem wiki)


    Das sagt mir ehrlicherweise nix, in allen demos die ich gefunden habe wird nichts zusätzlich gemacht.

  • Ein call in LOAD z.B. kommt gar nicht erst dahin, eine Ausgabe auf den Screen wird nicht mehr ausgeführt.

    Dann liegt das Problem also gar in der Routine im Startbeitrag.


    Standardvorgehen ist hier, im Ablauf erkennbare Zwischenschritte (z.B. durch Umfärben des Rahmens) klar zu kennzeichen, damit man sieht, wie weit das Programm (vor einem evtl. Absturz) überhaupt kommt.

    Das sagt mir ehrlicherweise nix, alle in allen demos wird nichts mehr zusätzlich gemacht.

    Die Signalpins am Prozessor, die durch Adresse $01 angesprochen werden, können eben nicht nur Ausgänge sondern auch Eingänge sein; das wird durch Adresse $00 vorgegeben.


    Damit die Ansteuerung durch Adresse $01 so funktioniert wie normalerweise erwartet, müssen die unteren drei Bits in $00 auf 1 gesetzt sein. Tatsächlich sind sie das nach dem Einschalten zunächst nicht, drei Widerstände auf der Hauptplatine sorgen dann trotzdem dafür, daß auf den Leitungen /LORAM, /HIRAM und /CHAREN definierte Werte sind (High-Pegel), so daß die PLA das BASIC- und KERNAL-ROM sowie den I/O-Bereich einblendet. Eine der ersten Aktionen im KERNAL ist dann, $00 auf den Wert $27 zu stellen, was u.a. eben die unteren drei Bits wie zuvor beschrieben setzt.

  • Das bestätigt meine Tests, an Routine selber liegt es nicht. Folgende Fehler wären daher möglich, die Routine liegt an einer anderen Adresse und der Aufruf endet in einen Absturz. Die Basic-Pointer stimmen nicht mehr und deshalb stützt das Basic-Programm ab, weil diese jetzt im ROM liegen.

  • Die Signalpins am Prozessor, die durch Adresse $01 angesprochen werden, können eben nicht nur Ausgänge sondern auch Eingänge sein; das wird durch Adresse $00 vorgegeben.


    Damit die Ansteuerung durch Adresse $01 so funktioniert wie normalerweise erwartet, müssen die unteren drei Bits in $00 auf 1 gesetzt sein. Tatsächlich sind sie das nach dem Einschalten zunächst nicht, drei Widerstände auf der Hauptplatine sorgen dann trotzdem dafür, daß auf den Leitungen /LORAM, /HIRAM und /CHAREN definierte Werte sind (High-Pegel), so daß die PLA das BASIC- und KERNAL-ROM sowie den I/O-Bereich einblendet. Eine der ersten Aktionen im KERNAL ist dann, $00 auf den Wert $27 zu stellen, was u.a. eben die unteren drei Bits wie zuvor beschrieben setzt.

    Das scheint ein Puzzle Teil zu sein, zumindest bei mir. Ich setze die jetzt und es läuft glaube ich, allerdings erst in Zusammenhang mit einem anderen Effekt, den ich noch nicht greifen kann.


    Wie oben von Acorn vermutet scheint aber z.B. Kernel LOAD oder irgendwas anderes noch in den Bereich zu schreiben, zumindest vermute ich das. Ich habe den Code woandershin kopiert. Aber mache ich das ohne auf $0 schreiben läift es auch nicht.


    Aber eins von beiden reicht nicht, nur in Kombination läuft es.

  • Ich bin etwas verwundert oder auch erstaunt, weil man die Adresse $00 in der Regel nie ändert muss. Nach dem Einschalten des C64 hat der Kernal beide Port-Register vom 6510 sinnvoll gesetzt. In Adresse $00 steht $2F und in Adresse $01 steht $37 und es gibt selten einen Grund $00 zu ändern. Daher eine Frage, das Programm wird ganz normal von Disk/Tape geladen und gestartet.

  • Guter Tipp, Danke!! Auch an alle anderen.


    Stand jetzt, ja ich glaube auch dass irgend wo noch ein code bug sein müsste. Nur das Programm, zumindest der Assembler Teil, ist nicht groß. (Das wars schon fast)

    Ich habe den Screen von $0400 auf $C800 gelegt. In $0400 lief der code.

    Ich habe die Vermutung, dass dort irgendwas noch reinschreibt danach. Sobald der Code auf $C000+ gemoved wurde ging es.


    Das mit der Zeropage würde auch erklären warum das BASIC danach wegschüsselt.

  • Ich bin etwas verwundert oder auch erstaunt, weil man die Adresse $00 in der Regel nie ändert muss. Nach dem Einschalten des C64 hat der Kernal beide Port-Register vom 6510 sinnvoll gesetzt. In Adresse $00 steht $2F und in Adresse $01 steht $37 und es gibt selten einen Grund $00 zu ändern. Daher eine Frage, das Programm wird ganz normal von Disk/Tape geladen und gestartet.

    Yep, erst mit LOAD"*",8 den BASIC TEIL, dann mit LOAD"name",8,1 aus BASIC den Assembler Teil, dann darin die anderen Teile mit Kernal LOAD aus Assembler.


    Es gab in einigen Artikeln den Hinweis, die vor Bank switching auf Ausgang zu schreiben und auch den Hinweis dass dies der Einschaltzustand ist (Was es eigentlich überflüssig machen sollte).