C 64
Hardware

Nichts ist ewig

Zugegeben, der Commodore 64 hat einige Nachteile. Aber warum sollte man sich damit abfinden? Alles kann mit dem ROM-Change-Programm verändert werden.

Bild 1. Die Steckplätze U3 bis U5

Jedem Computer, auch dem Commodore 64 wird ab Werk eine bestimmte Ausstattung an Software mit auf den Weg gegeben. Damit ist nicht die Demo-Diskette gemeint, sondern die fest im Computer eingebaute, auf PROMs gespeicherte Firmware. Sie sorgt dafür, daß der Commodore überhaupt auf Eingaben reagiert oder einen Basic-Befehl ausführt.

Der gesamte C 64 (und jeder andere Computer) ist eigentlich nichts anderes als eine Anzahl miteinander verdrahteter Baugruppen, die allein zu nichts fähig sind. Leben eingehaucht wird dem ganzen erst durch ein sehr wichtiges Programm, das sogenannte Betriebssystem. Dieses Programm initialisiert und verwaltet die gesamte Hardware. Beim Commodore 64 ist es genau 8 KByte lang und liegt im Bereich von $E000 bis $FFFF. Der zweite wichtige Festwertspeicher ist der Basic-Interpreter. Er ist ein Übersetzungsprogramm, das eine Anweisung in ein maschinengerechtes Signal umwandelt. Auch der Interpreter benötigt 8 KByte und liegt im Bereich von $A000 bis $C000. Jetzt fehlt nur noch der Charakter-Set von 4 KByte, der ebenfalls in einem eigenen ROM untergebracht ist.

Diese drei Programme sind für das äußere Erscheinungsbild und die Funktionalität des Commodore 64 verantwortlich. Hier eröffnet sich ein extrem interessanter Bereich der Programmierung. Dazu bieten sich zwei Wege an: Der erste Weg beruht auf der glücklichen Tatsache, daß es beim Commodore möglich ist, den RAM-Bereich unter einem ROM zu nutzen. In der Praxis sieht das folgendermaßen aus: Die Speicherinhalte des ROMs werden zum Bearbeiten in den darunter liegenden RAM-Bereich kopiert. Ob nun das RAM oder das ROM aktiv ist, entscheidet das 6510 Datenrichtungsregister (Speicherstelle 1). Vom Basic aus ist dieses Register allerdings nur dann zu verändern, wenn sowohl der Basic-Interpreter, als auch das Betriebssystem in das RAM kopiert wurden. Das geschieht entweder mit einer POKE-Schleife oder mit dem ROM-Change Programm. (Betriebssystem kopieren: FOR A = 57344 TO 65535: POKE A,PEEK (A): NEXT)

(Basic kopieren: FOR A = 40960 TO 49152: POKE A, PEEK (A) : NEXT). Der Normalwert dieses Registers ist 55 (probieren Sie es aus). Soll das RAM (für Basic) selektiert aktiv sein, muß hier der Wert 54 eingeschrieben werden. Für Basic und Betriebssystem zusammen beträgt der Wert 53. Alle Veränderungen des Basic und Betriebssystems sind dann aktiv. Bekannte Programme wie Quickcopy und viele Basic-Erweiterungen funktionieren nach diesem Prinzip.

Der zweite und wesentlich reizvollere Weg die Firmware zu beeinflussen ist, das Betriebssytem dauerhaft zu verändern. Dazu ist aber ein Eingriff im Computer notwendig, denn die oben beschriebenen Bausteine müssen gegen andere ausgetauscht werden. Wer also noch Garantie auf seinen Commodore hat, sollte besonders vorsichtig sein. Im ersten Teil dieses Artikels wollen wir, zum Einüben sozusagen, die Funktionstasten des Commodore 64 mit bestimmten, oft gebrauchten Werten belegen. Im zweiten Teil wird das Hypra-Load aus der Ausgabe 10/84 im Betriebssytem verankert. Der Nachteil dieser Änderungen soll nicht verschwiegen werden. Da alle neuen Funktionen natürlich Speicherplatz benötigen, müssen andere Teile des Betriebssystems entfallen. Wir haben uns entschlossen, die Kassettenroutinen ab $F800 herauszunehmen und zu überschreiben. Das Laden von Kassette wird dadurch unmöglich, es sei denn, das alte Betriebssystem wird parallelgeschaltet.

Bild 2. Der 2764 (links) und der 2364 (rechts)

Bevor wir nun auf das Hilfsprogramm für diese Veränderungen, das ROM-Change-Programm, eingehen, sollen die Hardware-Voraussetzungen für die Änderung des Betriebssystems erklärt werden. Nach dem Öffnen des Computers finden wir auf der linken hinteren Seite drei kleine Bausteine, hinter denen auf der Platine die Bezeichnungen U3 bis U5 stehen. U3 ist der Basic-Interpreter, U4 das Betriebssytem, U5 das Charakter-ROM (Bild 1). Heute interessieren wir uns aber nur für den U4-Steckplatz. Wer Glück hat, findet dort einen Stecksockel. Wer Pech hat, muß seinen Händler oder einen Lötkolbenfachmann bitten, ihm hier einen Stecksockel einzulöten. Anstelle des dort befindlichen ROMs kann aber, und das ist die wesentlichste Veränderung, auch ein EPROM stecken. Am besten eignen sich hierzu die 2564-Typen, denn sie sind pinkompatibel zu den Commodore-ICs. Leider sind sie sehr schwer zu beschaffen. Im Normalfall wird aber wahrscheinlich ein 2764-EPROM Verwendung finden. Der Nachteil dieses EPROMs besteht in einer anderen Belegung der Anschlußpins. Hier hilft allerdings ein einfacher Adaptersockel. Dazu braucht man einen 24- und einen 28-Pin-Stecksockel. Diese beiden Sockel werden miteinander verdrahtet (Bild 2 und 3). Bild 2 zeigt die beiden Sockel mit den Beinen nach unten stehend. Der kleine Sockel steckt später im U4-Steckplatz, der größere Sockel trägt das geänderte Betriebssystem und steckt auf dem kleineren Sockel. Vor dem Einbau ist es aber ratsam, alle Kontakte auf richtigen Anschluß und Leitfähigkeit zu überprüfen. Schon ein einziger falscher Anschluß führt zum »Absturz« des gesamten Systems. Bild 4 zeigt, wie der neue Sockel mit der EPROM-Kerbe zur Gehäuse-Rückseite auf der Platine steht.

Nun aber zur Praxis, dem ROM-Change-Programm. Es ermöglicht das gefahrlose Ändern und Ausprobieren aller Umprogrammierungen. Dazu wird nach dem Start der selektierte ROM-Bereich (Betriebssytem oder Basic) ab Adresse $6000 ins RAM kopiert. Das geschieht mit einem kurzen Maschinenprogramm, das im Kassettenpuffer steht. Das Programm ist für den Betrieb mit einem Diskettenlaufwerk gedacht, läuft aber auch im Kassettenbetrieb, wenn ein eigener Monitor zum Laden und Abspeichern Verwendung findet. Nach dem Kopieren erscheint das Hauptmenü, von dem aus alle wichtigen Funktionen erreichbar sind. Die erste dient dem Einlesen von fest im Programm eingebauten DATA-Zeilen. In unserem Beispiel sind ab Zeilennummer 8000 die DATAs für die Funktionstasten einprogrammiert. Hier können natürlich auch eigene Werte stehen. Die erste Zahl gibt dabei die reelle Adresse an, ab der die DATAs geschrieben werden sollen (zum Beispiel 57612 = $E10C). Der Computer errechnet dann die entsprechende Stelle im RAM. Die zweite Zahl gibt an, wieviel Bytes übertragen werden sollen. Die dritte Zahl ist die Prüfsumme. Danach folgen die Programm-DATAs. Bei einem Prüfsummenfehler zeigt der Computer die falsche Prüfsumme an. Eigene Daten werden einfach an die vorhandenen DATAs angehängt. Die ersten drei Bytes müssen natürlich auch die obige Bedeutung haben. Als letzte Zeile muß stehen: DATA 0, da es sonst zu einem OUT OF DATA ERROR kommt. Der zweite Menüpunkt liest Maschinenprogramme direkt an die vorgesehene Stelle. Damit kann man beispielsweise ein Programmfile, das von einem Assembler erzeugt wurde, direkt einlesen. Wichtig ist, daß die Startadresse des Programms im ROM-Adreßbereich beziehungsweise im Bereich $6000 liegt. Der mit Punkt 3 wählbare Minimonitor hilft beim schnellen Ändern einzelner Bytes im hexadezimalen Zahlensystem. Die Startadresse entspricht dabei der Adresse im ROM. Der Minimonitor wird durch Eingabe einer Zahl größer $FF oder des Buchstabens X verlassen. Will man keine Speicherstelle ändern, genügt RETURN für die Übernahme des alten Wertes. Für größere Änderungen reicht dieser Minimonitor natürlich nicht mehr aus. Dazu wird mit Punkt 4 ein eigener Monitor aktiviert. Dieser muß allerdings vor dem Start des ROM-Change-Programms bereits geladen sein. Der Monitor darf im Bereich von $8000 bis $9FFF oder von $C000 bis $CFFF stehen. Zum Starten genügt das Eingeben der Startadresse des Monitors hexadezimal!). Mit den Menüpunkten 5 und 6 wird der Speicherbereich von $6000 bis $7FFF geladen beziehungsweise abgespeichert. Das Laden eines kompletten Betriebssystems dauert allerdings mehrere Minuten. Einer der wichtigsten Menüpunkte ist aber der siebte. Er startet das gerade veränderte oder geladene neue Betriebssystem (es wird natürlich zuerst in seinen richtigen Speicherbereich verschoben). Vor dem Ausprobieren dieser Funktion muß in jedem Fall der Punkt 5 angewählt werden, wenn die Änderungen nicht verlorengehen sollen. Es kann vorkommen, daß das Betriebsystem beim Starten »abstürzt«. Dann genügt ein RESET und die erneute Aktivierung des geänderten ROMs durch POKE 1,53.

2764 2364
1,28,27,26 24
2 21
3 1
4 2
5 3
6 4
7 5
8 6
9 7
10 8
11 9
12 10
13 11
14 12,20
15 13
16 14
17 15
18 16
19 17
20,14 nicht angeschl.
21 19
22 20
23 18
24 22
25 23
1,28,27,26 24
Bild 3. So wird der 2764 mit den Pins des 2364-Sockels verbunden

Sind alle Tests im RAM positiv verlaufen, können wir uns an die Speicherung des neuen Betriebssytems auf EPROMs heranwagen. Das neue Betriebssystem wird von Diskette in den RAM-Bereich ab $6000 absolut, das heißt mit LOAD"Ihr Betriebssytem",8,1 geladen. Ab dieser Adresse beginnt auch die Programmierung des EPROMs. Sie endet bei $8000 (8 KByte). Das neue EPROM wird anschließend in den beschriebenen Stecksockel eingesetzt und in Steckplatz U4 befestigt. Fertig ist das Betriebssytem.

Was noch zu klären bleibt, ist die im ROM-Change-Programm bereits eingebaute Funktionstastenbelegung. Die Abfrage der Tastatur geschieht im Betriebssytem über den Interrupt. Wird eine Taste gedrückt, hält der Prozessor das laufende Programm an und springt in die Interrupt-Unterroutine bei $EA31. Dort wird festgestellt, welche Taste gedrückt wurde. Der ASCII-Code der Taste wird im Tastaturpuffer gespeichert. Das Funktionstastenprogramm greift an dieser Stelle ein, indem es den Wert der gedrückten Tasten mit den ASCII-Codes für die Funktionstasten (133-140) vergleicht. Stimmt der Wert nicht überein, so wird das Programm normal weitergeführt. Ansonsten vergleicht das Programm den Tastenwert mit einer Tabelle, in der die Belegungen für die Funktionstasten stehen. Hat das Programm die zur Funktionstaste gehörige Belegung gefunden, wird diese in den Tastaturpuffer geschrieben. Damit auch Programme, die auf einer Abfrage der Funktionstaste aufbauen, funktionieren, wurde eine Autoabschalt-Unterroutine mitprogrammiert. Kommt es dennoch einmal zu Schwierigkeiten, werden die Funktionstasten mit POKE 2,1 abgeschaltet und mit POKE 2,0 wieder aktiviert.

Abschließend sei nochmals darauf hingewiesen, daß alle Arbeiten an der Hardware des C 64 mit einem nicht geringen Zerstörungsrisiko verbunden sind. Wer also im Umgang mit Lötkolben und EPROMs nicht geübt ist, sollte sich an einen Fachmann wenden.

(Arnd Wängler/Ernst Schöberl/aa)
Bild 4. Das EPROM 2754 zweifach »gesockelt«

Beim Abtippen des Programms sind die Werte in Klammern am Ende einer Zeile nicht miteinzugeben. Sie sind erst für eine spätere Ausgabe von Bedeutung. Unterstrichene Buchstaben sind mit der Shift-Taste, überstrichene mit der Commodore-Taste einzugeben. Bei Ausdrücken in eckigen Klammern ist die jeweilige Taste zu drücken.

|
100 rem speicherplatz fuer rom vor basic schuetzen
110 poke 55,0:poke 56,96:clr
120 poke 53272,23:poke 53280,2
130 gosub 1130
140 if peek(53247)<>33 then 160
150 if peek(53246)=0 then gosub 3600:goto 500
155 gosub 3700:goto 500
160 print"{down}{down}":print" Druecken sie":print
170 print:print tab(7);"1  um Kernal ($E000-$FFFF)"
180 print:print tab(7);"2  um Basic ($A000-$BFFF)"
190 print:print:print tab(11);"in RAM ab $6000 zu kopieren."
200 get a$:if a$=""then 200
210 if a$="1"then poke 32767,255:gosub 3600:goto 240
220 if a$<>"2"then 200
230 gosub 3700
240 gosub 1600
300 poke k+8,int(an/256)
310 poke k+29,int(en/256)
340 sys k :rem schieberoutine
500 poke 53280,5:gosub 1130:print:poke 53247,0
505 print:print:print"      Erweiterung des ROMs durch":print
506 print tab(8);"1: Data Zeilen einlesen"
510 print tab(8);"2: Programm von Disk"
520 print tab(8);"3: Hexmonitor"
530 print tab(8);"4: Eigenen Monitor"
540 print tab(8);"5: Abspeichern des neuen ROMs"
545 print tab(8);"6: Laden von geaendertem ROM"
546 print tab(8);"7: Starten des neuen ROMs"
547 print tab(8);"8: Programm beenden"
550 print:print:print tab(10);"Bitte waehlen sie!"
560 get a$:if a$=""then 560
570 i=val(a$):if i<1 or i>8 then 560
580 on i goto 1000,2000,3000,4000,5000,6000,2500,3500
999 rem data zeilen einlesen
1000 print"{clr}":print:print tab(10);"Lesen der Data-Zeilen":print:print
1010 gosub 1600
1020 read a:if a=0 then 500
1030 read b:rem anzahl der bytes
1032 read p1:rem pruefsumme
1033 p2=0
1035 d=a:gosub 1300:print"$";a$;"-";:d=a+b-1:gosub 1300:print"$";a$;
1040 for i=a-of to a-of-1+b
1050 read d:poke i,d
1051 p2=p2+d:if p2>65535 then p2=p2-65536
1053 next i
1055 if p2<>p1 then 1070
1057 print"   ok"
1060 goto 1020
1070 print"pruefsumme falsch: ";p2
1080 get a$:if a$=""then 1080
1090 goto 1020
1100 stop
1130 print"{clr}":print tab(8);"Programm zum Aendern des":print
1140 print tab(12)"Betriebssystems":print:print
1150 print" geschrieben von Ernst Schoeberl (1984)"
1160 return
1199 rem hex in dez umwandlung
1200 d=0:for j1=0 to len(a$)-1
1210 b=asc(right$(a$,1)):a$=left$(a$,len(a$)-1)
1220 b=b-48:if b>9 then b=b-7
1230 if b<0 or b>16 then 1280
1240 d=d+b+16^j1
1250 next j1
1260 return
1280 d=-1:return
1299 rem dez in hex
1300 j2=int(log(d)/log(16)):a$=""
1310 for j1=j2 to 0 step-1
1320 k1=int(d/16^j1):d=d-k1*16^j1
1330 if k1>9 then k1=k1+7
1340 k1=k1+48:a$=a$+chr$(k1)
1350 next j1
1360 return
1600 restore:k=828:for i=k to k+32:read a:poke i,a:next i
1610 data 120,160,0,132,251,132,253,169,224,133,252,169,96,133,254,177,251,145
1620 data 253,200,208,249,230,252,230,254,165,252,201,0,208,239,96
1630 return
1999 rem programm von disk in rom einfuegen
2000 gosub 1130:print
2010 print tab(2);"Einfuegen eines Programms von Disk"
2020 print:print:print:input"Filename:";a$
2030 open 1,8,0,a$
2033 gosub 6100:i=asc(a$):gosub 6100:i=i+256*asc(a$):if st>0 then 6200
2035 print:print"found ";a$
2036 if i<an then 2110
2040 get#1,a$:a$=a$+chr$(0)
2050 if st>0 then 2100
2060 poke i-of,asc(a$):i=i+1:goto 2040
2100 close 1:goto 500
2109 rem programm nicht in rombereich
2110 print"ROM von $";:d=an:gosub 1300:print a$;"-";:d=an+8191:gosub 1300:print a$
2120 print"Startadresse des Programms bei $";:d=i:gosub 1300:print a$
2130 input"Neue Startadresse (muss im ROM-Bereich liegen:";a$
2140 gosub 1200:if d=-1 or d<an then 2100
2150 i=d:goto 2040
2499 rem rom starten
2500 gosub 1600
2510 poke k+8,160:poke k+29,0
2515 poke k+12,160
2520 sys k
2525 k=828
2530 poke k+8,96
2540 poke k+9,128
2550 poke k+12,int(an/256)
2560 sys k
2565 print"{clr}":print">Neues Rom aktiviert":print
2570 poke 1,53:input"Reset (j/n)";a$:if a$="j"then sys 64738
2580 goto 500
2999 rem monitor fuer einzelne speicherstellen
3000 print"{clr}":print"*** Monitor {SHIFT-*}{SHIFT-*}{SHIFT-*}":print:print
3010 input"Startadresse:";a$:gosub 1200
3020 i=d-of:if i=-1 then 3010
3030 d=i+of:gosub 1300:print a$;" ";:d=peek(i):gosub 1300:print a$;"    ";
3040 input":";a$
3050 if a$=chr$(13)then 3070
3060 gosub 1200:if d=-1 or d>255 then 3090
3065 poke i,d
3070 i=i+1:goto 3030
3090 print"Ende (j/n)"
3095 get a$:if a$="n"then 3010
3096 if a$<>"j"then 3095
3100 goto 500
3500 poke 53247,0:end
3599 rem werte fuer kernal ram
3600 an=14*4096:en=0:of=8*4096:poke 53246,0:return
3699 rem werte fuer basic rom
3700 an=10*4096:en=12*4096:of=4*4096:poke 53246,1:return
3999 rem eigener monitor
4000 print"{clr}":print:print"       Eigener Monitor"
4010 print:print:input"startadresse (hex):";a$
4020 if len(a$)>4 then 4000
4030 gosub 1200:if d=-1 then 4000
4040 sys d
4050 goto 500
4999 rem abspeichern des roms
5000 gosub 1130:print
5010 print tab(7);"Abspeichern des neuen ROMs"
5020 print:print:print:input"Filename:";a$
5030 open 1,8,1,a$
5035 print:print"saving ";a$
5040 print#1,chr$(0);chr$(96);
5050 for i=6*4096 to 32767
5060 print#1,chr$(peek(i));:next i
5070 print#1,chr$(an-int(an/256)*256);
5080 print#1,chr$(an/256)
5090 close 1:goto 500
5999 rem geaendertes rom laden
6000 gosub 1330:print
6010 print tab(10);"Laden eines neuen ROMs"
6020 print:print:print:input"Filename:";a$
6030 open 1,8,0,a$
6040 gosub 6100:gosub 6100
6042 if st>0 then 6200
6043 print:print"loading ";a$
6050 for i=6*4096 to 32767
6060 get#1,a$:a$=a$+chr$(0)
6070 poke i,asc(a$):next i
6080 gosub 6100:an=asc(a$):gosub 6100:an=an+256*asc(a$)
6090 of=an-6*4096:en=an+8192:close 1
6095 if en>65535 then en=0
6096 if an<14*4096 then poke 53246,1:goto 500
6097 poke 53246,0:goto 500
6100 get#1,a$:a$=a$+chr$(0):return
6200 close 1:print
6210 open 1,8,15
6220 if st=64 then 6250
6230 get#1,a$:print a$;:goto 6220
6250 close 1
6260 get a$:if a$=""then 6260
6270 goto 500
7990 rem ab hier datas
8000 data 64226,126,14014
8001 data 232,134,198,201,133,144,4,201,141,144,3,76,66,235,157,119,2,72,152
8002 data 72,160,0,196,2,208,13,185,41,251,221,119,2,240,11,200,192,176,208
8003 data 243,104,168,104,76,66,235,200,185,41,251,201,133,144,4,201,141,144
8004 data 238,236,137,2,176,233,157,119,2,232,134,198,76,15,251,133,76,207
8005 data 34,36,34,44,56,13,137,76,79,65,68,134,76,73,83,84,13,138,83,65,86
8006 data 69,135,82,85,78,13,139,83,89,83,136,63,70,82,69,40,48,41,13,140,83
8007 data 89,83,54,52,55,51,56,13,133,136
8010 data 60223,3,552
8011 data 76,226,250
10000 data 0
 100 REM SPEICHERPLATZ FUER ROM VOR BASIC SCHUETZEN 
 110 POKE 55,0:POKE 56,96:CLR 
 120 POKE 53272,23:POKE 53280,2 
 130 GOSUB 1130 
 140 IF PEEK (53247)<>33  THEN 160 
 150 IF PEEK (53246)=0  THEN GOSUB 3600:GOTO 500 
 155 GOSUB 3700:GOTO 500 
 160 PRINT"{2DOWN}":PRINT" DRUECKEN SIE":PRINT 
 170 PRINT:PRINT TAB( 7);"1{2SPACE}UM KERNAL ($E000-$FFFF)" 
 180 PRINT:PRINT TAB( 7);"2{2SPACE}UM BASIC ($A000-$BFFF)" 
 190 PRINT:PRINT:PRINT TAB( 11);"IN RAM AB $6000 ZU KOPIEREN." 
 200 GET A$:IF A$="" THEN 200 
 210 IF A$="1" THEN POKE 32767,255:GOSUB 3600:GOTO 240 
 220 IF A$<>"2" THEN 200 
 230 GOSUB 3700 
 240 GOSUB 1600 
 300 POKE K+8,INT (AN/256) 
 310 POKE K+29,INT (EN/256) 
 340 SYS K :REM SCHIEBEROUTINE 
 500 POKE 53280,5:GOSUB 1130:PRINT:POKE 53247,0 
 505 PRINT:PRINT:PRINT"{6SPACE}ERWEITERUNG DES ROMS DURCH":PRINT 
 506 PRINT TAB( 8);"1: DATA ZEILEN EINLESEN" 
 510 PRINT TAB( 8);"2: PROGRAMM VON DISK" 
 520 PRINT TAB( 8);"3: HEXMONITOR" 
 530 PRINT TAB( 8);"4: EIGENEN MONITOR" 
 540 PRINT TAB( 8);"5: ABSPEICHERN DES NEUEN ROMS" 
 545 PRINT TAB( 8);"6: LADEN VON GEAENDERTEM ROM" 
 546 PRINT TAB( 8);"7: STARTEN DES NEUEN ROMS" 
 547 PRINT TAB( 8);"8: PROGRAMM BEENDEN" 
 550 PRINT:PRINT:PRINT TAB( 10);"BITTE WAEHLEN SIE!" 
 560 GET A$:IF A$="" THEN 560 
 570 I=VAL (A$):IF I<1 OR I>8  THEN 560 
 580 ON I GOTO 1000,2000,3000,4000,5000,6000,2500,3500 
 999 REM DATA ZEILEN EINLESEN 
 1000 PRINT"{CLR}":PRINT:PRINT TAB( 10);"LESEN DER DATA-ZEILEN":PRINT:PRINT 
 1010 GOSUB 1600 
 1020 READ A:IF A=0  THEN 500 
 1030 READ B:REM ANZAHL DER BYTES 
 1032 READ P1:REM PRUEFSUMME 
 1033 P2=0 
 1035 D=A:GOSUB 1300:PRINT"$";A$;"-";:D=A+B-1:GOSUB 1300:PRINT"$";A$; 
 1040 FOR I=A-OF  TO A-OF-1+B 
 1050 READ D:POKE I,D 
 1051 P2=P2+D:IF P2>65535  THEN P2=P2-65536 
 1053 NEXT I 
 1055 IF P2<>P1  THEN 1070 
 1057 PRINT"{3SPACE}OK" 
 1060 GOTO 1020 
 1070 PRINT"PRUEFSUMME FALSCH: ";P2 
 1080 GET A$:IF A$="" THEN 1080 
 1090 GOTO 1020 
 1100 STOP 
 1130 PRINT"{CLR}":PRINT TAB( 8);"PROGRAMM ZUM AENDERN DES":PRINT 
 1140 PRINT TAB( 12)"BETRIEBSSYSTEMS":PRINT:PRINT 
 1150 PRINT" GESCHRIEBEN VON ERNST SCHOEBERL (1984)" 
 1160 RETURN 
 1199 REM HEX IN DEZ UMWANDLUNG 
 1200 D=0:FOR J1=0  TO LEN (A$)-1 
 1210 B=ASC (RIGHT$ (A$,1)):A$=LEFT$ (A$,LEN (A$)-1) 
 1220 B=B-48:IF B>9  THEN B=B-7 
 1230 IF B<0 OR B>16  THEN 1280 
 1240 D=D+B+16^J1 
 1250 NEXT J1 
 1260 RETURN 
 1280 D=-1:RETURN 
 1299 REM DEZ IN HEX 
 1300 J2=INT (LOG (D)/LOG (16)):A$="" 
 1310 FOR J1=J2  TO 0 STEP -1 
 1320 K1=INT (D/16^J1):D=D-K1*16^J1 
 1330 IF K1>9  THEN K1=K1+7 
 1340 K1=K1+48:A$=A$+CHR$ (K1) 
 1350 NEXT J1 
 1360 RETURN 
 1600 RESTORE :K=828:FOR I=K  TO K+32:READ A:POKE I,A:NEXT I 
 1610 DATA 120,160,0,132,251,132,253,169,224,133,252,169,96,133,254,177,251,145 
 1620 DATA 253,200,208,249,230,252,230,254,165,252,201,0,208,239,96 
 1630 RETURN 
 1999 REM PROGRAMM VON DISK IN ROM EINFUEGEN 
 2000 GOSUB 1130:PRINT 
 2010 PRINT TAB( 2);"EINFUEGEN EINES PROGRAMMS VON DISK" 
 2020 PRINT:PRINT:PRINT:INPUT"FILENAME:";A$ 
 2030 OPEN 1,8,0,A$ 
 2033 GOSUB 6100:I=ASC (A$):GOSUB 6100:I=I+256*ASC (A$):IF ST>0  THEN 6200 
 2035 PRINT:PRINT"FOUND ";A$ 
 2036 IF I<AN  THEN 2110 
 2040 GET #1,A$:A$=A$+CHR$ (0) 
 2050 IF ST>0  THEN 2100 
 2060 POKE I-OF,ASC (A$):I=I+1:GOTO 2040 
 2100 CLOSE 1:GOTO 500 
 2109 REM PROGRAMM NICHT IN ROMBEREICH 
 2110 PRINT"ROM VON $";:D=AN:GOSUB 1300:PRINT A$;"-";:D=AN+8191:GOSUB 1300:PRINT A$ 
 2120 PRINT"STARTADRESSE DES PROGRAMMS BEI $";:D=I:GOSUB 1300:PRINT A$ 
 2130 INPUT"NEUE STARTADRESSE (MUSS IM ROM-BEREICH LIEGEN:";A$ 
 2140 GOSUB 1200:IF D=-1 OR D<AN  THEN 2100 
 2150 I=D:GOTO 2040 
 2499 REM ROM STARTEN 
 2500 GOSUB 1600 
 2510 POKE K+8,160:POKE K+29,0 
 2515 POKE K+12,160 
 2520 SYS K 
 2525 K=828 
 2530 POKE K+8,96 
 2540 POKE K+9,128 
 2550 POKE K+12,INT (AN/256) 
 2560 SYS K 
 2565 PRINT"{CLR}":PRINT">NEUES ROM AKTIVIERT":PRINT 
 2570 POKE 1,53:INPUT"RESET (J/N)";A$:IF A$="J" THEN SYS 64738 
 2580 GOTO 500 
 2999 REM MONITOR FUER EINZELNE SPEICHERSTELLEN 
 3000 PRINT"{CLR}":PRINT"*** MONITOR ***":PRINT:PRINT 
 3010 INPUT"STARTADRESSE:";A$:GOSUB 1200 
 3020 I=D-OF:IF I=-1  THEN 3010 
 3030 D=I+OF:GOSUB 1300:PRINT A$;" ";:D=PEEK (I):GOSUB 1300:PRINT A$;"{4SPACE}"; 
 3040 INPUT":";A$ 
 3050 IF A$=CHR$ (13) THEN 3070 
 3060 GOSUB 1200:IF D=-1 OR D>255  THEN 3090 
 3065 POKE I,D 
 3070 I=I+1:GOTO 3030 
 3090 PRINT"ENDE (J/N)" 
 3095 GET A$:IF A$="N" THEN 3010 
 3096 IF A$<>"J" THEN 3095 
 3100 GOTO 500 
 3500 POKE 53247,0:END 
 3599 REM WERTE FUER KERNAL RAM 
 3600 AN=14*4096:EN=0:OF=8*4096:POKE 53246,0:RETURN 
 3699 REM WERTE FUER BASIC ROM 
 3700 AN=10*4096:EN=12*4096:OF=4*4096:POKE 53246,1:RETURN 
 3999 REM EIGENER MONITOR 
 4000 PRINT"{CLR}":PRINT:PRINT"{SPACE,6SPACE}EIGENER MONITOR" 
 4010 PRINT:PRINT:INPUT"STARTADRESSE (HEX):";A$ 
 4020 IF LEN (A$)>4  THEN 4000 
 4030 GOSUB 1200:IF D=-1  THEN 4000 
 4040 SYS D 
 4050 GOTO 500 
 4999 REM ABSPEICHERN DES ROMS 
 5000 GOSUB 1130:PRINT 
 5010 PRINT TAB( 7);"ABSPEICHERN DES NEUEN ROMS" 
 5020 PRINT:PRINT:PRINT:INPUT"FILENAME:";A$ 
 5030 OPEN 1,8,1,A$ 
 5035 PRINT:PRINT"SAVING ";A$ 
 5040 PRINT#1,CHR$ (0);CHR$ (96); 
 5050 FOR I=6*4096  TO 32767 
 5060 PRINT#1,CHR$ (PEEK (I));:NEXT I 
 5070 PRINT#1,CHR$ (AN-INT (AN/256)*256); 
 5080 PRINT#1,CHR$ (AN/256) 
 5090 CLOSE 1:GOTO 500 
 5999 REM GEAENDERTES ROM LADEN 
 6000 GOSUB 1330:PRINT 
 6010 PRINT TAB( 10);"LADEN EINES NEUEN ROMS" 
 6020 PRINT:PRINT:PRINT:INPUT"FILENAME:";A$ 
 6030 OPEN 1,8,0,A$ 
 6040 GOSUB 6100:GOSUB 6100 
 6042 IF ST>0  THEN 6200 
 6043 PRINT:PRINT"LOADING ";A$ 
 6050 FOR I=6*4096  TO 32767 
 6060 GET #1,A$:A$=A$+CHR$ (0) 
 6070 POKE I,ASC (A$):NEXT I 
 6080 GOSUB 6100:AN=ASC (A$):GOSUB 6100:AN=AN+256*ASC (A$) 
 6090 OF=AN-6*4096:EN=AN+8192:CLOSE 1 
 6095 IF EN>65535  THEN EN=0 
 6096 IF AN<14*4096  THEN POKE 53246,1:GOTO 500 
 6097 POKE 53246,0:GOTO 500 
 6100 GET #1,A$:A$=A$+CHR$ (0):RETURN 
 6200 CLOSE 1:PRINT 
 6210 OPEN 1,8,15 
 6220 IF ST=64  THEN 6250 
 6230 GET #1,A$:PRINT A$;:GOTO 6220 
 6250 CLOSE 1 
 6260 GET A$:IF A$="" THEN 6260 
 6270 GOTO 500 
 7990 REM AB HIER DATAS 
 8000 DATA 64226,126,14014 
 8001 DATA 232,134,198,201,133,144,4,201,141,144,3,76,66,235,157,119,2,72,152 
 8002 DATA 72,160,0,196,2,208,13,185,41,251,221,119,2,240,11,200,192,176,208 
 8003 DATA 243,104,168,104,76,66,235,200,185,41,251,201,133,144,4,201,141,144 
 8004 DATA 238,236,137,2,176,233,157,119,2,232,134,198,76,15,251,133,76,207 
 8005 DATA 34,36,34,44,56,13,137,76,79,65,68,134,76,73,83,84,13,138,83,65,86 
 8006 DATA 69,135,82,85,78,13,139,83,89,83,136,63,70,82,69,40,48,41,13,140,83 
 8007 DATA 89,83,54,52,55,51,56,13,133,136 
 8010 DATA 60223,3,552 
 8011 DATA 76,226,250 
 10000 DATA 0 
Listing »ROM-Change«
PDF Diesen Artikel als PDF herunterladen
Mastodon Diesen Artikel auf Mastodon teilen
← Vorheriger ArtikelNächster Artikel →