C 64
Tips & Tricks

Dem C 64 und Plus/4 Arbeit aufstapeln

Wollen Sie viele verschiedene Tätigkeiten direkt hintereinander ausführen und haben keine Lust, die ganze Zeit neben dem Computer sitzen zu müssen? Die Lösung heißt Batch- oder Stapel-Verarbeitung. Zusätzlich stellen wir Ihnen noch einen komfortablen Editor zur Verfügung.

Hier werden gleich zwei Programme auf einmal vorgestellt, die beide sehr nützlich sind:
EDI.BAS – ein total in Basic geschriebener und trotzdem vollwertiger, schneller Screen-Editor
BATCH – ein Programm, das einen Hauch von Großrechner-Komfort zugänglich macht, indem ganze Folgen von Programmen und Eingaben automatisch ablaufen, ohne daß der Benutzer Hand anlegen muß.

Die Batch-Verarbeitung arbeitet rein theoretisch wie ein sehr großer Tastaturpuffer. Man kann dem Computer im voraus die Eingaben für die nächsten Minuten oder gar Stunden geben. In diesen Eingaben können selbstverständlich LOAD- und RUN-Befehle enthalten sein, so daß sich ganze Programmketten auf einen Befehl hin abarbeiten lassen. Da man sich das wie einen Stapel von Eingaben vorstellen kann, von dem der Computer sich immer eine neue Arbeit abholt, bis der Stapel abgetragen ist, nennt man diese Prozedur Stapel- oder englisch Batch-Verarbeitung.

Der Editor – EDI.BAS

Wie oft muß in Programmen eine größere Menge Text eingegeben werden oder es werden Datenfiles gebraucht, in denen bestimmte Werte drinstehen oder korrigiert werden sollen. Man findet dann oft mehr oder weniger aufwendig gestaltete Editor-Routinen, die aber lange nicht an den Komfort heranreichen, den ein echter Screen-Editor bietet.

Die Routine EDI.BAS, die im Listing 1 die Zeilen 1 bis 299 umfaßt, ist ein kleiner Auszug aus einem kompletten Textsystem. Sie ist völlig eigenständig und kann auch ohne den Rest dieses Listings verwendet werden.

Eine besondere Eigenschaft von EDI.BAS ist, daß es sich automatisch an 40- und 80-Zeichen-Schirme anpassen kann! Wen die Verfahrensweise interessiert, der sollte sich die Zeile 350 ansehen. Dort wird ein Zeichen an die 41. Bildschirmposition gesetzt und dann überprüft, ob es sich schon in der zweiten Zeile befindet.

Vor der ersten Benutzung als eigenständiges Programm ist EDI.BAS durch Aufruf der Zeile 200 zu initialisieren. Dies entfällt, wenn man das komplette Listing abgetippt hat.

EDI.BAS bearbeitet einen zeilenweise in A$() abgespeicherten Text. Aufgerufen wird der Editor nach der Initialisierung einfach mit GOSUB 100.

EDI.BAS erklärt sich durch seine Help-Funktion fast von selbst. Diese Funktion kann man durch Eintippen von »H« und Return in der Kommandozeile erreichen.

Einschränkungen bestehen nur darin, daß nur die allernotwendigsten Funktionen vorhanden sind und daß die Zeilenlänge auf 77 Zeichen beschränkt werden mußte.

Erst dadurch, das EDI.BAS vollkommen in Basic programmiert wurde, ohne POKE- und PEEK-Befehle zu benutzen, konnte erreicht werden, daß die Routine auf fast allen Commodore-Rechnern, so dem C 64, C 128 oder dem 8032 anstandslos läuft.

Batch-Verarbeitung

Viele Aktionen sind nicht direkt programmierbar, so zum Beispiel die Aufrufe mehrerer Programme hintereinander und die Versorgung dieser Programme mit diversen Eingaben. Solche Befehlsfolgen können mit BATCH in einem Zug eingetippt und dann automatisch durchgeführt werden. Bedient wird BATCH folgendermaßen:

a) Start einfach mit RUN (ohne Parameter): Es wird ein Filename erfragt, unter dem die Kommandofolge auf der Floppy abgelegt werden soll beziehungsweise schon vorhanden ist. Wenn das File noch nicht existiert, kann es mit dem in BATCH 64 eingebauten Editor erstellt werden. Ist die Kommandofolge fertig, wird sie abgespeichert. Sie wird anschließend nochmals eingelesen und in einem geschützten RAM-Bereich abgelegt. Zum Schluß kann der Batch-Job mit einem unter dem Cursor bereitgestellten SYS-Befehl gestartet werden.

b) Start mit Angabe von Parametern: In einem Kommando-Mutterfile können manche Eingaben (zum Beispiel Filenamen) mit formalen Parametern %a, %b, ..., %z gekennzeichnet werden. Beim Aufruf von BATCH 64 werden diese dann mit aktuellen Inhalten versorgt und gelangen so zur Ausführung. Dazu muß hinter dem RUN-Befehl ein Doppelpunkt geschrieben werden, gefolgt von der Liste der aktuellen Parameter-Inhalte (Strings), jeweils durch Kommata getrennt. Der erste Parameter ist immer der Name des Kommando-Mutterfiles; wird hier ein Minus (-) eingegeben, wird der Parameter erfragt. Die folgenden entsprechen der alphabetischen Reihenfolge %a, ... Soll ein Parameterstring selbst ein Komma enthalten, muß er in Gänsefüßchen eingeschlossen werden. Gänsefüßchen können nicht übergeben werden! Beispiel: RUN: Mutterfile, erster Par, zweiter,, vierter, "ein komma: ,"
Bleibt ein Parameter leer (hier %c), erzeugt er im Kommandofile eine leere Stelle. Auf diese Weise wird aus dem Kommando-Mutterfile ein aktuelles Kommandofile (Batchfile) erzeugt, das auf Wunsch auch noch verändert werden kann. Vor Ausführung muß es auf jeden Fall noch einmal auf Floppy gespeichert werden. Der endgültige Aufruf erfolgt mit SYS wie oben bei a).

c) Aufruf mit Angabe des Kommandofilenamens: Ist schon ein fertig verwendbares Kommandofile vorhanden, kann es ohne weitere Nachfragen direkt gestartet werden. Dazu schreibt man dessen Filenamen (und nur diesen) durch Doppelpunkt getrennt hinter das RUN des Startkommados für das Programm BATCH 64. Beispiel: RUN:kommando.bat (also ähnlich wie oben das Mutterfile).

Wirkungsweise:

Der Kommandotext wird zusammen mit einer zugehörigen Maschinen-Routine unterhalb des aktuell zugänglichen RAM-Endes abgelegt (relokiert). Dieser Speicherbereich wird durch Umsetzen des Top-of-RAM-Pointers vor Überschreiben durch Basic geschützt. Die Maschinenroutine wird in die Interrupt-Routine des Computers eingeschleift. Stellt diese nach Aktivierung fest, daß der Tastaturpuffer leer ist, holt sie aus dem Kommandotext das nächste Byte und legt es in den Tastaturpuffer. Die eigene Interrupt-Routine schaltet sich automatisch selbst ab, wenn:

— der ganze Kommandotext abgearbeitet ist,

— die Stopptaste gedrückt wird oder

— im Tastaturpuffer mehr als ein Tastendruck, also Eingaben des Benutzers, angetroffen werden.

Der Top-of-RAM-Pointer wird nicht zurückgesetzt!

Einschränkungen:

Es sind einerseits die RAM-Belegung und andererseits das Interrupt-Verhalten aufgerufener Software zu beachten. Durch geeignetes Setzen des Top-of-RAM-Pointers vor Aufruf von BATCH 64 kann meist eine Kollision mit anderen Programmen in diesem Speicherbereich vermieden werden.

Da eine eigene Interrupt-Routine eingeschleift wird, kann es bei Programmen, die das auch tun, zu Kollisionen kommen. Bei wiederholten Aufruf von BATCH64 wird der Top-of-RAM-Pointer immer nur noch tiefer gesetzt, so daß er in vernünftigen Abständen wieder initialisiert werden sollte, zum Beispiel durch POKE56,160:clr

Als Detail sei noch auf die Parameterübergabe im RUN-Befehl hingewiesen, die durch die GET-Funktion aus dem Bildschirm bewerkstelligt wird. Dadurch sind Schreibweisen möglich, wie man sie sonst nur aus Betriebssystemkommandos anderer, größerer Computer kennt.

Zur Anpassung an andere Computer sind die DATA-Zeilen mit der Maschinenroutine (siehe unten) und die Zeilen 700 und 805 mit der Adresse des Top-of-Memory-Pointers zu verändern. Letztere ist auch zu beachten, wenn man diesen Pointer ab und zu wieder restauriert:

POKE56,160:CLR:REM C 64
POKE56,128:CLR:REM PLUS/4
POKE53,128:CLR:REM 8xxx/40xx

Daß man beim PLUS/4 nur die ersten 32 KByte des Speichers ausnutzen kann (siehe auch Zeile 701, Listing 1!), liegt daran, daß man bei höherer Plazierung der eigenen Interrupt-Routine noch Bank-Switching zwischen parallelliegendem RAM und ROM ausführen müßte. Diesen Ausbau der Routine will ich gern interessierten Lesern überlassen.

Noch etwas zum Verfahren: Der Kommandotext muß ins RAM gelegt werden, weil zum Zeitpunkt der Abarbeitung durchaus schon alle Floppy-Kanäle (beziehungsweise Puffer) belegt sein können, so daß kein direkter Zugriff auf das Kommandofile mehr möglich ist. Der Top-of-RAM-Pointer darf auch nicht automatisch beim Ausklinken der Interrrupt-Routine zurückgestellt werden, denn anschließend müßte ja ein CLR-Befehl gegeben werden, der Variablen eines womöglich nicht in vollem Lauf befindlichen Basic-Programms einfach zerstören würde!

Theoretischerweise kann man in BATSCH 64 auch die Routine EDI-BAS weglassen und durch eine andere ersetzen, oder man benutzt einen externen Texteditor zur Erstellung der Kommandofiles. Auf jeden Fall muß das File anschließend reinen ASCII-Text enthalten, also nicht Bildschirmcode oder Vorspänne mit Tab- und Formatier-Informationen.

Listing 2 ist das Assembler-Listing der von BATCH verwendeten Maschinen-Routine, und zwar in der 8xxx/40xx-Version. Die Version für den C 64 können Sie den Hinweisen und den DATAs aus Listing 1 entnehmen. Hinweise gibt es auch zur Anpassung an den Plus/4.

Der Quelltext ist mit Gewalt (Adresse $fe90 statt $90 für 8xxx, das Byte $fe=254 muß nachträglich zu Fuß in den DATAs auf 000 korrigiert werden!) so gestaltet, daß er für alle Computer die gleiche Länge hat. Die Anpassung an andere kann also direkt in den DATA-Zeilen von Listing 2 erfolgen, wenn man im Assembler-Listing die Änderungen und Vorkommen der fraglichen Werte heraussucht.

Nur für 8xxx/40xx ist der Programmteil aktiv, der sich um die I/O-Ende-Routine kümmert. Dahinter verbirgt sich eine ganz böse Falle für jeden Interrupt-Routinen-Programmierer. Auf besagtem Rechner wird nämlich nach jeder Ein-/Ausgabe eine Routine aufgerufen, die einfach so lange wartet, bis der Interrupt-Pointer wieder seinen Normalwert hat! Das kommt von den Kassettenroutinen, deren Timing über eigene Interrupt-Routinen gemanagt wird. Wenn man den Pointer nun aber selbst verbogen hat und zum Beispiel einen LOAD-Befehl gibt, bleibt der Computer erst mal hängen, läßt sich aber immerhin mit der Stopptaste zurückholen. Zur Abhilfe schaut nun in unserer Routine ein Programmteil auf dem Stack nach, ob die Rücksprungadresse womöglich irgendwo in diese Warteschleife zeigt. Wenn ja, wird die Rücksprungadresse brutal auf den nächsten RTS-Befehl umgesetzt.

Testlauf

Erstellen Sie am besten ein Kommandofile namens TEST.BAT mit folgenden zwei Zeilen Inhalt (Kleinschreibung wegen Groß/Klein-Modus des Editors):

list-5
run:test-bat

Wenn Sie BATCH 64 mit RUN:TEST.BAT aufrufen, müßte sich ein immer wieder selbst anstartender Ablauf ergeben, der erst durch OUT OF MEMORY ERROR gebremst wird, wenn Top-of-Memory nach wenigen Stunden zu klein geworden ist.

(Dr. P. Kittels/bs)
0 rem save"@0:batch64",8:rem batch-verarbeitung auf c 64 , verwendet:
1 rem  edi.bas  zeilenorientierter ascii-text-editor fuer alle cbm-rechner
2 rem  von p. kittel , ffm 1985
4 goto200:             rem  cold start mit initialisierung
20 bj=8:bi=cs+1:ifbi>len(a$)thenbi=len(a$):ifbi=0thenbi=1
22 gosub28:cs=bi-1:ifb1<>13andbi<=mland((b1<>17)ork)then22
24 ifb1=13thenreturn
25 ifb1=17andk=0thenk=b:return
26 iflen(a$)>250thena$=left$(a$,len(a$)-1):ifbi>len(a$)thenbi=bi-1:print"{left}";
27 printbl$;:goto22
28 b1=0:bj$=mid$(a$,bi,1):bi$=mid$(a$,bi+1,1):ifbj$=""thenbj$=" "
29 if(asc(bj$)and127)=18thenbj$=chr$(asc("#")+(asc(bj$)and128))
30 getb$:ifb$<>""thenprint"{rvof}"bj$;:goto34
31 bj=(1+bj)and15:printchr$(18+16*(bjand8));bj$;
32 ifbj$=g$thenprintg$"{left}{rvof}";:ifbi<len(a$)andbi$<>g$thenprintbi$"{left}";
33 print"{left}";:return
34 ifbj$=g$thenprintg$"{left}";:ifbi<len(a$)andbi$<>g$thenprintbi$"{left}";
35 print"{left}";:b=asc(b$):b1=band127:ifb1>31then39
36 ifb1>12thenonb1-12goto74,38,38,38,38,87,76,60,38,38,38,38,38,38,38,38,46
37 rem 13:return,17:vert,18:rev,19:home,20:del,29:horiz
38 return
39 ifbi>mlthenprintbl$;:return
40 bi=bi+1:ifb=222thenb$=chr$(255)
41 printb$;:ifb$=g$thenprintg$"{left}";:ifbi<=len(a$)andbi$<>g$thenprintbi$"{left}";
42 ifbi>2thenb$=left$(a$,bi-2)+b$
43 b$=b$+mid$(a$,bi)
44 a$=b$:return
46 ifb=29then54
48 ifbi>1thenprintb$;:bi=bi-1
50 ifbi<2thenprintbl$;
52 return
54 ifbi>=mlthenprintbl$;:return
56 printb$;:bi=bi+1:iflen(a$)<bithena$=a$+" "
58 return
60 ifb=148then66
62 ifbi<2thenprintbl$;:return
63 printb$;:b$=mid$(a$,bi):ifbi>2thenb$=left$(a$,bi-2)+b$
64 a$=b$:bi=bi-1:return
66 l=len(a$):bj$=right$(a$,1):ifl>=mlthenprintbl$;:return
68 printb$" {left}";:b$=" "+mid$(a$,bi):ifbi>1thenb$=left$(a$,bi-1)+b$
72 a$=b$:return
74 print:ifb=13thenb=17:b1=b:bi=1:goto81
75 b=141:return
76 ifb=19thenprintleft$(cb$,bi-1);:bi=1:return
78 ifbi<len(a$)thenprintspc(len(a$)-bi);:bi=len(a$)
79 ifbi<mlandright$(a$,1)<>" "thenbi=bi+1:a$=a$+" ":print"{rght}";
80 return
81 ifm>=nthenreturn
82 b$=a$(m+1):ifb$=""thenreturn
83 ifmid$(b$,bi,1)=" "thenifbi<len(b$)thenbi=bi+1:goto83
84 ifmid$(b$,bi,1)=" "thenbi=1
85 return
87 bi=bi+1:ifbi>ml+1thenprintbl$;
88 printchr$(asc("#")+(band128));:goto42
90 print"lx (x = Zahl) = Loeschen  x Zeilen od.
91 print"ex (x = Zahl) = Einfuegen x Zeilen od.
92 print"h  fuer Hilfe oder":print"-  fuer Abbruch.
93 print"{down}In den Textzeilen:":print"Cursortasten und INST/DEL normal
94 print"Shift-Return  = zurueck zu Befehlszeile
95 print"Return        = naechster Zeilenanfang
96 print"Home          = aktueller Zeilenanfang
97 print"Shift-Home    = Zeilenende.
99 print"{down}Taste druecken.":fori=-1to0:geta$:i=a$="":next
100 k=0:print"{clr}":n=-n*(n>=0):g$=chr$(34):bl$=chr$(7)
101 print"{home}";tab(69);m-(m<0)+(m-n)*(m>n)
102 print"{home}aend/{rvon}l{rvof}oesch/{rvon}e{rvof}infueg/{rvon}h{rvof}ilfe, Ende mit - , ";
103 input"Zeilennr./Befehl(l./e./h) = ";a$:b$=left$(a$,1):ifb$="-"thenreturn
104 v=m:ifm<0thenv=0
105 b=val(mid$(a$,2)):ifb$="l"thenb=b+v-1:gosub185:m=v:goto100
106 m=val(a$):ifb$="e"then190
110 ifm<0orm>nthen100
111 print"{home}Cursor aktiv,  Return: naechste Zeile,  Kommandoz.:";
112 print" Shift-Return, Z.:"
113 es$="."+chr$(20)+left$(cb$,50):fori=1to39-40*c8:print"-";:next:print
114 ifb$="h"thenprint"{down}Befehlszeile:":print"zu aendernde Zeilennr. oder":goto90
118 i=4-6*c8:zv=m-i:zb=m+i+1:ifzv<0thenzv=0:zb=2*i+1
119 forj=zvtozb:ifj>nthena$="":goto122
120 a$=a$(j)
122 l=len(a$):ifl=0thenprintleft$(cp$,78)es$:goto128
124 forbi=1tol:b$=mid$(a$,bi,1):ifb$=g$thenprintg$;chr$(20);
125 if(asc(b$)and127)=18thenb$=chr$(asc("#")+(asc(b$)and128))
126 printb$;:next
127 printleft$(cp$,78-l);es$
128 next
130 print"{home}":fori=zvtom:print:next
155 a$=a$(m):l=len(a$):ifcs>l-1thencs=l-1:ifcs<0thencs=0
156 printspc(cs);
160 gosub20
161 iflen(a$)<2then169
162 ifright$(a$,1)=" "thena$=left$(a$,len(a$)-1):goto161
169 a$(m)=a$:ifk<=0then180
170 m=m+1+2*(k>20):ifm<zvorm>zbthen100
171 print"{home}"tab(69);m;"{left}   ":k=0:ifm>nthenn=m
172 goto130
180 ifa$(n)=""thenn=n-1:ifn>-1then180
182 goto100
185 ifv<0orv>borb>nthenprint"{down}Unmoeglich!":fori=1to200:next:return
186 m=b-v+1:ifb=nthen188
187 fori=b+1ton:a$(i-m)=a$(i):next
188 n=n-m:ifn<mzthenfori=n+1ton+m:a$(i)="":next:return
190 ifb+n>mzorb<1thenv=-1:gosub185:goto100
191 fori=ntovstep-1:a$(i+b)=a$(i):next
192 fori=vtov+b-1:a$(i)="":next:ifcs=0orcs>=len(a$(v+b))then199
193 a$(v)=left$(a$(v+b),cs):a$(v+b)=mid$(a$(v+b),cs+1)
199 n=n+b:m=v:goto100
200 rem initialisierung edi.bas: ---------------------------------------------
210 rem einfuehrung der benutzten variablen:
220 dim a$,b,b$,b1,bi,bj,bj$,g$,bi$,bl$,cb$,cp$,cs,es$,i,j,k,l,m,ml,mz,n,v,c8
221 dim zb,zv
230 mz=600: rem  maximale zeilenzahl
240 ml= 77: rem  max. zeichenzahl/zeile  ggf. per input (nur kleiner moeglich)
250 n = -1: rem  aktueller fuellstand in a$()
251 m = -1: rem  zuletzt edierte zeilennr.
262 cb$="{left}{left}{left}{left}":fori=1to5:cb$=cb$+cb$:next:cb$=cb$+left$(cb$,127):rem curs back
263 cp$="    ":fori=1to5:cp$=cp$+cp$:next:cp$=cp$+left$(cp$,127):rem space
270 dima$(mz) :rem  text zeilenweise
280 :          rem  editor mit gosub100 aufrufen
284 :          rem  test auf 40- bzw. 80-zeichen-schirm:
285 rem print"{home}{home}{clr}{swlc}"spc(40)"t{home}{down}";:open1,3:get#1,a$:close1:c8=a$=" ":rem s.u.
290 rem
299 rem edi.bas fertig -------------------------------------------------------
300 print"{up}{rght}{rght}";:dimp$(27),n%(27):np=0:open1,3:rem parameter holen
301 c=0:fori=2to79:get#1,a$:ifa$=":"thenc=i:i=80
302 next:ifc=0thenclose1:mp=-1:goto350
310 mp=0:forp=1to27:g$="":fg=1:fc=0
311 fori=-1to0:i=-1:get#1,a$:ifa$=chr$(34)thenfg=1-fg:goto320
312 c=c+1:ifc>79ora$=chr$(13)theni=0:p$(fc*p)=g$:mp=mp+fc*(p-mp):p=99:goto320
313 iffgthenifa$=","theni=0:p$(fc*p)=g$:mp=mp+fc*(p-mp):goto320
315 iffcor(a$<>" ")thenfc=1:g$=g$+a$
320 next:next:close1:ifmp=0then350
330 forp=1tomp:ifp$(p)=""then335
331 p$=p$(p):l=len(p$)
332 ifright$(p$,1)=" "thenl=l-1:p$=left$(p$,l):goto332
333 p$(p)=p$
335 p$(p-1)=p$(p):next:p$(mp)="":mp=mp-1
340 np=-1:forp=0tomp:ifp$(p)<>""thennp=p
341 next:mp=np:f$=p$(0):iff$=""thenf$="-"
349 rem zeile 285 hierher verlegt:
350 print"{home}{home}{clr}{swlc}"spc(40)"t{home}{down}";:open1,3:get#1,a$:close1:c8=a$=" ":rem 40/80 ?
351 print"{clr}{down} {rvon}{swlc} B{$a0}A{$a0}T{$a0}C{$a0}H{$a0}{rvof}{down}
352 fp=0:ifmp=0andf$<>"-"andf$<>""thenfp=1:goto511
353 ifmp<0then500
360 print"{down}{down}Parameter:":print"{down}File: "f$"{down}"
361 forp=1tomp:ifp$(p)<>""thenprint"   "chr$(p+64)": "p$(p)
362 next:goto510
500 print"{down}Namen fuer seq-Kommando-File eingeben,
502 print "wenn noch keines existiert: einfach  -
505 input"{down}Filename = ";f$
510 iff$="-"then520
511 print"{down}File wird eingelesen, bitte Geduld.{down}{down}{down}
512 n$=chr$(0):cr$=chr$(13):n=-1:open1,8,3,f$
513 forz=-1to0:g$="":fori=-1to0:get#1,a$:s=st:a$=left$(a$+n$,1)
514 i=(s=0)and(a$<>cr$):ifa$<>cr$theng$=g$+a$:ifa$="%"thenifmp>0thengosub1000
515 next:n=n+1:a$(n)=g$:printg$:z=s=0:next:close1:ifmp>0then520
516 iffpthen650
517 print"{down}{down}{down}Aenderungen noetig (j/n) ? ";
518 geta$:ifa$<>"j"anda$<>"n"then518
519 printa$:ifa$="n"then650
520 print"{down}File muss mit eingebautem Editor
521 print "be/er-arbeitet werden.
522 print "Geben Sie in der spaeteren Kommando-
523 print "zeile {rvon}h{rvof} fuer Hilfe ein.
524 print"{down}Hinweis: Mit diesem Editor koennen nur
525 print "         Standardzeichen, CR und RVS
526 print "         eingegeben werden, {rvon}keine{rvof}
527 print "         anderen Steuerzeichen!
528 print"{down}Alternative: File mit anderem reinen
529 print "         ASCII-Editor erzeugen.
530 print"{down}{down}Drive fuer File-Speicherung (0/1) ? ";
531 getd$:ifd$<>"0"andd$<>"1"then531
532 printd$:ifmp>0thenmp=0:goto550
540 gosub100
550 fa$=f$:print"{home}{home}{clr}{down}File-Inhalt ok (j/n) ? ";
551 geta$:ifa$<>"j"anda$<>"n"then551
552 printa$:ifa$="n"then540
560 input"{down}File-Name fuer Speicherung = ";f$:iff$="-"then560
570 ifnp>0theniff$=fa$thenprint"{down}Nicht Parameter-File ueberschreiben!":goto560
600 print"{down}File wird gespeichert, bitte Geduld.
610 open1,8,15,"s"+d$+":"+f$:close1:open1,8,3,(d$+":"+f$+",s,w")
620 fori=0ton:print#1,a$(i):next:close1
630 iflen(f$)<5orright$(f$,4)<>".mot"then650
640 print"{down}Bitte mit Parameterangabe neu starten.":end
650 m=0:fori=0ton:m=m+len(a$(i))+1:next
700 tr=55:rem plus/4: 55, 8xxx/40xx: 52
701 t=peek(tr)+256*peek(tr+1)-1:rem plus/4:  ift>32767thent=32767
702 th=int(t/256):tl=t-256*th
703 lh=int(m/256):ll=m-256*lh
704 b=t-m:bh=int(b/256):bl=b-256*bh
710 pa=bh:ifbl<122thenpa=pa-1
720 p=256*pa:pokep,tl:pokep+1,th:pokep+2,bl:pokep+3,bh:pokep+4,fp
721 l=len(f$):ifl>16thenl=16
722 fori=1tol:n%(i)=asc(mid$(f$,i,1)):next
730 pokep+5,l:fori=1tol:pokep+5+i,n%(i):next
740 poke55,0:poke56,pa
750 clr
800 a$="":i=0:n$=chr$(0)
805 tr=55:rem plus/4: 55, 8xxx/40xx: 52
810 m=peek(tr+1):p=256*m
815 tl=peek(p):th=peek(p+1):bl=peek(p+2):bh=peek(p+3):fp=peek(p+4)
820 l=peek(p+5):f$="":fori=1tol:f$=f$+chr$(peek(p+5+i)):next
830 t=tl+256*th
835 print"{down}File "f$" wird noch einmal
836 print"eingelesen, bitte Geduld.{down}
840 open1,8,3,f$:fori=-1to0:get#1,a$:i=st=0:poket,asc(a$+n$):t=t-1:next:close1
850 restore:readn
860 fori=0ton:reada:ifa<0thena=m
861 pokep+i,a:next
870 pokep+ 71,tl:pokep+ 72,th
871 pokep+118,bl:pokep+119,bh
900 print"{down}{down}Batch-Job mit    sys"p"    starten:
910 iffpthenprint:sysp:end
920 print"{down}{down}{down}sys"p"{up}{up}{up}"
999 end
1000 get#1,a$:s=st:a$=left$(a$+n$,1):a=asc(a$)
1010 forp=1tomp:ifa=p+64theng$=left$(g$,len(g$)-1)+p$(p):p=mp:a=-1
1011 next:ifa>-1theng$=g$+a$
1020 i=(s=0)and(a$<>cr$):return
6000 a=7*4096:forz=0to13:printa;"data";
6010 fori=0to7:pe=peek(a):a=a+1:ifi>0thenprint",";
6020 print" ";right$("00"+mid$(str$(pe),2),3);:next:print:next
6030 end
7000 restore:readn:a=28672
7010 fori=0ton:readp:ifabs(p)=112thenprintchr$(18-(p<0)*128);a+(iand248),
7020 next:end
8000 rem"  Benutzte Maschinenadressen:
8010 rem"  55-56    Pointer Top of RAM
8020 rem"  $0314    Pointer IRQ-Routine
8030 rem"  $0277    Erstes Byte Tastaturpuffer
8040 rem"  $c6      Anzahl Bytes im Tastaturpuffer
28600 rem  source-file:  irqbat.src
28666 data 119
28672 data 120, 173, 020, 003, 141, 116,-112, 173
28680 data 021, 003, 141, 117,-112, 169, 051, 141
28688 data 020, 003, 169,-112, 141, 021, 003, 088
28696 data 096, 189, 005, 001, 041, 252, 201, 044
28704 data 208, 017, 189, 006, 001, 201, 249, 208
28712 data 010, 169, 052, 157, 005, 001, 169, 249
28720 data 157, 006, 001, 165, 198, 240, 013, 201
28728 data 002, 176, 044, 173, 119, 002, 201, 003
28736 data 240, 037, 208, 047, 230, 198, 173, 255
28744 data 255, 141, 119, 002, 173, 071,-112, 208
28752 data 003, 206, 072,-112, 206, 071,-112, 173
28760 data 071,-112, 205, 118,-112, 208, 020, 173
28768 data 072,-112, 205, 119,-112, 208, 012, 173
28776 data 116,-112, 141, 020, 003, 173, 117,-112
28784 data 141, 021, 003, 076, 255, 255, 000, 000
Listing 1. Programm EDI.BAS/BATCH. Bitte mit dem Checksummer Seite 6 eingeben.
                        line

00002  0000              ;put"80:irqbat.src"
00003  0000              ;*
00004  0000              ;*********************************************************
00005  0000              ;*
00006  0000              ;* irq - bat
00007  0000              ;*
00008  0000              ;* batch-job-abwicklung ueber irq-routine
00009  0000              ;* version fuer 8xxx/40xx mit hinweisen fuer c 64, plus/4
00010  0000              ;*
00011  0000              ;* p. kittel, frankfurt 1985
00012  0000              ;*
00013  0000              ;*********************************************************
00014  0000              ;
00015  0000              irqptr = $fe90         ;pointer irq-routine (8xxx: $0090)
00016  0000                              ;                high-byte $fe=254 in datas korrigieren!
00017  0000                              ;                c-64: $0314,  plus/4: $0212
00018  0000                                   ;
00019  0000              tasanz = $9e           ;anzahl im tastaturpuffer (8xxx)
00020  0000                              ;                c-64: $c6,    plus/4: $ef
00021  0000                              ;
00022  0000              taspuf = $026f         ;tastaturpuffer (8xxx)
00023  0000                              ;                c-64: $0277,  plus/4: $0527
00024  0000                              ;
00025  0000              ;
00026  0000                     * = $7000
00027  7000              ;
00028  7000  78          aktiv  sei             ; batch-routine aktivieren
00029  7001  ad 90 fe           lda irqptr     ;alten pointer retten
00030  7004  8d 74 70           sta irqend+1
00031  7007  ad 91 fe           lda irqptr+1
00032  700a  8d 75 70           sta irqend+2
00033  700d                                    ;statt 'start' bei c-64 und plus/4    start1 :
00034  700d  a9 19              lda #<start    ;neuen setzen, bzw. start1
00035  700f  8d 90 fe           sta irqptr
00036  7012  a9 70              lda #>start    ;bzw. start1 (s.o.)
00037  7014  8d 91 fe           sta irqptr+1
00038  7017  58                 cli
00039  7018  60                 rts            ;fertig, gleich gehts los
00040  7019              ;
00041  7019              ;programmteil nur fuer cbm 8/4xxx benoetigt:
00042  7019  bd 05 01    start  lda $0105,x     ;i/o-ende-schleife?
00043  701c  29 fc              and #$fc       ;ruecksprungadr pruefen
00044  701e  c9 2c              cmp #$2c
00045  7020  d0 11              bne start1     ;ne: nein
00046  7022  bd 06 01           lda $0106,x
00047  7025  c9 f9              cmp #$f9
00048  7027  d0 0a              bne start1     ;ne: nein
00049  7029  a9 34              lda #$34       ;ruecksprungadr
00050  702b  9d 05 01           sta $0105,x    ;manipulieren
00051  702e  a9 f9              lda #$f9
00052  7030  9d 06 01           sta $0106,x
00053  7033              ;
00054  7033  a5 9e       start1 lda tasanz      ;tastenpuffer leer?
00055  7035  f0 0d              beq holtas     ;eq: ja, was dagegen tun
00056  7037  c9 02              cmp #2         ;mehr als eine taste?
00057  7039  b0 2c              bcs reset      ;cs: ja, abbruch wegen operator-eingriff
00058  703b              ;
00059  703b  ad 6f 02           lda taspuf     ;zuletzt gedrueckte taste
00060  703e  c9 03              cmp #3         ;stop-taste?
00061  7040  f0 25              beq reset      ;eq: ja, abbrechen
00062  7042  d0 2f              bne irqend     ;ne: einfach weiter

irqbat......page 0003

line# loc   code        line

00063  7044              ;
00064  7044  e6 9e       holtas inc tasanz      ;eine taste 'druecken'
00065  7046  ad ff ff    holptr lda $ffff       ;dummy-adresse wird modifiz.
00066  7049  8d 6f 02           sta taspuf     ;in tastaturpuffer
00067  704c  ad 47 70           lda holptr+1   ;low byte
00068  704f  d0 03              bne nocar      ;ne: kein uebertrag
00069  7051  ce 48 70           dec holptr+2   ;high byte
00070  7054  ce 47 70    nocar  dec holptr+1    ;naechstes byte
00071  7057              ;
00072  7057  ad 47 70           lda holptr+1   ;abfrage auf ende
00073  705a  cd 76 70           cmp endptr
00074  705d  d0 14              bne irqend     ;ne: nein
00075  705f  ad 48 70           lda holptr+2
00076  7062  cd 77 70           cmp endptr+1
00077  7065  d0 0c              bne irqend     ;ne: nein, weiter
00078  7067              ;
00079  7067  ad 74 70    reset  lda irqend+1    ;fertig, irq restaurieren
00080  706a  8d 90 fe           sta irqptr
00081  706d  ad 75 70           lda irqend+2
00082  7070  8d 91 fe           sta irqptr+1
00083  7073                                    ;
00084  7073  4c ff ff    irqend jmp $ffff       ;dummy-adresse wird modifiziert
00085  7076              ;
00086  7076  00          endptr .byte 0,0       ;hier pointer auf (letztes byte -1)
00086  7077  00
00087  7078              ;
00088  7078                     .end
Listing 2. Der Sourcecode für BATCH 64
PDF Diesen Artikel als PDF herunterladen
Mastodon Diesen Artikel auf Mastodon teilen
← Vorheriger ArtikelNächster Artikel →