Ich bin auf der Suche nach einer Möglichkeit, einen Interrupt zu programmieren, steige aber bei der Firmware nicht durch. :(
Wie stellt man es da, das eine Aktion einmal oder öfter pro Sekunde gestartet wird?
Hier hilft z.B. das Schneider CPC Systembuch: http://k1.spdns.de/Vintage/Schneider%20CPC/Das%20Schneider%20CPC%20Systembuch/z138.htm (http://k1.spdns.de/Vintage/Schneider%20CPC/Das%20Schneider%20CPC%20Systembuch/z138.htm)
Ansonsten gab es auch im Schneider Magazin bzw. Computer Partner eine gute Serie dazu, müsste ich mal raussuchen.
Viel Erfolg,
AMSi
Du könntest natürlich auch einfach den Interrupt an Adresse &0038 abfangen und in dein Programm umleiten. In dem Fall gibt es sechs Interrupts pro Bild (also pro 1/50 Sekunde). Und jedes 6te mal kannst Du testen ob der Elektronenstrahl zurück läuft, um den Bildaufbau zu synchronisieren.
Das funktioniert aber nur solange du das untere RAM eingeblendet hast, dann im ROM würde ja noch die alte Interrupt Routine stehen.
Ich hatte eigentlich auf einen kleinen Codeschnipsel gehofft. So muß ich ja doch wieder selber denken. Ich weiß nur das ich vor 30 Jahren mal was versucht hatte und das ging nach hinten los. :(
'n Abend!
Oh, Z80, geht es überhaupt um den CPC?
Was soll die aufzurufende Routine tun? Von asynchronen Events aus lassen sich die wenigsten Firmwareroutinen nutzen. Muss sie synchron zum Strahlrücklauf aufgerufen werden?
Gute Nacht,
AlMaSys
Ööööhh... :gruebel:
Da soll einfach nur was regelmäßig aufgerufen werden. Strahlrücklauf ist nicht so wichtig, nur die Regelmäßgkeit vom Aufruf würde ich gerne steuern können. 1x pro Sekunde oder 5x oder nur alle 2 Sekunden. Irgendwie sowas.
Mein erster Interrupt. :00008351: :00008351: :00008351: :00008351: :00008351:
Gibt (fast) im Sekundentakt den Buchstaben A aus. Heute mal voll stolz auf mich bin. :jubelaola:
org &4000
InterruptInit:
LD HL,BlocEvent
LD DE,InterruptHandle
LD BC,#8100
call #BCD7
ret
InterruptDone:
LD HL,BlocEvent
call #BCDD
ret
InterruptHandle:
DI
ld a,(counter)
dec a
ld (counter),a
cp 0
jr nz,nixmachen
;; was soll ich hier machen?
ld a,65
call &bb5a
ld a,50
ld (counter),a
.nixmachen
ei
ret
BlocEvent:
DS 16
.counter
defb 50
Wenn ich keine Fehler beim Abtippen gemacht habe, hier das erste Listing aus https://cpcwiki.de/forum/index.php/topic,282.msg2022.html#msg2022 (https://cpcwiki.de/forum/index.php/topic,282.msg2022.html#msg2022)
org &a000
ld hl,free4
ld bc,tab1
call &bcd1
ret
.free4
defs 4
.tab1
defw ntab
jp init2
jp aus
.ntab
defb "O","N"+&80
defb "O","F","F"+&80
defb 0
.init2
ld a,0
call &bd1c
call &bd19
ld hl,block
call &bce3
di
ld a,6
ld (auf),a
call &bd19
ei
ret
.aus
ld hl,block
call &bce6
ld a,2
call &bd1c
ret
.block
defw 0
defw 0
defb 0
defb &81
defw routi
defb 0
defw 0
.routi
ld a,(auf)
dec a
ld (auf),a
cp 0
jr z,mod0
cp 2
ret nz
ld a,2
jp &bd1c
.mod0
ld a,6
ld (auf),a
ld a,0
jp &bd1c
.auf
defb 6
Wer keinen Assembler zur Hand hat:
10 AD=&A000:L=&006A
20 READ a:POKE AD+P,a
30 P=P+1:IF P=L THEN CALL &A000:END
40 GOTO 20
50 DATA &21,&0A,&A0,&01,&0E,&A0,&CD,&D1,&BC,&C9,&00,&00,&00,&00,&16,&A0
60 DATA &C3,&1C,&A0,&C3,&35,&A0,&4F,&CE,&4F,&46,&C6,&00,&3E,&00,&CD,&1C
70 DATA &BD,&CD,&19,&BD,&21,&41,&A0,&CD,&E3,&BC,&F3,&3E,&06,&32,&69,&A0
80 DATA &CD,&19,&BD,&FB,&C9,&21,&41,&A0,&CD,&E6,&BC,&3E,&02,&CD,&1C,&BD
90 DATA &C9,&00,&00,&00,&00,&00,&81,&4C,&A0,&00,&00,&00,&3A,&69,&A0,&3D
100 DATA &32,&69,&A0,&FE,&00,&28,&08,&FE,&02,&C0,&3E,&02,&C3,&1C,&BD,&3E
110 DATA &06,&32,&69,&A0,&3E,&00,&C3,&1C,&BD,&06
Das bekomm ich aber net mit Copy/Paste in den CPC rein. :zunge0020:
Hab mal bissl am Code gefummelt...
So ist er etwas Übersichtlicher:
org &a000
uppermode equ 0
lowermode equ 1
resetmode equ 1
ld hl,free4
ld bc,tab1
call &bcd1
ret
.free4
defs 4
.tab1
defw ntab
jp init2
jp aus
.ntab
defb "O","N"+&80
defb "O","F","F"+&80
defb 0
.init2
ld a,0
call &bd1c
call &bd19
ld hl,block
call &bce3
di
ld a,6
ld (auf),a
call &bd19
ei
ret
.aus
ld hl,block
call &bce6
ld a,resetmode
call &bd1c
ret
.block
defw 0
defw 0
defb 0
defb &81
defw routi
defb 0
defw 0
.routi
ld a,(auf)
dec a
ld (auf),a
cp 0
jr z,mod0
cp 2
ret nz
ld a,lowermode
jp &bd1c
.mod0
ld a,6
ld (auf),a
ld a,uppermode
jp &bd1c
.auf
defb 6
Was mich ja mal interessieren würde:
Bekommt man den Mode-Split um genau 1 Pixelzeile nach Oben verschoben?
Quote from: Devilmarkus on 21. February 2015, 20:25:15
Bekommt man den Mode-Split um genau 1 Pixelzeile nach Oben verschoben?
Was mich interessieren würde ist, kann man überhaupt am CPC auf die gewünschte Rasterzeile warten?
Ja mit viel Mathematik (nicht so schlimm, Du musst das ja nur einmal berechnen) und das HALT Kommando.
HALT wartet bis ein Interrupt auftritt, es geht also noch dem HALT Kommando im Code dann weiter, wenn sich der Elektronenstrahl auf einer von sechst ganz definierten Stellen befindet.
Um abzufragen ob der Elektronenstrahl gerade zurück läuft kann man folgendes benutzten:
02006 ;Auf FRAME warten
02007 ;
02008 ;Manip. AF, B
02009
02010 93B9 06 F5 FRA LD B,&F5
02011 93BB JSZ
02011 93BB ED 78 IN A,(C)
02011 93BD 0F RRCA
02011 93BE 30 FB JR NC,JSZ ;V-Sync abwarten
02012
02013 93C0 C9 RET
Sehe ich das richtig, das zwischen einem DI&EI ein HALT ewig warten würde?
Mir ist aber immer noch nicht klar, wie ein Rasterzeileninterrupt auf dem CPC funktioniert.
Hab eh noch meine Schwierigkeiten, das mit einem Interrupt richtig hin zu bekommen (siehe Lustige Bugs in FruttyMan).
Obwohl ich bei den Bildschirmausgaben DI/EI verwende, habe ich dort merkwürdige grafische Effekte. :(
Kann es sein, dass du Speicher aus dem ROM einblendest? Im Screen-RAM?
Quote from: Devilmarkus on 25. February 2015, 11:51:23
Kann es sein, dass du Speicher aus dem ROM einblendest? Im Screen-RAM?
Nein. Ich mache doch nur normales PRINT in Assembler.
org &4000
ld hl,text
call printtext
ret
.PrintText
ld a,(hl)
or a
ret z
call &bb5a
inc hl
jr PrintText
.text
defb 22,1,15,1,129,8,15,3,130,0
Keine Ahnung war mein Frutty gleich zweimal auftaucht. :motz:
Das macht irgendwie keinen Sinn. Der darf nur auf der Leiter sein! :motz:
Habs gefunden, was ich Dir im Chat schrieb:
Register sichern:
DI
PUSH AF
PUSH BC
PUSH DE
PUSH HL
PUSH IX
PUSH IY
EX AF,AF'
PUSH AF
EX AF,AF'
Hier nun Deine Routine zum Gegner bewegen usw...
Dann:
Zurückholen:
ex af,af'
pop af
ex af,af'
pop iy
pop ix
pop hl
pop de
pop bc
pop af
ei
Wenn ich das beim Frutty-Zeichnen reinsetze, dann bleibt das Problem. Nehm ich das auch zusätzlich beim Monster mit rein, dann stürzt das Spiel ab. Interessant. :gruebel:
AF' und BC' müssen immer erhalten bleiben. Vielleicht liegt's daran.
Quote from: TFM on 25. February 2015, 17:54:14
AF' und BC' müssen immer erhalten bleiben. Vielleicht liegt's daran.
AF' und BC' hab ich ja nie benutzt.
War nur so eine Idee.
Ich mache die Ausgabe ja komplett über Steuerzeichen als String, d.h. die Figur wird in einem Rutsch ausgegeben. Wenn dann dabei ein Grafikfehler auftritt, dann muß die Routine &BB5A irgendwo die Interrupts freigeben, so das mein Interrupt dazwischen fummeln kann.
Das ist richtig &BB5A gibt die Interrupts frei. Kannst Du beides nicht "trennen"?
Quote from: TFM on 25. February 2015, 19:37:11
Das ist richtig &BB5A gibt die Interrupts frei. Kannst Du beides nicht "trennen"?
Nee, da muß ich entweder das BB5A ohne Unterbrechung nachprogrammieren oder die Bildausgabe komplett selber schreiben, wobei ich dann nicht weiß wie ich den Farbwechsel in einem Sprite hinbekommen soll. :(
Ich gerade im Intern am suchen bei BB5A, kann da aber keine Interruptunterbrechung sehen. Was ich noch im Verdacht habe ist die Soundausgabe. Die werde ich gleich mal wechschalten und mir dann das Ergebniss anschauen.
Wenn Du mir das nicht glaubst, dann nimm doch mal einen CPC Emulator und lasse den ab BB5A im Debugger-Modus laufen, also Befehl für Befehl. Nach dem RST und folgenden Befehlen wird sehr schnell ein DI und später auch ein EI zu sehen sein.
Quote from: TFM on 25. February 2015, 22:18:20
Wenn Du mir das nicht glaubst, dann nimm doch mal einen CPC Emulator und lasse den ab BB5A im Debugger-Modus laufen, also Befehl für Befehl. Nach dem RST und folgenden Befehlen wird sehr schnell ein DI und später auch ein EI zu sehen sein.
Ja das muß ich wohl mal machen mit dem Debugger, denn in meinen CPC 464 Intern seh ich kein RST mit DI&EI. Aber es ist auch spät, Zeit fürs Bettchen. :)
So, hab heute mal im Debugger geschaut. Läßt sich der Sprung mit dem RST 8 irgendwie umgehen?
Ich glaub ich habe das Interrupt Problem gelöst. Ich lasse die Interruptroutine zusätzlich über ein Flag pürfen ob sie aktuell überhaupt was machen darf. Und jede Zeichenroutine setzt entsprechend vorher das Flag, bzw. löscht es.