VolksForth/sources/AtariST/RAMDISK.fth

443 lines
27 KiB
Forth
Raw Normal View History

\ *** Block No. 0 Hexblock 0
HOW TO USE THE RAMDISK bp 17Aug86
Die Ramdisk ist im Prinzip ein erweiterter Buffermechanismus,
der Buffer au<EFBFBD>erhalb des Forth-Systems verwaltet. Die Organi-
sation ist analog, mit der Ausnahme, da<EFBFBD> es kein Updateflag
gibt, ge<EFBFBD>nderte Bl<EFBFBD>cke also sofort auf die Diskette zur<EFBFBD>ckge-
schrieben werden. Die Benutzung ist v<EFBFBD>llig transparent, am
Anfang mu<EFBFBD> nur einmal INITRAMDISK aufgerufen werden.
Die Struktur der Buffer wird auf Screen 3 dargestellt.
Die Ramdisk allokiert ihren Speicher mit MALLOC.
\ *** Block No. 1 Hexblock 1
\ loadscreen for more buffers bp 17Aug86
\needs 2over include double.scr
Onlyforth
\needs 4dup : 4dup 2over 2over ;
\needs 4drop : 4drop 2drop 2drop ;
\needs user' : user' ' >body c@ ;
\needs d> : d> 2swap d< ;
2 $B +thru
1 +load \ patch ramdisk into system
\ *** Block No. 2 Hexblock 2
\ patch ramdisk into System bp 17Aug86
| : ((close ( fcb -- fcb ...) \ word for patch (CLOSE !!
dup flushramfile [ Dos ' (close >body @ , ] ;
| : (empty-buffers ( -- ...) \ word for patching EMPTY-BUFFE
emptyramdisk [ ' empty-buffers >body @ , ] ;
' ramdiskr/w is r/w
' ((close Dos ' (close >body !
' (empty-buffers ' empty-buffers >body !
save
initramdisk
\ *** Block No. 3 Hexblock 3
\ Variables and Constants bp 10Aug86
2Variable ramprev 0. ramprev 2! \ points to first buffer
2Variable ramfirst 0. ramfirst 2! \ start of buffer area
2Variable ramsize 0. ramsize 2! \ length of buffer area
$408 Constant b/rambuf
| Code link>file ( d1 -- d2 ) .l 4 SP ) addq
Label >next Next end-code
| Code link>block .l 6 SP ) addq >next bra end-code
| Code link>data .l 8 SP ) addq >next bra end-code
\\
structure of a buffer:
| link to next buffer | file | block | data .... |
+0 +4 +6 +8 +1032
\ *** Block No. 4 Hexblock 4
\ search for a buffer bp 24Aug86
\ D0:blk D1:file A0:bufadr A1:Vorgaenger
Label thisbuffer?
4 A0 D) D1 cmp 0= IF 6 A0 D) D0 cmp THEN rts
Code rambuf? ( blk file -- dadr tf \ blk file )
2 SP D) D0 move SP ) D1 move
.l ramprev r#) A0 move .w thisbuffer? bsr
0= IF Label blockfound .l 8. # A0 adda A0 SP ) move .w
true # SP -) move Next THEN
BEGIN .l A0 A1 move A1 ) A0 move 0. # A0 cmpa .w
0= IF false # SP -) move Next THEN
thisbuffer? bsr 0= UNTIL
.l A0 ) A1 ) move
ramprev r#) A0 ) move A0 ramprev r#) move .w
blockfound bra end-code
\ *** Block No. 5 Hexblock 5
\ read and write buffers b28sep86we
| : readrambuf ( adr daddr -- ) \ copy from daddr to adr
rot >absaddr b/blk lcmove ;
| : writerambuf ( adr daddr --) \ copy from adr to daddr
rot >absaddr 2swap b/blk lcmove ;
\ *** Block No. 6 Hexblock 6
\ search for empty buffer bp 10Aug86
\ : takerambuf ( -- daddr ) \ get last buffer
\ ramprev 2@
\ BEGIN 2dup link>file l@ 1+ ( empty buffer ? )
\ WHILE 2dup l2@ or ( last buffer ? )
\ WHILE l2@ REPEAT ;
| Code takerambuf ( -- daddr )
.l ramprev r#) A0 move
Label takeloop .w -1 4 A0 D) cmpi
0<> IF .l A0 ) tst 0<>
IF A0 ) A0 move takeloop bra THEN THEN
A0 SP -) move Next end-code
\ *** Block No. 7 Hexblock 7
\ allocate a buffer bp 24Aug86
| 2Variable (daddr
\ | : markrambuf ( blk file daddr -- daddr )
\ 2dup (daddr 2! link>file l! (daddr 2@ link>block l!
\ (daddr 2@ ;
| Code markrambuf ( blk file daddr -- daddr ) .l
SP )+ A0 move .w SP )+ 4 A0 D) move
SP )+ 6 A0 D) move .l A0 SP -) move Next end-code
| : makerambuf ( adr blk file -- ) \ create a buffer
BEGIN rambuf? 0= WHILE 2dup takerambuf markrambuf
2drop REPEAT writerambuf ;
\ *** Block No. 8 Hexblock 8
\ clear buffers bp 10Aug86
: clearrambuf ( laddr -- ) \ clear a buffer
link>file -1 -rot l! ;
: flushramfile ( fcb -- ) \ clear all buffers of a file
>r ramprev 2@
BEGIN 2dup or
WHILE 2dup link>file l@ r@ = IF 2dup clearrambuf THEN
l2@ REPEAT 2drop rdrop ;
\ *** Block No. 9 Hexblock 9
\ allocate all buffers bp 10Aug86
| : nextbuf ( d1 -- d2) \ adr of next buffer
b/rambuf extend d+ ;
| : ramfull? ( daddr -- f) \ true if more buffers
nextbuf ramsize 2@ ramfirst 2@ d+ d> 0= ;
: emptyramdisk ( -- ) \ initialize ramdisk
0. ramprev 2! ramfirst 2@
BEGIN 2dup ramfull?
WHILE 2dup clearrambuf ( clear buffer )
ramprev 2@ 2over l2! ( chain to list )
2dup ramprev 2! ( store last buffer )
nextbuf REPEAT 2drop ;
\ *** Block No. 10 Hexblock A
\ Interactive memory allocation bp 17Aug86
: #in ( -- n) query name number drop ;
: initramdisk ( -- )
[ Dos ] 0. ramprev 2!
ramfirst 2@ or IF ramfirst 2@ mfree
drop ?diskabort 0. ramfirst 2! THEN
cr ." Wie viele Kilos sollen es sein ? " #in
b/rambuf um* 2. d+ 2dup malloc ( 2 Angstbytes zus.)
dup 0< IF drop ?diskabort THEN ( Fehler !)
dup 0= abort" Speicher voll !!" ( DR sei Dank gesagt !)
ramfirst 2! ramsize 2!
emptyramdisk ;
\ *** Block No. 11 Hexblock B
\ new r/w bp 10Aug86
' r/w >body @ Alias oldr/w
: ramdiskr/w ( adr blk file rw/f -- f )
ramprev 2@ or 0= IF oldr/w exit THEN
dup >r
IF rambuf? IF readrambuf rdrop false exit THEN THEN
r> 4dup oldr/w
IF 4drop true exit THEN \ disk error !
drop makerambuf false ; \ create or overwrite buffer
\ *** Block No. 12 Hexblock C
\ print a list of ram buffers bp 10Aug86
: .rambufs ( -- )
ramprev 2@
BEGIN 2dup or
WHILE cr 2dup 8 d.r 5 spaces \ adress
2dup link>file l@
dup 1+ IF [ Dos ] .file 4 spaces
2dup link>block l@ 5 .r
ELSE drop ." empty" THEN
l2@ stop? UNTIL 2drop ;
\ *** Block No. 13 Hexblock D
\ Wichtige Worte sind bp 17Aug86
INITRAMDISK ( -- ) fragt nach der Zahl der Anzahl der
anzulegenden Buffer und erzeugt sie.
EMPTYRAMDISK ( -- ) l<EFBFBD>scht den Inhalt aller Buffer.
RAMBUF? ( blk file -- dadr tf \ blk file ff )
sucht den Buffer blk im File file in der Ramdisk.
CLEARRAMBUF? ( laddr -- )
markiert den Ramdiskbuffer bei Adr. laddr als leer.
..
\ *** Block No. 14 Hexblock E
bp 17Aug86
Wird in RAMDISKR\W benutzt
Gibt Offset einer Uservariablen in der Userarea. Dieses
Wort geh<EFBFBD>rt eigentlich in den Assembler !
\ *** Block No. 15 Hexblock F
bp 17Aug86
Dieses Wort wird in (CLOSE gepatched. FCB ist die Adresse des
zu schlie<EFBFBD>enden Files. Alle Blockpuffer dieses Files werden
gel<EFBFBD>scht.
Dieses Wort wird in EMPTY-BUFFERS gepatched. Es l<EFBFBD>scht alle
Ramdiskpuffer
Neues R/W
Patche (CLOSE
Patche EMPTY-BUFFERS
Frage nach der Gr<EFBFBD><EFBFBD>e der Ramdisk
\ *** Block No. 16 Hexblock 10
bp 17Aug86
Zeiger auf den ersten Buffer in der Ramdisk.
Beginn des f<EFBFBD>r die Ramdisk allokierten Speicherbereichs
L<EFBFBD>nge " " " " " "
L<EFBFBD>nge eines Buffers der Ramdisk
Diese Worte erlauben den Zugriff auf die Felder eines
Ramdiskbuffers.
Dies ist die Struktur eines Ramdiskbuffers. Alle Buffer befinden
sich in einer gelinkten Liste, analog zum volksFORTH83-Block=
=buffermechanismus.
\ *** Block No. 17 Hexblock 11
bp 17Aug86
Sucht einen Buffer in der Ramdisk. Gesucht wird der Buffer
mit der Nummer BLK aus dem File mit der Nummer FCB.
Zun<EFBFBD>chst wird der erste Eintrag untersucht (weniger Rechenzeit).
Ist es nicht der oberste, so werden die restlichen Buffer
verglichen. Wurde er gefunden, so wird der betreffende Buffer
an den Anfang der Liste geh<EFBFBD>ngt, so da<EFBFBD> die Buffer immer in
der Reihenfolge des Zugriffs geordnet sind. Dadurch wird die
Zugriffsgeschwindigkeit erh<EFBFBD>ht.
\ *** Block No. 18 Hexblock 12
bp 17Aug86
Kopiert den Inhalt des Ramdiskbuffers in den Blockbuffer des
volksFORTH-Systems
Kopiert den Inhalt des Blockbuffers im System in den Ramdisk=
=buffer.
Diese beiden Worte k<EFBFBD>nnen noch optimiert werden, da LCMOVE
byteweise <EFBFBD>bertr<EFBFBD>gt, aber auch langwortweise <EFBFBD>bertragen
werden kann.
\ *** Block No. 19 Hexblock 13
bp 17Aug86
Dieses Wort sucht einen leeren Ramdiskbuffer. Ist keiner leer,
so wird der letzte Buffer in der Liste genommen.
\ *** Block No. 20 Hexblock 14
bp 24Aug86
Hilfsvariable
Markiert den Ramdiskbuffer DADDR als Buffer f<EFBFBD>r den Block BLK
im File FILE.
Erzeugt einen Buffer f<EFBFBD>r den Blockl BLK des Files FILE in der
Ramdisk. Der Inhalt des Buffers steht ab Adresse ADR im System.
RAMBUF? wird benutzt, um den allokierten Buffer an die erste
Stelle zu h<EFBFBD>ngen. Der WHILE-Teil wird max. einmal durchlaufen !
\ *** Block No. 21 Hexblock 15
bp 17Aug86
L<EFBFBD>scht den Buffer LADDR.
L<EFBFBD>scht alle Ramdiskbuffer, die zum File FCB geh<EFBFBD>ren.
\ *** Block No. 22 Hexblock 16
bp 17Aug86
Berechnet die Adresse D2 des Ramdiskbuffers, der auf den Buffer
mit der Adresse D1 folgt.
F ist wahr, falls noch weitere Buffer in der Ramdisk allokiert
werden k<EFBFBD>nnen.
Initialisiert die Ramdisk. Es werden soviele Buffer angelegt,
wie in den durch RAMFIRST und RAMSIZE angegebenen Speicher=
=bereich passen. Alle allokierten Buffer werden als leer
markiert.
\ *** Block No. 23 Hexblock 17
bp 17Aug86
Liest eine Zahl von der Tastatur ein
Erzeugt die Ramdisk. Zun<EFBFBD>chst wird der alte Speicherbereich
freigegeben, falls einer allokiert war. Dann wird nach der
gew<EFBFBD>nschten Zahl von Buffern gefragt. Es wird ein Speicher=
=bereich vom GEM-Dos angeordert und mit leeren Buffern
gef<EFBFBD>llt.
\ *** Block No. 24 Hexblock 18
bp 17Aug86
Die alte R/W-Routine wird nat<EFBFBD>rlich auch ben<EFBFBD>tigt.
Kommuniziert mit den Massenspeichern.
RW/F ist wahr, falls ein Lesezugriff erfolgen soll.
Ist die Ramdisk leer, so darf sie nicht angesprochen werden !
Sonst wird gepr<EFBFBD>ft, ob es sich um einen Lesezugriff handelt
und ob der Buffer in der Ramdisk vorliegt. Ist das der Fall,
so wird einfach dessen Inhalt kopiert. Andernfalls mu<EFBFBD>, falls
noch nicht vorhanden, ein Buffer allokiert werden. Der Inhalt
des Systembuffers wird dann in die Ramdisk kopiert und steht
beim n<EFBFBD>chsten Lesezugriff zur Verf<EFBFBD>gung.
\ *** Block No. 25 Hexblock 19
bp 17Aug86
Es wird eine Liste mit dem Inhalt aller Ramdiskbuffer ausgegeben