NeoRAM Programmierung

  • NeoRAM Programmierung

    Hi!

    Um den Software-Fred nicht weiter vollzumüllen, bevor wirklich was fertig ist, starte ich mal diesen Fred.

    Stand aktuell: Ich glaube, die Programmierung dank cbmhardware.de grob begriffen zu haben - nach einigen Kämpfen mit VICE2.1 (besser die .IMGs doppelt und dreifach sichern, bevor man sie sich zerschießt...). Habe mittlerweile erfolgreich ein paar VIC-Bänke hin und her kopiert, scheint tatsächlich nicht zu hoch für mich zu sein, das klappte echt gut.

    Was mich jetzt noch interessiert: Wäre ja schon recht elegant, wenn man nicht noch zusätzlich eine Disk braucht, sondern die Software nach dem Bespielen des NeoRAM direkt vom Modul starten kann. Enthusi hat doch bei MMGold geschafft, einen SYS-Start direkt vom Cartridge zu ermöglichen. Wie geht sowas denn?
    an allem schuld (sagt Sauhund, und der ist bekanntlich nicht ohne)

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von TheRyk ()

  • Okay, sowas ähnliches hatte ich schon geahnt, Danke.

    Also Seite/Bank whatever #$00 frei lassen für den eigentlichen Code. Aber hilf mir nochmal auf die Sprünge: Wo genau muss der "Initialcode" dann innerhalb der ersten 16k hin? Vom C64 aus gesehen aus wird der SYS/jmp-Aufruf ja irgendwo zwischen $de00 und $deff liegen müssen, richtig?
    an allem schuld (sagt Sauhund, und der ist bekanntlich nicht ohne)
  • 57000 hatte ich auch genommen. Laesst sich mit SYS5E3 starten, hehe.
    Hier einfach mal der launcher.asm code (damals noch im acme format):
    Ich hab das ein wenig kommentiert - frag sonst nach wenn es Unklarheiten gibt.

    Brainfuck-Quellcode

    1. launch_code
    2. ;this code is the small kicker at de00 that copies the
    3. ;launcher to $c900 and starts it there
    4. bankl = $fb
    5. bankm = $fc
    6. bankh = $fd
    7. ;temp = $fe
    8. temp1 = $a7
    9. temp2 = $a8
    10. temp3 = $a9
    11. temp_c3 = $aa
    12. temp_cmp = $ab
    13. *= $de00
    14. start_of_launcher =*
    15. sei
    16. ldx #(end_of_first_launcher-start_of_launcher)
    17. ;only copy required no of bytes
    18. sol_1
    19. lda $de00,x ;adjust x to actual extern code-start
    20. sol_2
    21. sta $0800
    22. inx
    23. beq sol_end ;FINETUNE
    24. inc sol_2+1
    25. jmp sol_1
    26. sol_end
    27. lda #$00
    28. sta sol_2+1
    29. ;inc $d020
    30. jmp $0800
    31. end_of_first_launcher
    32. length_start = (end_of_first_launcher-start_of_launcher)
    33. ;------------------------------------------
    34. *=$0800
    35. .(
    36. second_launch
    37. lda #$00
    38. sta $dfff
    39. sta $dffe
    40. lda $dece
    41. sta $02
    42. lda $d011
    43. and #%11101111
    44. sta $d011
    45. lda seekp
    46. sta temp
    47. and #%00111111
    48. sta $dffe
    49. lda seekp+1
    50. asl temp
    51. rol
    52. asl temp
    53. rol
    54. sta $dfff
    55. ldx #$00
    56. init_1
    57. lda $de00,x
    58. destination
    59. sta $1000,x ;store menu at $1000
    60. inx
    61. bne init_1 ;load one page
    62. inc destination+2
    63. inc seekp
    64. bne next_byte
    65. inc seekp+1
    66. next_byte
    67. lda destination+2
    68. cmp #$40 ;3800 actually, but be careful FINETUNE
    69. bne second_launch
    70. ;inc $d021
    71. jmp $1000 ; launch drive code (finally)
    72. ;}
    73. second_launch_end
    74. &length_0800 = (second_launch_end-second_launch)
    75. ;-----------------------------------------
    76. sys_start
    77. .dsb ($dea8-$de00-length_0800-length_start),0
    78. jumptable .byt $4c,$00,$de
    79. ;SYS $de00 at $dea8
    80. sys_end
    81. seekp .byte $0c,$06 ;here the menu resides ->check datablock.labels
    82. temp .byte $00
    83. .aasc "enthusi of onslaught "
    84. .aasc " options:|"
    85. options
    86. .byte 0,0
    87. .aasc "|"
    88. &length_sys=(sys_end-sys_start)
    89. .)
    Alles anzeigen


    Das Options ist einfach ein reservierter Bereich in dem ich z.B. die Einstellung ob man das intro vorher sehen will permanent speichere....
    Gruss,
    enthusi
  • Ja, den Trick mit SYS X E Y habe ich Enthusi schon mal für ein paar Dinge geklaut (geht auch schön, um einen vorhandenen Basic-Sys-Start wegzusägen und platzsparend durch Start in VIC-Bank 3 zu ersetzen).

    Danke fürs Sharen, Enthusi, ACME ist genau, was ich brauche, wenn ich feststecke, werde ich wie gewohnt herumnerven. :)
    an allem schuld (sagt Sauhund, und der ist bekanntlich nicht ohne)
  • Launcher auf Speicherbank $0

    Hi!

    Ich bin ziemlich weit fortgeschritten. Mir fehlen eigentlich nur noch Launcher und Loader (um schließlich das NeoRAM mit den 32X64 Blocks von Disk zu beschreiben.) Mit Enhusis Source komme ich über Relaunch/ACME 0.93 syntax-mäßig nicht so ganz klar und blicke auch glaube ich noch nicht 100%ig durch.

    Mein eigener Launcher will immerhin teilweise schon, bleibt aber doofer Weise noch nicht im Speicher. Das folgende (bei dem das Auslesen fehlt) funktioniert mit SYS4096 (Bank 0 beschreiben) und SYS56888 (was nichts weiter macht als Verschieben von $4100 nach $800 sowie anschließendes JMP $80d). Das PRG landet wirklich bei $80d und wird decruncht und gestartet. Soweit so gut.

    Quellcode

    1. !to "neolaunch.prg", cbm
    2. *=$1000; Geowrite schiebt $4000 bis 4fff nach NeoRam-Bank1
    3. geobuf = $de00
    4. geobuf_sect = $dffe
    5. block = $dfff
    6. membuf = $4000 ; - $7fff
    7. sourcemem = $3b;$02
    8. targetmem = $3d;$06
    9. lda #$00; bank ; Register auf Block $00 und $0000
    10. sta geobuf_sect
    11. sta block
    12. ldx #$00
    13. ldy #$00
    14. j0
    15. lda membuf,x ; 256 Byte in die GEORam kopieren
    16. sta geobuf,x
    17. inx
    18. bne j0
    19. iny
    20. sty geobuf_sect
    21. inc j0+2 ; Hi-Byte erhöhen
    22. cpy #$40 ; 64 x 256 = 16 Kb
    23. bne j0
    24. sty j0+2 ; Speicheradresse restaurieren
    25. rts
    26. *= $4038; landet nach Verschieben bei DE38, also SYS 56888
    27. ; nachfolgender Code schiebt 56 Blöcke von 4100ff nach 0800ff
    28. lda #$00
    29. sta targetmem
    30. sta sourcemem
    31. copy0
    32. lda #$08; siehe unten
    33. sta targetmem+1; hibyte
    34. lda #$41; siehe unten
    35. sta sourcemem+1; hibyte
    36. kopieren
    37. ldx #$38; bzw. dez. 56
    38. ldy #$00
    39. kopieren0
    40. lda (sourcemem),y
    41. sta (targetmem),y
    42. iny
    43. bne kopieren0
    44. inc sourcemem+1
    45. inc targetmem+1
    46. dex
    47. bne kopieren0
    48. jmp $080d; Aufruf des PRGs
    49. *= $410d
    50. !bin "C:\C64\xasm\sample\prgexo.prg",,2; exomisiertes PRG ohne SYS-Start, Start bei $80d/SYS2061
    Alles anzeigen

    Es kann aber logischerweise nach einem Hard-Reset nicht mehr funktionieren, weil dafür ein "GeoREAD" fehlt.
    Aber wenn ich den folgenden Code bei $4038 ergänze, kriege ich nach Hard-Reset und SYS56888 immer "JAM at $DE77"

    Quellcode

    1. lda #$00 ; Register auf Block $00 und $0000
    2. sta geobuf_sect
    3. sta block
    4. ldx #$00
    5. ldy #$00
    6. j1 lda geobuf,x
    7. j1a sta membuf,x ; 256 Byte aus GEORam kopieren
    8. inx
    9. bne j1a
    10. iny
    11. sty geobuf_sect
    12. inc j1+2 ; Hi-Byte erhöhen
    13. cpy #$40 ; 64 x 256 = 16 Kb
    14. bne j1a
    15. sty j1+2 ; Speicheradresse restaurieren
    Alles anzeigen

    Warum denn dieses? Wer kann helfen? Danke im Voraus!
    an allem schuld (sagt Sauhund, und der ist bekanntlich nicht ohne)

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von TheRyk ()

  • Loader steht übrigens mittlerweile. Vielleicht nicht sonderlich posh, weil ich die Krill-Sources nur mit zerhackten Zeilenumbrüchen öffnen konnte und deshalb keinen Bock hatte, sie zu studieren, aber meine derzeitige Kombi (paar Zeilen ASM, paar Zeilen Basic, Uralt-Software-Speeder) ist auch funktional und schnell. :) Ich konnte also schonmal auf echter Hardware testen und bin schon sehr zufrieden.

    Wenn mir jetzt noch jemand mit dem Launcher helfen könnte, wäre es perfekt, weil man das Modul autark von jedweder anderen Quelle nutzen könnte. Wenn nicht, nutze ich die letzte Bank einfach noch für andere Sachen, ist notfalls auch okay, wenn auch natürlich nicht 101% comfortable.
    an allem schuld (sagt Sauhund, und der ist bekanntlich nicht ohne)
  • So, ich habe den ganzen Code mal aufgeräumt, vereinfacht und so gut wie möglich kommentiert. Vielleicht wird dann deutlicher, wie das ganze funktioniert. Wenn nicht, einfach fragen. :)
    Alle benötigten Dateien sowie das ausführbare Programm (Launch.prg) befinden sich im Anhang. Das Programm kann nach einem Reset mit SYS 57000 wieder gestartet werden.

    Brainfuck-Quellcode

    1. ; ***********************************************************************************************
    2. ; * *
    3. ; * Launcher-Code für Geo-/NeoRAM (füllt GeoRAM mit Hauptprogramm + Launcher) *
    4. ; * *
    5. ; ***********************************************************************************************
    6. geobuf = $de00 ; 256 Byte-Fenster zum Lesen und Schreiben
    7. geobuf_sect = $dffe ; Auswahl des 256 Byte-Fenster im 16 Kb-Block
    8. block = $dfff ; Auswahl des 16 Kb-Block
    9. ; 512 Kb = 0- 31, $00-$1f
    10. ; 1024 Kb = 0- 63, $00-$3f
    11. ; 2048 Kb = 0-127, $00-$7f
    12. ; *---------------------------------------------------------------------------------------------*
    13. ; * 1.) initiales Befüllen der GeoRAM mit den Daten ab $0900 *
    14. ; *---------------------------------------------------------------------------------------------*
    15. !zone {
    16. * = $0801
    17. !byte $0c,$08,$0a,$00,$9e,$32,$30,$36,$31,$00,$00,$00 ; SYS 2061
    18. .membuf = $0900
    19. ; Kopieren des Bereichs $0900-$48ff in GeoRAM $0000-$3fff (16 Kb)
    20. lda #$00 ; Register auf Block $00 und $0000
    21. sta geobuf_sect
    22. sta block
    23. ldx #$00
    24. ldy #$00
    25. .j0 lda .membuf,x ; 256 Byte in die GEORam kopieren
    26. sta geobuf,x
    27. inx
    28. bne .j0
    29. iny
    30. sty geobuf_sect
    31. inc .j0+2 ; Hi-Byte erhöhen
    32. cpy #$40 ; 64 x 256 = 16 Kb
    33. bne .j0
    34. ldy #>.membuf
    35. sty .j0+2 ; Speicheradresse restaurieren
    36. lda #<.str1
    37. ldy #>.str1
    38. jsr $ab1e ; String ausgeben
    39. rts
    40. .str1 !pet 17,17,"sys 57000",145,145,0
    41. }
    42. ; *---------------------------------------------------------------------------------------------*
    43. ; * 2.) resetfester Launcher ab $de00 (Aufruf mit SYS 57000) *
    44. ; *---------------------------------------------------------------------------------------------*
    45. !zone {
    46. * = $0900
    47. georam_start
    48. ldx #(georead_end - georead)
    49. .l1 lda $de00+georead-$0901,x
    50. sta $c000-1,x
    51. dex
    52. bne .l1
    53. jmp $c000
    54. }
    55. ; *---------------------------------------------------------------------------------------------*
    56. ; * 3.) GeoRAM-Reader (wird vom Launcher nach $c000 kopiert und dort ausgeführt *
    57. ; *---------------------------------------------------------------------------------------------*
    58. georead
    59. !pseudopc $c000 {
    60. !zone {
    61. .membuf = $0800
    62. ; Kopieren des Bereichs $0100-$3fff in den Rechner-Speicher $0800-$47ff (erste Page auslassen)
    63. lda #$01 ; Register auf Block $01 und $0000
    64. sta geobuf_sect
    65. lda #$00
    66. sta block
    67. ldx #$00
    68. ldy #$01 ; mit Page 1 statt 0 beginnen
    69. .j1 lda geobuf,x
    70. .j0 sta .membuf,x ; 256 Byte aus GeoRAM kopieren
    71. inx
    72. bne .j1
    73. iny
    74. sty geobuf_sect
    75. inc .j0+2 ; Hi-Byte erhöhen
    76. cpy #$40 ; 63 x 256 = 16.128 Bytes
    77. bne .j1
    78. ldy #>.membuf
    79. sty .j0+2 ; Speicheradresse restaurieren
    80. jmp $080b ; Hauptprogramm starten
    81. }
    82. }
    83. georead_end
    84. ; *--- Ende des NeoRAM-Readers
    85. * = georam_start + $00A8 ; Einsprungpunkt auf Page 0 = $dea8 = 57000
    86. jmp $de00
    87. ; *---------------------------------------------------------------------------------------------*
    88. ; * 4.) eigentliches Hauptprogramm liegt in der GeoRAM ab Page 1 *
    89. ; *---------------------------------------------------------------------------------------------*
    90. * = georam_start + $0100
    91. !bin "Freeze.prg",,1
    Alles anzeigen

    Viel Spaß beim Ausprobieren. ;)

    CU
    Kratznagel
    Dateien
    • Launch.zip

      (13,63 kB, 22 mal heruntergeladen, zuletzt: )
  • Super, Kratz!

    Vielen Dank! Ein Nach-Vorne-Rücken in den Scroller-Credz ist Dir gewiss. ;)

    Ich werde das morgen studieren und damit rummachen bzw. ggf. nachfragen. Da ich die nächsten 5 Wochen bis zur BCC#5 außer Beta-Testing eh nichts geplant hatte, ist ja auch noch Zeit.
    an allem schuld (sagt Sauhund, und der ist bekanntlich nicht ohne)
  • Noch ein paar Anmerkungen zu dem Beispielcode:
    • Das so in die GeoRAM kopierte Programm ist "resetfest" und kann jederzeit wieder mit einem SYS 57000 gestartet werden. Bei der batteriegepufferten NeoRAM natürlich auch noch nach einem Stromausfall. ;)
    • Das Hauptprogramm (hier "Freeze.prg") wird vom Assembler zunächst an Adresse $0900 untergebracht. Beim initialen Befüllen (Abschnitt 1) wird es dann im Speicher der GeoRAM ab $000100 abgelegt (die ersten 256 Bytes von $000000 bis $0000ff beinhalten ja den Laucher-Code).
    • Der Launcher selbst (Abschnitt 2) wird dann über SYS 57000 gestartet. Dieser kopiert dann den GeoRAM-Reader nach $c000 und führt ihn dort aus.
    • Der GeoRAM-Reader (Abschnitt 3) letztendlich kopiert den Inhalt der GeoRAM ab Byte $000100 an ihren eigentlichen Bestimmungsort $0800 im C64-RAM. Durch den "jmp $080b" wird das Programm nach dem Kopieren dann ausgeführt.
    • Das "Restaurieren" der Speicheradresse an zwei Stellen ist hier nicht unbedingt notwendig, da beide Routinen eh nur ein einziges Mal aufgerufen werden, wurde aber der Ordnung halber so belassen. Selbstmodifiziernder Code ist eine beliebte Fehlerquelle.

    Folgendes ist zu beachten, wenn man das beispielhafte Hauptprogramm "Freeze.prg" durch ein anderes ersetzen will:
    • Ladeadresse: "Freeze.prg" muss für die Ausführung nach $0801 geladen werden. Da der GeoRAM-Reader die Daten bündig nach $0800 kopiert, wurde beim Assemblieren lediglich das erste Byte des PRG-Headers übersprungen (mit ",,1"). Somit landet am Ende das zweite Byte des PRG-Headers als Füllbyte an $0800 und das eigentliche Programm an $0801, da wo es hingehört. Quick&Dirty, aber funktioniert. ;)
    • Startadresse: Bei "Freeze.prg" ist die Startadresse $080b (siehe den JMP am Ende des GeoRAM-Readers). Muss für ein anderes Programm evtl. angepasst werden.
    • Es werden von diesem Code immer genau 16.128 Bytes kopiert (16 kb minus die 256 Byte für den Launcher). Lässt sich aber im Bedarfsfall leicht ändern.


    Natürlich lässt sich an diesem Code noch eine ganze Menge optimieren. Aber dieses Beispiel soll ja auch einfach nur das Grundprinzip verdeutlichen, wie Programmdaten in die GeoRAM hinein- und für die Ausführung wieder aus ihr herausgeschaufelt werden können. Optimieren kannst Du dann selber immer noch. :)

    CU
    Kratznagel

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Kratznagel ()

  • Supergeil, funktioniert 1-a - und zwar dank der Erklärungen auf Anhieb, idiotensicher quasi ;) !

    Tausen Dank!
    an allem schuld (sagt Sauhund, und der ist bekanntlich nicht ohne)

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von TheRyk ()

  • Ich geb mir ja schon wirklich Mühe, möglichst viel selbst auf die Reihe zu kriegen. :)

    War auch schon kurz davor, Dich mit PMs zu terrorisieren. Schätze, Du hättest mir das genauso erklären und servieren können wie Kratz, der einfach schneller war. Trotzdem vielen Dank!

    N8
    Ryk
    an allem schuld (sagt Sauhund, und der ist bekanntlich nicht ohne)