Aus eins mach zwei
Mit dieser kleinen Routine »verdoppeln« Sie Ihren Computer. Sie sind damit in der Lage, zwei Maschinenprogramme praktisch gleichzeitig laufen zu lassen.
Die Routine selbst belegt etwa 190 Byte und ist im freien 4-KByte-RAM-Bereich (ab Adresse 49152) abgelegt. Außerdem benötigt sie zwei Pages (Page 193 und 194) als Zwischenspeicher. Zusätzlich wird noch der Basic-Interpreter und das Betriebssystem in das darunterliegende RAM kopiert. Schließlich »verbiegt« die Routine den Interruptvektor.
Das Programm ermöglicht das »gleichzeitige« Betreiben zweier Maschinenroutinen. Jede dieser Routinen läuft nun nur noch mit der halben Geschwindigkeit.
Die Routine wird folgendermaßen gehandhabt: Die Startadresse des ersten Maschinenprogramms, das man benutzen möchte, wird in Adresse 49158 (Lo-Byte) und 49159 (Hi-Byte) abgelegt. Analog verfährt man mit der Startadresse des zweiten Maschinenprogramms, die in Adresse 49156 und 49157 gePOKEt werden muß. Der Befehl SYS 49168 aktiviert die Routine, der Befehl POKE 1,55 (oder in Maschinensprache LDA # 55; STA 1) stellt sie wieder ab. Diese Umschaltung, sei es Basic oder Assembler, wird am besten durch das erste Programm durchgeführt, da nur von dort wieder im Basic-Modus weiter gearbeitet werden kann.
Basic und Maschinensprache gleichzeitig
Grundvoraussetzung für das Koppel-Programm ist, daß die beiden zu betreibenden Routinen in Maschinensprache geschrieben sind. Auf den ersten Blick mag es daher so aussehen, als wären die Einsatzmöglichkeiten dieser Routine sehr beschränkt. Das Gegenteil ist jedoch der Fall. Da auch das Basic-ROM »Maschinensprache« ist, kann man ohne weiteres mit RTS zum Basic-Modus zurückkehren, anstatt die erste Maschinenroutine zu beginnen. Um dies zu erreichen, ersetzt man die Zahl 108 (JMP indirekt) in Speicherstelle 49187 durch eine 96 (RTS-Code). Jetzt kann man in Basic programmieren und seine Basic-Programme auch entsprechend abarbeiten lassen, während eine zweite Maschinensprache-Routine quasi »im Hintergrund« abgearbeitet wird. Denkbare Anwendungen sind das Spielen von Melodien oder die automatische Bewegung von Sprites während des Programm-Laufs.
Nachdem Sie »Multiprogramming« (Listing 1) mit RUN gestartet haben, sehen Sie ein merkwürdiges Geflimmer auf dem Bildschirm. Dies ist kein Fehler im Programm (dessen dokumentierter Source-Code in Listing 2 zu finden ist), sondern eine kleine Demonstration. Eine Maschinenroutine ändert fortwährend die Rahmen-, eine zweite die Hintergrundfarbe. Beide kleinen Programme (Adresse 49350 und 49375) laufen jetzt quasi »gleichzeitig« ab. Die Anwendungsbereiche der Basic-Routine sind sehr vielfältig. Sie reichen von der Ausgabe auf zwei Drucker über die »gleichzeitige« Abfrage von Port A und B bis hin zu komplexeren Realtime-Aufgaben. Da gerade bei einem solchen Programm die Dokumentation sehr wichtig ist, • drucken wir sowohl den Source-Code (Listing 2) als auch das Flußdiagramm (siehe Bild) mit ab.
(Thomas Weinbrenner/ev)
PROGRAMM : MULTIPROGRAMMING 0801 091D ----------------------------------- 0801 : 0C 08 C1 07 9E 20 32 30 77 0809 : 36 32 00 00 00 A0 00 B9 D1 0811 : 1C 08 99 00 C0 C8 D0 F7 1D 0819 : 4C 10 C0 00 00 00 21 DF E2 0821 : C0 C6 C0 F0 F9 54 45 58 9A 0829 : 20 41 53 78 20 27 C0 A9 5F 0831 : 35 A0 62 A2 C0 85 01 8C F9 0839 : FE FF 8E FF FF 58 4C C6 5C 0841 : C0 EA A0 00 84 26 88 84 43 0849 : 27 20 3C C0 A0 BF 84 27 10 0851 : 20 3C C0 20 4F C0 60 A2 85 0859 : 20 A0 00 88 B1 26 91 26 B9 0861 : C0 00 D0 F7 C6 27 CA D0 C7 0869 : F0 60 A9 00 85 02 A0 05 E9 0871 : B9 00 C0 99 FA C2 88 10 96 0879 : F7 60 54 2E 57 48 8A 48 EE 0881 : 98 48 A5 02 D0 27 A0 FF B0 0889 : B9 00 01 99 00 C1 88 C0 68 0891 : FF D0 F5 B9 00 C2 99 00 29 0899 : 01 88 C0 FF D0 F5 BA 8E D3 08A1 : 08 C0 AE 09 C0 9A A9 01 60 08A9 : 85 02 4C B6 C0 A0 FF B9 9E 08B1 : 00 01 99 00 C2 88 C0 FF 0C 08B9 : D0 F5 B9 00 C1 99 00 01 DD 08C1 : 88 C0 FF D0 F5 BA 8E 09 45 08C9 : C0 AE 08 C0 9A A9 00 85 FC 08D1 : 02 68 A8 68 AA 68 4C 48 EE 08D9 : FF FF FF FF FF FF FF FF D8 08E1 : FF A9 00 8D 20 D0 A9 01 98 08E9 : 8D 20 D0 4C C6 C0 FF FF B6 08F1 : FF FF FF FF FF FF FF FF F0 08F9 : FF FF A9 00 8D 21 D0 A9 DB 0901 : 01 8D 21 D0 4C DF C0 FF F2 0909 : FF FF FF FF FF FF FF FF 08 0911 : FF FF FF FF FF FF FF FF 10 0919 : FF FF FF 60 53
Daten für das Programm: 49152 xxx ;y-Register 49153 xxx ;x-Register 49154 xxx ;Akkumulator 49155 33 ;Statusregister 49156 xxx ;Startadresse 2. Programm (Lo und Hi) 49157 xxx 49158 xxx ;Startadresse 1. Programm (Lo und Hi) 49159 xxx 49160 xxx ;Stapelzeiger 1. Programm 49161 249 ;Stapelzeiger 2. Programm Aktivierungsroutine: 49168 SEI 120 49169 JSR 49191 32,39,192 49172 LDA #53 169,53 ;RAM-Konfiguration 49174 LDY #98 160,98 49176 LDX #192 162,192 49178 STA 1 133,1 49180 STY 65534 140,254,255 49183 STX 65535 142,255,255 49186 CLI 88 49187 JMP (49158) 108,6,192 ;Sprung zum 1. Programm Hier werden die Zeiger auf die eigene Interruptroutine gesetzt. Danach wird das erste Programm angesprungen. 49191 LDY #0 160,0 ;Werte setzen zum Basic-ROM kopieren 49193 STY 38 132,38 49195 DEY 136 49196 STY 39 132,39 49198 JSR 49212 32,60,192 ;Basic-ROM kopieren 49201 LDY #191 160,191 ;Werte setzen zum Kernal-ROM kopieren 49203 STY 39 132,39 49205 JSR 49212 32,60,192 ;Kernal-ROM kopieren 49208 JSR 49231 32,79,192 ;Daten setzen 49211 RTS 96 49212 LDX #32 162,32 ;32 Pages kopieren 49214 LDY #0 160,0 49216 DEY 136 49217 LDA (38),Y 177,38 49219 STA (38),Y 145,38 49221 CPY #0 192,0 49223 BNE 49216 208,247 49225 DEC 39 198,39 49227 DEX 202 49228 BNE 49214 208,240 49230 RTS 96 Diese Routine kopiert das Betriebssystem und den Basic-Interpreter in das darunter liegende RAM. 49231 LDA #0 169,0 ;Entscheidungsfaktor 49233 STA 2 133,2 49235 LDY #5 160,5 ;Daten für späteren Interruptrücksprung in Page 194 setzen 49237 LDA 49152,Y 185,0,192 49240 STA 49914,Y 153,250,194 49243 DEY 136 49244 BPL 49237 16,247 49246 RTS 96 Interruptroutine: 49250 PHA 72 ;x-,y-Register und Akku auf den Stack retten 49251 TXA 138 49252 PHA 72 49253 TYA 152 49254 PHA 72 49255 LDA 2 165,2 49257 BNE 49298 208,39 49259 LDY #255 160,255 ;Stack in Page 193 kopieren 49261 LDA 256,Y 185,0,1 49264 STA 49408,Y 153,0,193 49267 DEY 136 49268 CPY #255 192,255 49270 BNE 49261 208,245 49272 LDA 49664,Y 185,0,194 ;Page 194 in den Stack kopieren 49275 STA 256,Y 153,0,1 49278 DEY 136 49279 CPY #255 192,255 49281 BNE 49272 208,245 49283 TSX 186 ;Stapelzeiger vertauschen 49284 STX 49160 142,8,192 49287 LDX 49161 174,9,192 49290 TXS 154 49291 LDY #1 169,1 ;Entscheidungsfakten ändern 49293 STA 2 133,2 49295 JMP 49334 76,182,192 49298 LDY #255 160,255 ;Stack in Page 194 kopieren 49300 LDA 256,Y 185,0,1 49303 STA 49664,Y 153,0,194 49306 DEY 136 49307 CPY #255 192,255 49309 BNE 49300 208,254 49311 LDA 49408,Y 185,0,193 ;Page 193 in den Stack kopieren 49314 STA 256,Y 153,0,1 49317 DEY 136 49318 CPY #255 192,255 49320 BNE 49311 208,245 49322 TSX 186 ;Stapelzeiger ver tauschen 49323 STX 49161 142,9,192 49326 LDX 49160 174,8,192 49329 TXS 154 49330 LDA #0 169,0 ;Entscheidungs Faktor ändern 49332 STA 2 133,2 49334 PLA 104 ;x,y-Register und 49335 TAY 168 ;Akku vom Stack holen 49336 PLA 104 49337 TAX 170 49338 PLA 104 49339 JMP 65352 76,72,255