Utilities - kleine, aber oft sehr hilfreiche Hilfsprogramme, gibt es viele, aber nicht immer sind diese auch brauch- oder leicht erweiterbar (weil z.B. kein Source-Code vorhanden ist). Bei diesem Utility ist beides gewährleistet: leichte Erweiterbarkeit (Assembler-Kenntnisse vorausgesetzt) und nützliche Funktionen für Spieler, Anwender und Programmierer.
Aufgerufen wird ST-Speed mit der Tastenkombination ALT-HELP. Das Utility selber besteht aus zwei Teilen: LADER und HAUPTPROGRAMM. Der Lader sorgt dafür, daß das Hauptprogramm resetresident im Speicher gehalten werden kann. Der Lader ist leider nicht auf meinem eigenen Mist gewachsen (warum sollte man das Rad auch ein zweites Mal erfinden?), sondern wurde [ 1 ] entnommen. Wer genau wissen möchte, wie dieser Lader funktioniert, sollte dort nachlesen. Für uns ist nur wichtig, daß das Hauptprogramm frei verschiebbar im Speicher sein muß.
Den Lader finden Sie im Listing 1. Die Konstante MYMAGIC = $10293847 sorgt dafür, daß das Hauptprogramm ST-SPEED auch nur einmal installiert wird. Im Listing 2 finden Sie den Grundaufbau des Utilities. Sie werden feststellen, daß einige Zeilen noch fehlen, d.h. Sie können zwar schon damit beginnen, das Listing abzutippen (stöhn...), funktionieren wird es aber erst ab Ende des dritten Teils. Am besten warten Sie mit dem Abtippen bis zum dritten Teil, denn wenn Sie einige Funktionen nicht brauchen, z.B. wenn Sie schon Ihre Lieblings-RAM-Disk haben, dann brauchen Sie die entsprechenden Zeilen im Source-Text natürlich nicht mit abzutippen.
In den ersten 100 Zeilen finden Sie zunächst einige Makros und Konstantendefinitionen. Jetzt wird es interessant: Es existieren zwei Einsprungadressen, die eine für den Lader, die andere fürs TOS. Ab Zeile 107 (Einsprung vom Lader aus) wird zunächst die Voreinstellung von Diskette geladen. Danach wird ST-SPEED in die VBL-Queue eingetragen, und alle Vektoren, die später verbogen werden, werden nach dem XBRA-Verfahren gesichert.
Die zweite Einsprungadresse (Zeilen 125 ff.) wird vom TOS bei jedem RESET benutzt. Hier sorgt man zunächst dafür, daß der Speicher, den ST-SPEED benutzt, nicht wieder ans GEMDOS zurückgegeben wird (ST-SPEED bleibt somit resident). Danach installiert man alle Vektoren, sofern benötigt (siehe Listing). Soll die RAM-Disk reset-resident sein, wird ab Zeile 164 dafür gesorgt, daß auch dieser Speicherbereich nicht wieder ans GEMDOS zurückgegeben wird. Achtung! Nach einem RESET läßt sich eine installierte Ramdisk nicht mehr aus dem System rausschmeißen. Das liegt daran, daß GEMDOS-Speicherbereiche nicht in beliebiger Reihenfolge wieder freigegeben werden können [2].
Die Hauptroutine (Zeilen 225 ff.) ist in der VBL-Queue des Rechners verankert und wird alle 1/50, 1/60 oder 1/71 Sekunde (je nach Videomodus) abgearbeitet. Falls der Computer verlangsamt werden soll, wird eine Warteschleife ausgeführt, weiterhin prüft man, ob die Tastenkombination ALT-HELP gedrückt wurde. Wenn dies der Fall war ($4ee.w enthält eine 0), erfolgt die Verzweigung zum Hauptmenü.
Im Hauptmenü findet zunächst eine Überprüfung statt, ob ein Menü überhaupt auf dem Bildschirm angezeigt werden soll. Das ist bei einigen Spielprogrammen erforderlich, da diese Shapes einen Interrupt ausgeben und ein Menü nur den Bildschirmaufbau durcheinander bringen würde.
In der Schleife ab Zeile 256 wird die gedrückte Taste ausgewertet und in ein entsprechendes Unterprogramm verzweigt. Wollen Sie eigene Routinen einfügen, gehen Sie wie folgt vor:
Innerhalb der Schleife fügen Sie die Zeilen
CMPI.B #'x',D0
(x = Kleinbuchstabe oder Zahl)
BEQ Unterprogramm
ein. Ein Unterprogramm hat nun folgenden Aufbau:
Falls der Bildschirm vor dem Ausführen der Routine restauriert werden muß und am Ende der Routine nicht zum Hauptmenü zurückgesprungen werden soll, z.B. bei einer Hardcopy-Routine:
Unterprogramm:
LEA menueflag(PC),A0
TST.W (A0)
BNE.S Up1
BSR hole_screen
Up1:
<... Ihre Routine ...>
BRA ende
Die Routine soll ausgeführt werden, und es soll zum Hauptmenü zurückgesprungen werden.
Unterprogramm:
<... Ihre Routine ...>
BRA menue
Das Unterprogramm benutzt den oberen Bildschirmbereich, der auch von ST-SPEED benutzt wird (12 Zeilen), für eigene Ausgaben. Das Unterprogramm darf nur ausgeführt werden, wenn auch eine Menüausgabe erfolgen darf.
Unterprogramm:
LEA menueflag(PC),A0
TST.W (A0)
BNE m_quit
BSR loesche_screen
<... Ihre Routine ...>
BRA menue
oder BRA ende
Zu den einzelnen Unterprogrammen in diesem Teil gibt es nicht mehr viel zu sagen, da sie ausreichend gut im Source-Text beschrieben sind.
Im zweiten Teil beschäftigen wir uns mit den RAM-Disk-Routinen, die es u.a. auch erlauben, die RAM-Disk schreibzuschützen. Weiterhin stelle ich Ihnen den XBRA-Lister vor.
[1] Zeitschrift c't, Ausgabe 6/89, „Residenter Wachhund“
[2] Atari-ST Profibuch, H.-D. Jankowski / J.F. Reschke / D. Rabich, Sybex Verlag
Taste | Beschreibung |
---|---|
0-9 | den Computer verlangsamen (klappt besonders gut in der mittleren und niedrigen Auflösung). Hiermit werden einige Spielprogramme einfacher zu spielen. |
A | die Anfangsmeldung ein- und ausschalten (manche Spielprogramme setzen Shapes innerhalb einer Interrupt-Routine auf dem Bildschirm. Damit es zu keinen Kollisionen zwischen ST-SPEED und dem Spielprogramm kommt, kann hiermit die Menümeldung ausgeschaltet werden. Wichtig! Es können jetzt nur noch folgende Funktionen aufgerufen werden: 0-9,A,C,H,P,R,Q,S,L). |
B | das Boot-Laufwerk ändern. Für alle Festplattenbesitzer besonders interessant, die von beliebigen Partitionen booten möchten (auch von einer reset-residenten RAM-Disk). |
C | schaltet zwischen 50 und 60 Hertz um. |
D | Einrichten einer RAM-Disk (auch reset-resident) |
I | gibt den freien Speicher, Informationen über den Schreibschutzstatus der Laufwerke und die Größe der installierten RAM-Disk aus. |
H | druckt eine Hardcopy |
P | Kalt-Start (RESET) (ST-Speed + RAM-Disk werden gelöscht) |
Q | Utility beenden |
R | Warmstart (RESET) (ST-Speed + RAM-Disk bleiben im Speicher) |
W | Hiermit kann man beliebige Laufwerke mit einem Schreibschutz versehen (auch die RAM-Disk). |
S | speichert aktuelle Informationen über: - Einschaltmeldung (A) - Schreibschutz (W) - Fileprotect (F) |
L | Lädt gespeicherte Informationen. Die Informationen werden auch beim ersten Programmstart geladen (z.B. bei dem Start aus dem AUTO-Ordner). |
X | Listet alle im Speicher vorhandenen XBRA-Programme auf (wichtig: Es werden nur Programme angezeigt, die Vektoren im Adreßbereich $8 - $1000 verbiegen). |
F | Man kann verhindern, daß Programme unerlaubt auf andere zugreifen (Virenschutz). Das ist mit FILEPROTECT möglich. Es gibt zwei Modi: Soft und Hard. Im Soft-Mode werden nur die Betriebssystemfunktionen Fcreate, Fopen (Schreiben und Lesen+Schreiben), Fdelete, im Hard-Mode zusätzlich Fopen (Lesen) und Pexec abgefangen. |
* Loader für ST-SPEED V1.x
*
* Ladeprogramm basiert auf c't - Lösung
* Ausgabe 6/89 „Residenter Wachhund"
*
mymagic: equ $10293847
output \st_speed.tos
lea $10000,a0
lea $70000,a1
ht_im0:
cmp.l #$12123456,(a0)
beq.s hier
n_hier:
lea 512(a0),a0
cmp.l a1,a0
ble.s ht_im0
bra.s insta
hier:
cmp.l 4(a0),a0
bne.s n_hier
cmp.l #mymagic,12(a0)
bne.s n_hier
termy:
clr.w -(sp)
trap #1
insta:
move.l #$10000,a0
lea tot_end(pc),a1
inst_g0:
cmp.l a0,a1
ble.s inst_g1
lea 512(a0),a0
bra.s inst_g0
inst_g1:
move.l a0,a5
lea t_inf(pc),a0
bsr pr_strg
clr.w -(sp)
pea t_datna(pc)
move.w #$3d,-(sp)
trap #1
addq.l #8,sp
move.w d0,d6
bmi fehler
addq.l #2,a5
f1_10:
move.w (a5),-2(a5)
moveq.l #2,d0
bsr.s fread
tst.l d0
bmi fehler
cmp.l #$12123456,-2(a5)
bne.s f1_10
addq.l #2,a5
move.l #80000,d0
bsr.s fread
tst.l d0
bmi fehler
subq.l #4,a5
move.w d6,-(sp)
move.w #62,-(sp)
trap #1
addq.l #4,sp
move.l a5,4(a5)
move.l a5,a0
clr.w d0
move.w #$ff,d1
itpol:
add.w (a0)+,d0
dbra d1,itpol
move.w #$5678,d1
sub.w d0,d1
move.w d1,10(a5)
jsr 16(a5)
move.l 4(sp),a1
sub.l a1,a0
clr.w -(sp)
move.l a0,-(sp)
move.w #$31,-(sp)
trap #1
fread:
move.l a5,-(sp)
move.l d0,-(sp)
move.w d6,-(sp)
move.w #63,-(sp)
trap #1
lea 12(sp),sp
rts
fehler:
lea t_nles(pc),a0
bsr.s pr_strg
move.w #7,-(sp)
trap #1
addq.l #2,sp
bra termy
pr_strg:
move.l a0,-(sp)
move.w #9,-(sp)
trap #1
addq.l #6,sp
rts
section data
t_datna: dc.b 'st_speed.bin',0
t_nles: dc.b 27,'E',13,10,' Diskerror ! *** Not installed *** ',0
t_inf: dc.b 27,'E',13,10
dc.b ' ST-SPEED Version 1.x installed.',13,10
dc.b 13,10
dc.b ' (c) MAXON Computer GmbH 1990',13,10
dc.b 0
even
tot_end: end
*
* "ST-SPEED" - (c) MAXON Computer GmbH 1990
*
* Programmcode muß verschiebbar sein!
* (deshalb LEA xxx(pc),Ax TST (Ax) !)
*
* Programm unterstützt XBRA-Methode
* Kennung: "SPxx". xx gibt Versionsnummer an.
*
* Geschrieben mit Devpac-ST V2.0 von HiSoft.
*
opt o+,p+ * Optimier, Abs.Code
zeilen: equ 12*16*80-1
etv_critic: equ $404 * Critical-Error-Hdlr
hdv_bpb: equ $472 * GETBPB-Vektor
hdv_rw: equ $476 * RWABS-Vektor
hdv_mediach: equ $47e * Mediach-Vektor
drvbits: equ $4c2 * Drvbits-Sysvar
_vblqueue: equ $456 * VBL-Liste
_dumpflg: equ $4ee * Hardcopy-Flag
_sysbase: equ $4f2
_bootdev.hi: equ $446
_bootdev.lo: equ $447
vbl_slot: equ 28 * VBL-Slot #7
kennung: equ 'SP10'
version: equ '1'
revision: equ '0'
output \st_speed.bin
PRINT: MACRO
pea \1
move.w #9,-(sp) * PRINT
trap #1
addq.l #6,sp
ENDM
SUP_EXEC: MACRO
pea \1
move.w #$26,-(sp) * SUP_EXEC
trap #14
addq.l #6,sp
ENDM
MALLOC: MACRO
move.l \1,-(sp)
move.w #$48,-(sp) * MALLOC
trap #1
addq.l #6,sp
ENDM
SETBLOCK: MACRO
move.l \1,-(sp)
move.l \2,-(sp)
clr.w -(sp)
move.w #$4a,-(sp) * SETBLOCK
trap #1
lea 12(sp),sp
ENDM
FCREATE: MACRO
clr.w -(sp) * Normale Datei
pea \1 * Dateiname
move.w #$3c,-(sp) * FCREATE
trap #1
addq.l #8,sp
ENDM
FWRITE: MACRO
pea \1 * Adresse
move.l \2,-(sp) * Bytes
move.w \3,-(sp)
move.w #$40,-(sp) * FWRITE
trap #1
lea $c(sp),sp
ENDM
FCLOSE: MACRO
move.w \1,-(sp)
move.w #$3e,-(sp) * FCLOSE
trap #1
addq.l #4,sp
ENDM
FOPEN: MACRO
clr.w -(sp) * Lesen
pea \1 * Dateiname
move.w #$3d,-(sp) * FOPEN
trap #1
addq.l #8,sp
ENDM
FREAD: MACRO
pea \1 * Save-Area
move.l \2,-(sp) * Bytes
move.w \3,-(sp)
move.w #$3f,-(sp) * FREAD
trap #1
lea $c(sp),sp
ENDM
REINS_VEC:MACRO
lea \1,a0 * Vector-Adr.
move.l \2,d0 * Alter Inhalt
bsr vector_reinstall
ENDM
progstart:dc.l $12123456 * TOS-MAGIC 1
dc.l 0 * TOS-ADRESS
bra.s res_mem * TOS-START
dc.w 0,$1029,$3847 * ALIGN + MY-MAGIC
********* Einsprung vom Lader aus
movem.l d0-d7/a0-a6,-(sp)
bsr m_load2 * Parms laden
SUP_EXEC installvec(pc) * Prg in VBL
SUP_EXEC initoldvec1(pc) * RAMDISK
SUP_EXEC initoldvec2(pc) * FILE-Prot
PRINT install(pc)
moveq.l #-1,d0
moveq.l #1,d1
njump: mulu #9999,d1
mulu #9999,d1
dbra d0,njump * Zeitverzög.
movem.l (sp)+,d0-d7/a0-a6
lea res_end(pc),a0
add.l #zeilen+l,a0 * Ende melden
rts
********* Programm in die VBL-QUEUE einbinden
* Einsprung vom TOS nach einem RESET
res_mem: movem.l d0-d7/a0-a6,-(sp)
MALLOC #80000 * Speicher res.
lea res_end(pc),a1
add.l #zeilen+1,a1 * berechnen und
move.l a1,d1 * verkleinern
sub.l d0,d1
SETBLOCK d1,d0 * schützen
bsr file_reinstall * alter Vektor!
lea fileflag(pc),a0 * Protect?
tst.w (a0)
beq.s res_mem1 * Nein...
bsr file_install * Vektoren
res_mem1: bsr ramdisk_vec_reinstall * RAMDISK-Vektoren reinstallieren!
bsr initoldvec1 * alte Vektoren
lea installflag(pc),a0
tst.w (a0)
beq no_ramdisk * keine da
lea resident(pc),a0
tst.w (a0)
bne.s resdisk * reset-resident!
lea installflag(pc),a0 * wenn nicht resident, dann
clr.w (a0) * Disk abmelden
move.l drvbits,d0 * Bit in Sysvar
clr.l d1 * löschen
move.w driveno(pc),d1
tst.w d1
beq.s no_ramdisk
bclr d1,d0
move.l d0,drvbits
bra.s no_ramdisk
resdiik: MALLOC #-1 * Ber. schützen
sub.l #30000,d0 * 30 kB
MALLOC d0
lea mfree(pc),a0
clr.l (a0) * Je. Reinst.
move.l puffer(pc),d1 * Adr. RAMDISK
add.l groesse(pc),d1 * +Größe
sub.l d0,d1 * - Blockanfang
SETBLOCK d1,d0
move.l drvbits,d0 * anmelden
clr.l d1
move.w driveno(pc),d1
bset d1,d0
move.l d0,drvbits
no_ramdisk:
movem.l (sp)+,d0-d7/a0-a6
installvec:
movem.l d0/a0/a2,-(sp)
lea start(pc),a2 * Start
move.l _vblqueue,a0 * Start VBLANK
move.l a2,vbl_slot(a0) * in VBL
move sr,-(sp) * Floppy aus
or.w #$700,sr
move.b #14,$ffff8800.w * Port A
move.b $ffff8800.w,d0 * aktuellen Wert holen
and.b #$f8,d0
or.b #5,d0 * LW A, Seite 0
move.b d0,$ffff8802.w * in Port A
move (sp)+,sr
movem.l (sp)+,d0/a0/a2
rts
initoldvec1:
lea o_bpb(pc),a0 * alter BPB
move.l hdv_bpb,(a0)
lea o_rw (pc),a0 * alter RW
move.l hdv_rw,(a0)
lea o_media(pc),a0 * alter MEDIA
move.l hdv_mediach,(a0)
lea mybpb(pc),a0 * Vektoren
move.l a0,hdv_bpb
lea myrwabs(pc),a0
move.l a0,hdv_rw
lea mymedia(pc),a0
move.l a0,hdv_mediach
rts
initoldvec2:
lea trap1_old(pc),a0 * alter TRAP-1-Vektor
move.l $84.w,(a0)
lea fileflag(pc),a0
tst.w (a0)
beq.s kein_fileprotect1 * kein Fileprotect
bsr file_install * Vektoren
bra.s initoldvecend
kein_fileprotect1:
bsr file_reinstall * Vektoren
initoldvecend:
rts
********* Anfang Hauptroutine
dc.b 'XBRA'
dc.l kennung
dc.l 0
start: move.l a0,-(sp)
lea speedflag(pc),a0
tst.w (a0) * verlangsamen?
bne.s speedwait * Ja...
timeout: move.l (sp)+,a0
tst.w $4ee.w * ALT+HELP?
beq.s haupt * Ja !
rts
speedwait:move.l d0,-(sp)
move.l speedtime(pc),d0
time1: nop
dbra d0,time1
move.l (sp)+,d0
bra.s timeout
********* ALT+HELP wurde gedrückt
haupt: lea menueflag(pc),a0
tst.w (a0) * Menü anzeigen
bne.s schleife * Nein
bsr maus_aus * Maus aus
bsr sichere_screen * Screen si.
menue: bsr loesche_screen * Screen lö.
PRINT text(pc) * Text ausgeben
schleife: bsr inkey * Tast.-Abfrage
bset #5,d0 * Nur Kleinb.
cmpi.b #'h',d0 * Hardcopy
beq m_hardcopy * drucken!
cmpi.b #'q',d0 * Zurück zum
beq.s m_quit * Programm
cmpi.b #' ',d0 * wie Q
beq.s m_quit
cmpi.b #'c',d0 * Synchronisatonl
beq m_sync * 50 <-> 60 Hz
cmpi.b #'a',d0 * Menümldg I/O
beq m_menueaa
cmpi.b #'p',d0 * RESET kalt
beq.s m_reset
cmpi.b #'r',d0 * RESET warm
beq m_reset1
cmpi.b #'d',d0 * RAMDISK
beq m_startram
cmpi.b #'b',d0 * BOOT-Device
beq m_bootdevice
cmpi.b #'w',d0 * WRITE-Prot
beq m_write
cmpi.b #'s',d0 * SAVE-Default
beq m_save
cmpi.b #'l',d0 * LOAD-Default
beq m_load
cmpi.b #'x',d0 * XBRA-List
beq m_xbra
cmpi.b #'i',d0 * Systeminfo
beq m_stspeed
cmpi.b #'f',d0 * File-Protect
beq m_file
cmpi.b #'0’,d0 * Tasten-Code>=0
bge.s speed * Ja !
notspeed: bra schleife
speed: cmpi.b #'9',d0 * Tasten-Code<=9
ble speed1 * Ja !
bra.s notspeed
********* Zurück zun Programm oder GEM—DESKTOP
m_quit: lea menueflag(pc),a0
tst.w (a0)
bne.s ende
bsr hole_screen * Screen zurück
ende: move.w #-1,_dumpflg * Hardcopy-Flag
lea menueflag(pc),a0
tst.w (a0)
bne.s ende1
bsr maus_an * Maus an
ende1: rts * Zurück
********* reset
m_reset: lea progstart(pc),a0 *Kill Magic
clr.l (a0)
REINS_VEC $84,trap1_old(pc) * TRAP-1
lea installflag(pc),a0 * RAMDISK
tst.w (a0)
beq.s m_reset1 * Nein...
bsr ramdisk_vec_reinstall
move.l drvbits,d0
clr.l d1
move.w driveno(pc),d1
tst.w d1
beq.s m_reset1
bclr d1,d0
move.l d0,drvbits
m_reset1: move.l _sysbase,a0 * in RESET-Vek.
jmp (a0)
********* Ausgabe einer Hardcopy
m_hardcopy:
lea menueflag(pc),a0
tst.w (a0)
bne.s hard1
bsr hole_screen
hard1: move.w #20,-(sp) * XBIOS 20
trap #14
addq.l #2,sp
bra.s ende
********* Synchronisation 50 <—> 60 Hz
m_sync: bchg.b #1,$ffff820a.w
bra menue
********* Verändern der Geschwindigkeit
speed1: cmpi.b #'0',d0
beq.s speednormal
clr.l d1
move.b d0,d1
sub.b #48,d1 * Taste 1 bis 9
mulu #1070,d1
lea speedtime(pc),a0
move.l d1,(a0)
lea speedflag(pc),a0
move.w #-1,(a0)
bra m_quit
speednormal:
lea speedflag(pc),a0
clr.w (a0)
lea speedtime(pc),a0
clr.l (a0)
bra m_quit
********* Menüflag invertieren
m_menueaa:lea menueflag(pc),a0
not.w (a0)
move.w #-1,_dumpflg
tst.w (a0)
beq ende1
bsr hole_screen
bsr maus_an
bra ende1
********* BOOT-Device
m_bootdevice:
lea menueflag(pc),a0
tst.w (a0)
bne m_quit
bsr loesche_screen
PRINT boottext(pc)
move.l drvbits,d0 * Drvbits holen
move.w #-1,d1 * Startwert, LW
ffdlp: addq.w #1,d1 * nächstes LW
cmp.w #16,d1 * schon 16?
beq.s fende * ja, Fehler
btst d1,d0 * LW inst.?
beq.s ffdlp
movem.l d0/d1,-(sp)
add.w #65,d1 * ASCII
move.w d1,-(sp) * Laufwerk
move.w #2,-(sp)
trap #1
addq.l #4,sp
PRINT spaces(pc)
movem.l (sp)+,d0/d1
bra.s ffdlp
fende: bsr inkey
bclr #5,d0
cmp.b #'Q',d0
beq menue
ext.w d0
sub.w #65,d0
move.l drvbits,d1
btst d0,d1
bne.s fok
bra.s fende
fok: move.b d0,_bootdev.hi * Laufwerk in LOW- und HIGH-Byte
move.b d0,_bootdev.lo * eintragen. Falls ein gepatchtes TOS
bra menue * verwendet wird, durch
* MOVE.W D0,_BOOTDEV.HI ersetzen
********* Systeminfo
m_stspeed:lea menueflag(pc),a0
tst.w (a0)
bne m_quit
bsr loesche_screen
PRINT st_speedl(pc) * Freier Spei.
MALLOC #-1
move.l d0, d1
lea freezahl(pc),a2
bsr binasc
PRINT freezahl(pc) * Memory
PRINT st_speed2(pc) * Drives
bsr show_protected
PRINT st_speed3(pc) * Massage
lea installflag(pc),a0 * Ramdisk vorhanden?
tst.w (a0)
bne memdisk * Ja...
PRINT line(pc)
bra.s st_jump
memdisk: move.l groesse(pc),d1
lea freezahl(pc),a2
bsr binasc
PRINT freezahl(pc)
st_jump: lea filepmode(pc),a0 * File-Prot.
move.b #'O',(a0)+ * = An
move.b #'N',(a0)+
move.b #' ',(a0)+
lea fileflag(pc),a1
tst.w (a1)
bna.s st_jump1
move.b #'F',-(a0) * Prot, aus
move.b #'F',-(a0)
st_jump1: PRINT fileptext(pc)
PRINT filetext1(pc)
PRINT fileptext1(pc)
bsr wait
bra menue
sens