Fragen zu Displaylist in Assembler etc.
von Jan1980 » Do 20. Feb 2020, 23:28Hallo.
Ich beschäftige mich seit ca einem Jahr generell mit Assembler. Ich habe mich mit dem C64 beschäftigt, da es mir für den Anfang einfacher schien, weil ich mit dem Gerät aufgewachsen bin und die Hardware gut kenne. Außerdem hab ich für meinen Imsai 8080 ein Floppy-Bios mit Monitor-Programm und einigen Transfer-Tools programmiert. Also ich behaupte jetzt einfach mal, es sind zumindest Grundkenntnisse in MOS6502 und Intel8080 Assembler vorhanden.
Da ich großer Atari Fan bin, will ich jetzt versuchen, das erlernte an meinem Atari 800XL bzw. über WUDSN für meinen Atari 800XL um zu setzen. Es ist eine neue Herausforderung und ich freue mich darauf !
Was mir natürlich direkt positiv aufgefallen ist, ist die Displaylist und wie leicht man damit zB eine Textlinie zum (fine)-scrollen kriegt. Dafür musste ich beim Cevi so einiges mehr tippen..
Jetzt stehe ich hier vor einem Berg von neuen bzw. anderen Adressen, vor jede Menge Grafik Modes, vor einem
frei definierbarem Screen-RAM, was für mich neu ist. Und natürlich habe ich einige Fragen.
1. Schattenregister vs. Hardwareregister. Wie ist die Refresh Rate von den Schattenregistern ? Wenn ich zB an das hw-Register $2c8 eine andere Bordercolor schreibe, bleibt diese erhalten. Wenn ich an das dementsprechende Schattenregister den Farbwert schreibe, ändert sich die Farbe nur ganz kurz. Ist der Refresh bei jedem Bildaufbau ? Also während jedem vertical blank ?
2. Die Adresse des Screen-Memory steht ja an den Zeropage Adressen $58 und $59. Wenn ich indirekt adressiere, kann ich mein "Hello World !!!" auch auf dem Bildschirm ausgeben.
Aber wenn ich die Screenadresse ändere, geht es nicht. Ich hatte mir das so vorgestellt:
Im Debugger steht dann die Adresse $3000 an $58 und $59, aber die Bildschirmausgabe funktioniert nicht. Was mache ich falsch ?
3. Player/Missiles. Gibt es die Möglichkeit PMs zu spiegeln ? Also wenn zB das Auto den linken Bildschirmrand erreicht, spiegele ich das Sprite und die Motorhaube steht plötzlich nach rechts.
4. Wenn ich einen Startscreen mit der Displaylist erstelle, wie kann ich die Displaylist anschließend wieder leeren ? Also ich hatte eine Routine geschrieben, die nach drücken des Feuerknopfes in das nächste Bild springen soll, aber ich kriege das Bild einfach nicht mehr weg. Gibts irgendeine Adresse, die die DL resettet. Ich hatte auch nach der Joystickabfrage ein Unterprogramm geschrieben, das eine andere Adresse bzw. im Assembler ein anderes Label in die Vectoradressen $230 und $231 schreibt. Dann geht zwar das alte Bild weg, aber ich kann die neue Displaylist nicht aufbauen. Es kommen nur 3 blaue Balken oben. Egal, was ich in die neue Displaylist reinschreibe.
5. Bei C64 hab ich den Bildschirm über Rasterzeileninterrupts gesplittet. zB oben die Punkte, in der Mitte das Spiel oder was auch immer und unten noch ein Lauftext. Kann ich das beim Atari rein über die Displaylist relaisieren ?
6. Das mit dem Scrolling via Displaylist ist mir nicht aus dem Kopf gegangen. Ich habe ein kleines Programm geschrieben, wo man mit dem Joystick über mehrere Bildschirme scrollen kann. Oben die Punkte-Anzeige soll stehen bleiben, in der Mitte die 21 Zeilen sollen scrollen und unten die Sterne stehen bleiben.
a) Wie beende ich die definitionbytes unten ? Der Text der Scrolltextes vermischt sich mit den Sternen. Wie krieg ich es hin, dass er nur das nimmt, was in dem dementsprechenden .db Fenster steht. Beim Intel Assembler hatte ich da eine Byte festgelegt, das den Ende des Blocks festlegt. Somit wusste die Konsole, dass sie zurückspringen soll. Wie mach ich das im WUDSN ?
b) Wie bringe ich das Scrolling zum stoppen, wenn ich am linken bzw. rechten Rand bin ?
c) Wie krieg ich das Ding langsamer ? Ich hab schon einen Zähler über $14 eingebaut und eine verschachtelte Schleife hatte ich auch probiert.
d) Schaut euch mal meine Unterroutinen für rechts und links an. Da verschiebe ich jede Zeile einzeln. Gibt es da eine elegantere Lösung ?
Und zu guter Letzt. Bin ich mit meinem Bildschirmscrolling via Displaylist überhaupt auf dem richtigen Weg ? Oder doch besser das Screen-RAM verschieben ? Da hätte ich dann aber das Problem, wenn ich eins abziehe, rückt das Zeichen aus der zweiten Reihe nach und nicht das erste aus Zeile 1 von Seite 2....
Vielen Dank !
Gruß Jan
Ich beschäftige mich seit ca einem Jahr generell mit Assembler. Ich habe mich mit dem C64 beschäftigt, da es mir für den Anfang einfacher schien, weil ich mit dem Gerät aufgewachsen bin und die Hardware gut kenne. Außerdem hab ich für meinen Imsai 8080 ein Floppy-Bios mit Monitor-Programm und einigen Transfer-Tools programmiert. Also ich behaupte jetzt einfach mal, es sind zumindest Grundkenntnisse in MOS6502 und Intel8080 Assembler vorhanden.
Da ich großer Atari Fan bin, will ich jetzt versuchen, das erlernte an meinem Atari 800XL bzw. über WUDSN für meinen Atari 800XL um zu setzen. Es ist eine neue Herausforderung und ich freue mich darauf !
Was mir natürlich direkt positiv aufgefallen ist, ist die Displaylist und wie leicht man damit zB eine Textlinie zum (fine)-scrollen kriegt. Dafür musste ich beim Cevi so einiges mehr tippen..
Jetzt stehe ich hier vor einem Berg von neuen bzw. anderen Adressen, vor jede Menge Grafik Modes, vor einem
frei definierbarem Screen-RAM, was für mich neu ist. Und natürlich habe ich einige Fragen.
1. Schattenregister vs. Hardwareregister. Wie ist die Refresh Rate von den Schattenregistern ? Wenn ich zB an das hw-Register $2c8 eine andere Bordercolor schreibe, bleibt diese erhalten. Wenn ich an das dementsprechende Schattenregister den Farbwert schreibe, ändert sich die Farbe nur ganz kurz. Ist der Refresh bei jedem Bildaufbau ? Also während jedem vertical blank ?
2. Die Adresse des Screen-Memory steht ja an den Zeropage Adressen $58 und $59. Wenn ich indirekt adressiere, kann ich mein "Hello World !!!" auch auf dem Bildschirm ausgeben.
- Code: Alles auswählen
org $2000
;
.proc main
lda #0
tay
tax
;
loop
lda text,y
sta ($58),y
iny
bne loop
jmp *
.end main
;
;
text
.byte "Hello World !!!"
;
run main
Aber wenn ich die Screenadresse ändere, geht es nicht. Ich hatte mir das so vorgestellt:
- Code: Alles auswählen
screenadr=$3000
;
org $2000
;
.proc main
lda #0
tay
tax
;
lda #<screenadr
sta $58
lda #>screenadr
sta $59
;
;
loop
lda text,y
sta $3000,y
iny
bne loop
jmp *
.end main
;
;
text
.byte "Hello World !!!"
;
run main
Im Debugger steht dann die Adresse $3000 an $58 und $59, aber die Bildschirmausgabe funktioniert nicht. Was mache ich falsch ?
3. Player/Missiles. Gibt es die Möglichkeit PMs zu spiegeln ? Also wenn zB das Auto den linken Bildschirmrand erreicht, spiegele ich das Sprite und die Motorhaube steht plötzlich nach rechts.
4. Wenn ich einen Startscreen mit der Displaylist erstelle, wie kann ich die Displaylist anschließend wieder leeren ? Also ich hatte eine Routine geschrieben, die nach drücken des Feuerknopfes in das nächste Bild springen soll, aber ich kriege das Bild einfach nicht mehr weg. Gibts irgendeine Adresse, die die DL resettet. Ich hatte auch nach der Joystickabfrage ein Unterprogramm geschrieben, das eine andere Adresse bzw. im Assembler ein anderes Label in die Vectoradressen $230 und $231 schreibt. Dann geht zwar das alte Bild weg, aber ich kann die neue Displaylist nicht aufbauen. Es kommen nur 3 blaue Balken oben. Egal, was ich in die neue Displaylist reinschreibe.
5. Bei C64 hab ich den Bildschirm über Rasterzeileninterrupts gesplittet. zB oben die Punkte, in der Mitte das Spiel oder was auch immer und unten noch ein Lauftext. Kann ich das beim Atari rein über die Displaylist relaisieren ?
6. Das mit dem Scrolling via Displaylist ist mir nicht aus dem Kopf gegangen. Ich habe ein kleines Programm geschrieben, wo man mit dem Joystick über mehrere Bildschirme scrollen kann. Oben die Punkte-Anzeige soll stehen bleiben, in der Mitte die 21 Zeilen sollen scrollen und unten die Sterne stehen bleiben.
a) Wie beende ich die definitionbytes unten ? Der Text der Scrolltextes vermischt sich mit den Sternen. Wie krieg ich es hin, dass er nur das nimmt, was in dem dementsprechenden .db Fenster steht. Beim Intel Assembler hatte ich da eine Byte festgelegt, das den Ende des Blocks festlegt. Somit wusste die Konsole, dass sie zurückspringen soll. Wie mach ich das im WUDSN ?
b) Wie bringe ich das Scrolling zum stoppen, wenn ich am linken bzw. rechten Rand bin ?
c) Wie krieg ich das Ding langsamer ? Ich hab schon einen Zähler über $14 eingebaut und eine verschachtelte Schleife hatte ich auch probiert.
d) Schaut euch mal meine Unterroutinen für rechts und links an. Da verschiebe ich jede Zeile einzeln. Gibt es da eine elegantere Lösung ?
- Code: Alles auswählen
org $2000
;
.proc main
lda #<dlist
sta $230
lda #>dlist
sta $231
start
loop lda $278
tax
and #$04
bne notleft
jsr left
notleft txa
and #$08
bne loop
jsr right
jmp start
.end main
run main
.local dlist
.byte $70,$70,$70
lms .byte $52,a(points)
.byte $70
lms3 .byte $52,a(text)
lms4 .byte $52,a(text)
lms5 .byte $52,a(text)
lms6 .byte $52,a(text)
lms7 .byte $52,a(text)
lms8 .byte $52,a(text)
lms9 .byte $52,a(text)
lmsa .byte $52,a(text)
lmsb .byte $52,a(text)
lmsc .byte $52,a(text)
lmsd .byte $52,a(text)
lmse .byte $52,a(text)
lmsf .byte $52,a(text)
lms10 .byte $52,a(text)
lms11 .byte $52,a(text)
lms12 .byte $52,a(text)
lms13 .byte $52,a(text)
lms14 .byte $52,a(text)
lms15 .byte $52,a(text)
lms16 .byte $52,a(text)
lms17 .byte $52,a(boden)
lms18 .byte $52,a(boden)
.byte $41,a(dlist)
.endl
.local left
;dec dlist.lms+1
;dec dlist.lms2+1
dec dlist.lms3+1
dec dlist.lms4+1
dec dlist.lms5+1
dec dlist.lms6+1
dec dlist.lms7+1
dec dlist.lms8+1
dec dlist.lms9+1
dec dlist.lmsa+1
dec dlist.lmsb+1
dec dlist.lmsc+1
dec dlist.lmsd+1
dec dlist.lmse+1
dec dlist.lmsf+1
dec dlist.lms10+1
dec dlist.lms11+1
dec dlist.lms12+1
dec dlist.lms13+1
dec dlist.lms14+1
dec dlist.lms15+1
dec dlist.lms16+1
;dec dlist.lms17+1
;dec dlist.lms18+1
jsr delay
rts
.endl
.local right
;inc dlist.lms+1
;inc dlist.lms2+1
inc dlist.lms3+1
inc dlist.lms4+1
inc dlist.lms5+1
inc dlist.lms6+1
inc dlist.lms7+1
inc dlist.lms8+1
inc dlist.lms9+1
inc dlist.lmsa+1
inc dlist.lmsb+1
inc dlist.lmsc+1
inc dlist.lmsd+1
inc dlist.lmse+1
inc dlist.lmsf+1
inc dlist.lms10+1
inc dlist.lms11+1
inc dlist.lms12+1
inc dlist.lms13+1
inc dlist.lms14+1
inc dlist.lms15+1
inc dlist.lms16+1
;inc dlist.lms17+1
;inc dlist.lms18+1
jsr delay
rts
.endl
.local delay
dloop lda $14
and #$07
bne dloop
rts
.endl
.align 120
.local text
.byte " Hallo das is ein Text, der laenger als der Bildschirm sein soll, ich will den Bildschirm scrollen,..............." ; 120 Zeichen = 3 Bildschirme
.endl
.align 120
.local boden
.byte "*********************************************************************************************************************"
.endl
;org $3300
.align 13
.local points
.byte " Punkte: "
.endl
Und zu guter Letzt. Bin ich mit meinem Bildschirmscrolling via Displaylist überhaupt auf dem richtigen Weg ? Oder doch besser das Screen-RAM verschieben ? Da hätte ich dann aber das Problem, wenn ich eins abziehe, rückt das Zeichen aus der zweiten Reihe nach und nicht das erste aus Zeile 1 von Seite 2....
Vielen Dank !
Gruß Jan