This commit is contained in:
parent
e275156211
commit
1e16142429
|
@ -0,0 +1,7 @@
|
|||
|
||||
"Die Blütenträume
|
||||
Von Faltern, wie ich hörte,
|
||||
So lautlos wie sie -"
|
||||
Reikan
|
||||
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
"Die Blütenträume
|
||||
Von Faltern, wie ich hörte,
|
||||
So lautlos wie sie -"
|
||||
Reikan
|
||||
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
"Die Blütenträume
|
||||
Von Faltern, wie ich hörte,
|
||||
So lautlos wie sie -"
|
||||
Reikan
|
||||
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
Johann Wolfgang Goethe
|
||||
|
||||
Der Zauberlehrling
|
||||
|
||||
Hat der alte Hexenmeister
|
||||
Sich doch einmal wegbegeben!
|
||||
Und nun sollen seine Geister
|
||||
Auch nach meinem Willen leben!
|
||||
Seine Wort' und Werke
|
||||
Merkt' ich und den Brauch,
|
||||
Und mit Geistesstärke
|
||||
Tu' ich Wunder auch.
|
||||
|
||||
Walle! Walle
|
||||
Manche Strecke,
|
||||
Dass, zum Zwecke,
|
||||
Wasser fließe
|
||||
Und mit reichem, vollem Schwalle
|
||||
Zu dem Bade sich ergieße.
|
||||
|
||||
Und nun komm, du alter Besen!
|
||||
Nimm die schlechten Lumpenhüllen!
|
||||
Bist schon lange Knecht gewesen;
|
||||
Nun erfülle meinen Willen!
|
||||
Auf zwei Beinen stehe,
|
||||
Oben sei ein Kopf,
|
||||
Eile nun und gehe
|
||||
Mit dem Wassertopf!
|
||||
|
||||
Walle! Walle
|
||||
Manche Strecke,
|
||||
Dass, zum Zwecke,
|
||||
Wasser fließe
|
||||
Und mit reichem, vollem Schwalle
|
||||
Zu dem Bade sich ergieße.
|
||||
|
||||
Seht, er läuft zum Ufer nieder;
|
||||
Wahrlich! ist schon an dem Flusse,
|
||||
Und mit Blitzesschnelle wieder
|
||||
Ist er hier mit raschem Gusse.
|
||||
Schon zum zweiten Male!
|
||||
Wie das Becken schwillt!
|
||||
Wie sich jede Schale
|
||||
Voll mit Wasser füllt!
|
||||
|
||||
Stehe! Stehe!
|
||||
Denn wir haben
|
||||
Deiner Gaben
|
||||
Voll gemessen!
|
||||
Ach, ich merk' es! Wehe! Wehe!
|
||||
Hab' ich doch das Wort vergessen!
|
||||
|
||||
Ach, das Wort, worauf am Ende
|
||||
Er das wird, was er gewesen.
|
||||
Ach, er läuft und bringt behände!
|
||||
Wärst du doch der alte Besen!
|
||||
Immer neue Güsse
|
||||
Bringt er schnell herein,
|
||||
Ach! und hundert Flüsse
|
||||
Stürzen auf mich ein.
|
||||
|
||||
Nein, nicht länger
|
||||
Kann ich's lassen;
|
||||
Will ihn fassen.
|
||||
Das ist Tücke!
|
||||
Ach! nun wird mir immer bänger!
|
||||
Welche Miene! Welche Blicke!
|
||||
|
||||
Oh, du Ausgeburt der Hölle!
|
||||
Soll das ganze Haus ersaufen?
|
||||
Seh' ich über jede Schwelle
|
||||
Doch schon Wasserströme laufen.
|
||||
Ein verruchter Besen,
|
||||
Der nicht hören will!
|
||||
Stock, der du gewesen,
|
||||
Steh doch wieder still!
|
||||
|
||||
Willst's am Ende
|
||||
Gar nicht lassen?
|
||||
Will dich fassen,
|
||||
Will dich halten
|
||||
Und das alte Holz behände
|
||||
Mit dem scharfen Beile spalten.
|
||||
|
||||
Seht, da kommt er schleppend wieder!
|
||||
Wie ich mich nun auf dich werfe,
|
||||
Gleich, o Kobold, liegst du nieder;
|
||||
Krachend trifft die glatte Schärfe!
|
||||
Wahrlich, brav getroffen!
|
||||
Seht, er ist entzwei!
|
||||
Und nun kann ich hoffen
|
||||
Und ich atme frei!
|
||||
|
||||
Wehe! Wehe!
|
||||
Beide Teile
|
||||
Stehn in Eile
|
||||
Schon als Knechte
|
||||
Völlig fertig in die Höhe!
|
||||
Helft mir, ach! ihr hohen Mächte!
|
||||
|
||||
Und sie laufen! Nass und nässer
|
||||
Wird's im Saal und auf den Stufen.
|
||||
Welch entsetzliches Gewässer!
|
||||
Herr und Meister! Hör' mich rufen! -
|
||||
Ach, da kommt der Meister!
|
||||
Herr, die Not ist groß!
|
||||
Die ich rief, die Geister,
|
||||
Werd' ich nun nicht los.
|
||||
|
||||
In die Ecke,
|
||||
Besen! Besen!
|
||||
Seid's gewesen!
|
||||
Denn als Geister
|
||||
Ruft euch nur, zu seinem Zwecke,
|
||||
Erst hervor der alte Meister."
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,7 @@
|
|||
|
||||
"Die Blütenträume
|
||||
Von Faltern, wie ich hörte,
|
||||
So lautlos wie sie -"
|
||||
Reikan
|
||||
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
Johann Wolfgang Goethe
|
||||
|
||||
Der Zauberlehrling
|
||||
|
||||
Hat der alte Hexenmeister
|
||||
Sich doch einmal wegbegeben!
|
||||
Und nun sollen seine Geister
|
||||
Auch nach meinem Willen leben!
|
||||
Seine Wort' und Werke
|
||||
Merkt' ich und den Brauch,
|
||||
Und mit Geistesstärke
|
||||
Tu' ich Wunder auch.
|
||||
|
||||
Walle! Walle
|
||||
Manche Strecke,
|
||||
Dass, zum Zwecke,
|
||||
Wasser fließe
|
||||
Und mit reichem, vollem Schwalle
|
||||
Zu dem Bade sich ergieße.
|
||||
|
||||
Und nun komm, du alter Besen!
|
||||
Nimm die schlechten Lumpenhüllen!
|
||||
Bist schon lange Knecht gewesen;
|
||||
Nun erfülle meinen Willen!
|
||||
Auf zwei Beinen stehe,
|
||||
Oben sei ein Kopf,
|
||||
Eile nun und gehe
|
||||
Mit dem Wassertopf!
|
||||
|
||||
Walle! Walle
|
||||
Manche Strecke,
|
||||
Dass, zum Zwecke,
|
||||
Wasser fließe
|
||||
Und mit reichem, vollem Schwalle
|
||||
Zu dem Bade sich ergieße.
|
||||
|
||||
Seht, er läuft zum Ufer nieder;
|
||||
Wahrlich! ist schon an dem Flusse,
|
||||
Und mit Blitzesschnelle wieder
|
||||
Ist er hier mit raschem Gusse.
|
||||
Schon zum zweiten Male!
|
||||
Wie das Becken schwillt!
|
||||
Wie sich jede Schale
|
||||
Voll mit Wasser füllt!
|
||||
|
||||
Stehe! Stehe!
|
||||
Denn wir haben
|
||||
Deiner Gaben
|
||||
Voll gemessen!
|
||||
Ach, ich merk' es! Wehe! Wehe!
|
||||
Hab' ich doch das Wort vergessen!
|
||||
|
||||
Ach, das Wort, worauf am Ende
|
||||
Er das wird, was er gewesen.
|
||||
Ach, er läuft und bringt behände!
|
||||
Wärst du doch der alte Besen!
|
||||
Immer neue Güsse
|
||||
Bringt er schnell herein,
|
||||
Ach! und hundert Flüsse
|
||||
Stürzen auf mich ein.
|
||||
|
||||
Nein, nicht länger
|
||||
Kann ich's lassen;
|
||||
Will ihn fassen.
|
||||
Das ist Tücke!
|
||||
Ach! nun wird mir immer bänger!
|
||||
Welche Miene! Welche Blicke!
|
||||
|
||||
Oh, du Ausgeburt der Hölle!
|
||||
Soll das ganze Haus ersaufen?
|
||||
Seh' ich über jede Schwelle
|
||||
Doch schon Wasserströme laufen.
|
||||
Ein verruchter Besen,
|
||||
Der nicht hören will!
|
||||
Stock, der du gewesen,
|
||||
Steh doch wieder still!
|
||||
|
||||
Willst's am Ende
|
||||
Gar nicht lassen?
|
||||
Will dich fassen,
|
||||
Will dich halten
|
||||
Und das alte Holz behände
|
||||
Mit dem scharfen Beile spalten.
|
||||
|
||||
Seht, da kommt er schleppend wieder!
|
||||
Wie ich mich nun auf dich werfe,
|
||||
Gleich, o Kobold, liegst du nieder;
|
||||
Krachend trifft die glatte Schärfe!
|
||||
Wahrlich, brav getroffen!
|
||||
Seht, er ist entzwei!
|
||||
Und nun kann ich hoffen
|
||||
Und ich atme frei!
|
||||
|
||||
Wehe! Wehe!
|
||||
Beide Teile
|
||||
Stehn in Eile
|
||||
Schon als Knechte
|
||||
Völlig fertig in die Höhe!
|
||||
Helft mir, ach! ihr hohen Mächte!
|
||||
|
||||
Und sie laufen! Nass und nässer
|
||||
Wird's im Saal und auf den Stufen.
|
||||
Welch entsetzliches Gewässer!
|
||||
Herr und Meister! Hör' mich rufen! -
|
||||
Ach, da kommt der Meister!
|
||||
Herr, die Not ist groß!
|
||||
Die ich rief, die Geister,
|
||||
Werd' ich nun nicht los.
|
||||
|
||||
In die Ecke,
|
||||
Besen! Besen!
|
||||
Seid's gewesen!
|
||||
Denn als Geister
|
||||
Ruft euch nur, zu seinem Zwecke,
|
||||
Erst hervor der alte Meister."
|
|
@ -0,0 +1,3 @@
|
|||
0123456789
|
||||
0123456789
|
||||
0123456789
|
|
@ -1,711 +0,0 @@
|
|||
{{
|
||||
' fsrw.spin 1.6 Copyright 2008 Radical Eye Software
|
||||
'
|
||||
' See end of file for terms of use.
|
||||
'
|
||||
' This object provides FAT16 file read/write access on a block device.
|
||||
' Only one file open at a time. Open modes are 'r' (read), 'a' (append),
|
||||
' 'w' (write), and 'd' (delete). Only the root directory is supported.
|
||||
' No long filenames are supported. We also support traversing the
|
||||
' root directory.
|
||||
'
|
||||
' In general, negative return values are errors; positive return
|
||||
' values are success. Other than -1 on popen when the file does not
|
||||
' exist, all negative return values will be "aborted" rather than
|
||||
' returned.
|
||||
'
|
||||
' Changes:
|
||||
' v1.1 28 December 2006 Fixed offset for ctime
|
||||
' v1.2 29 December 2006 Made default block driver be fast one
|
||||
' v1.3 6 January 2007 Added some docs, and a faster asm
|
||||
' v1.4 4 February 2007 Rearranged vars to save memory;
|
||||
' eliminated need for adjacent pins;
|
||||
' reduced idle current consumption; added
|
||||
' sample code with abort code data
|
||||
' v1.5 7 April 2007 Fixed problem when directory is larger
|
||||
' than a cluster.
|
||||
' v1.6 23 September 2008 Fixed a bug found when mixing pputc
|
||||
' with pwrite. Also made the assembly
|
||||
' routines a bit more cautious.
|
||||
}}
|
||||
'
|
||||
' Constants describing FAT volumes.
|
||||
'
|
||||
con
|
||||
SECTORSIZE = 512
|
||||
SECTORSHIFT = 9
|
||||
DIRSIZE = 32
|
||||
DIRSHIFT = 5
|
||||
'
|
||||
' The object that provides the block-level access.
|
||||
'
|
||||
obj
|
||||
sdspi: "admflash-sdspiqasm"
|
||||
|
||||
var
|
||||
'
|
||||
'
|
||||
' Variables concerning the open file.
|
||||
'
|
||||
long fclust ' the current cluster number
|
||||
long filesize ' the total current size of the file
|
||||
long floc ' the seek position of the file
|
||||
long frem ' how many bytes remain in this cluster from this file
|
||||
long bufat ' where in the buffer our current character is
|
||||
long bufend ' the last valid character (read) or free position (write)
|
||||
long direntry ' the byte address of the directory entry (if open for write)
|
||||
long writelink ' the byte offset of the disk location to store a new cluster
|
||||
long fatptr ' the byte address of the most recently written fat entry
|
||||
|
||||
long fsize ' dateigröße
|
||||
long fattrib ' dateiattribute
|
||||
long ftime ' zeitstempel
|
||||
'
|
||||
' Variables used when mounting to describe the FAT layout of the card.
|
||||
'
|
||||
long rootdir ' the byte address of the start of the root directory
|
||||
long rootdirend ' the byte immediately following the root directory.
|
||||
long dataregion ' the start of the data region, offset by two sectors
|
||||
long clustershift ' log base 2 of blocks per cluster
|
||||
long fat1 ' the block address of the fat1 space
|
||||
long totclusters ' how many clusters in the volume
|
||||
long sectorsperfat ' how many sectors per fat
|
||||
'
|
||||
' Variables controlling the caching.
|
||||
'
|
||||
long lastread ' the block address of the buf2 contents
|
||||
long dirty ' nonzero if buf2 is dirty
|
||||
'
|
||||
' Buffering: two sector buffers. These two buffers must be longword
|
||||
' aligned! To ensure this, make sure they are the first byte variables
|
||||
' defined in this object.
|
||||
'
|
||||
byte buf[SECTORSIZE] ' main data buffer
|
||||
byte buf2[SECTORSIZE] ' main metadata buffer
|
||||
byte padname[11] ' filename buffer
|
||||
|
||||
CON { SEKTORINTERFACE
|
||||
das sektorinterface arbeitet mit zusammenhängenden containerdateien und ermöglicht einen wahlfreien
|
||||
zugriff auf die daten. die containerdatei werden mit dem entsprechenden tool auf einer leeren und
|
||||
frisch formatierten karte erzeugt.
|
||||
|
||||
}
|
||||
|
||||
PUB sec_start(strptr): s | err 'sec: startsektor einer containerdatei ermitteln
|
||||
{{ conainerdatei wird geöffnet und startsektor berechnet. die sektornummer wird zurückgeliefert;
|
||||
bei einem fehler der wert -1}}
|
||||
s~
|
||||
err := popen(strptr,"r") 'containerdatei öffnen
|
||||
ifnot err 'kein fehler bei öffnen des containers
|
||||
s := (fclust << clustershift) + dataregion 'startsektor berechnen
|
||||
pclose 'containerdatei schließen
|
||||
return s
|
||||
else
|
||||
return -1
|
||||
|
||||
' sequenz aus pfillbuf:
|
||||
' sdspi.readblock(datablock, @buf) 'cluster einlesen
|
||||
|
||||
' sequenz aus datablock:
|
||||
' return (fclust << clustershift) + dataregion + ((floc >> SECTORSHIFT) & ((1 << clustershift) - 1))
|
||||
|
||||
|
||||
PUB sec_readblock(secnr, badr)
|
||||
sdspi.readblock(secnr, badr)
|
||||
|
||||
PUB sec_writeblock(secnr, badr)
|
||||
sdspi.writeblock(secnr, badr)
|
||||
|
||||
|
||||
CON { FAT16-Code
|
||||
|
||||
}
|
||||
pri writeblock2(n, b)
|
||||
'
|
||||
' On metadata writes, if we are updating the FAT region, also update
|
||||
' the second FAT region.
|
||||
'
|
||||
sdspi.writeblock(n, b)
|
||||
if (n => fat1 and n < fat1 + sectorsperfat)
|
||||
sdspi.writeblock(n+sectorsperfat, b)
|
||||
|
||||
pri flushifdirty
|
||||
'
|
||||
' If the metadata block is dirty, write it out.
|
||||
'
|
||||
if (dirty)
|
||||
writeblock2(lastread, @buf2)
|
||||
dirty := 0
|
||||
|
||||
pri readblockc(n)
|
||||
'
|
||||
' Read a block into the metadata buffer, if that block is not already
|
||||
' there.
|
||||
'
|
||||
if (n <> lastread)
|
||||
flushifdirty
|
||||
sdspi.readblock(n, @buf2)
|
||||
lastread := n
|
||||
|
||||
pri brword(b)
|
||||
'
|
||||
' Read a byte-reversed word from a (possibly odd) address.
|
||||
'
|
||||
return (byte[b]) + ((byte[b][1]) << 8)
|
||||
|
||||
pri brlong(b)
|
||||
'
|
||||
' Read a byte-reversed long from a (possibly odd) address.
|
||||
'
|
||||
return brword(b) + (brword(b+2) << 16)
|
||||
|
||||
pri brwword(w, v)
|
||||
'
|
||||
' Write a byte-reversed word to a (possibly odd) address, and
|
||||
' mark the metadata buffer as dirty.
|
||||
'
|
||||
byte[w++] := v
|
||||
byte[w] := v >> 8
|
||||
dirty := 1
|
||||
|
||||
pri brwlong(w, v)
|
||||
'
|
||||
' Write a byte-reversed long to a (possibly odd) address, and
|
||||
' mark the metadata buffer as dirty.
|
||||
'
|
||||
brwword(w, v)
|
||||
brwword(w+2, v >> 16)
|
||||
|
||||
pub mount(basepin) | start, sectorspercluster, reserved, rootentries, sectors
|
||||
{{
|
||||
' Mount a volume. The address passed in is passed along to the block
|
||||
' layer; see the currently used block layer for documentation. If the
|
||||
' volume mounts, a 0 is returned, else abort is called.
|
||||
}}
|
||||
sdspi.start(basepin)
|
||||
lastread := -1
|
||||
dirty := 0
|
||||
sdspi.readblock(0, @buf)
|
||||
if (brlong(@buf+$36) == constant("F" + ("A" << 8) + ("T" << 16) + ("1" << 24)))
|
||||
start := 0
|
||||
else
|
||||
start := brlong(@buf+$1c6)
|
||||
sdspi.readblock(start, @buf)
|
||||
if (brlong(@buf+$36) <> constant("F" + ("A" << 8) + ("T" << 16) + ("1" << 24)) or buf[$3a] <> "6")
|
||||
return 1 ' not a fat16 volume
|
||||
if (brword(@buf+$0b) <> SECTORSIZE)
|
||||
return 2 ' bad bytes per sector
|
||||
sectorspercluster := buf[$0d]
|
||||
if (sectorspercluster & (sectorspercluster - 1))
|
||||
return 3 ' bad sectors per cluster
|
||||
clustershift := 0
|
||||
repeat while (sectorspercluster > 1)
|
||||
clustershift++
|
||||
sectorspercluster >>= 1
|
||||
sectorspercluster := 1 << clustershift
|
||||
reserved := brword(@buf+$0e)
|
||||
if (buf[$10] <> 2)
|
||||
return 4 ' not two FATs
|
||||
rootentries := brword(@buf+$11)
|
||||
sectors := brword(@buf+$13)
|
||||
if (sectors == 0)
|
||||
sectors := brlong(@buf+$20)
|
||||
sectorsperfat := brword(@buf+$16)
|
||||
if (brword(@buf+$1fe) <> $aa55)
|
||||
return 5 ' bad FAT signature
|
||||
fat1 := start + reserved
|
||||
rootdir := (fat1 + 2 * sectorsperfat) << SECTORSHIFT
|
||||
rootdirend := rootdir + (rootentries << DIRSHIFT)
|
||||
dataregion := 1 + ((rootdirend - 1) >> SECTORSHIFT) - 2 * sectorspercluster
|
||||
totclusters := ((sectors - dataregion + start) >> clustershift)
|
||||
if (totclusters > $fff0)
|
||||
return 6 ' too many clusters
|
||||
return 0
|
||||
|
||||
pri readbytec(byteloc)
|
||||
'
|
||||
' Read a byte address from the disk through the metadata buffer and
|
||||
' return a pointer to that location.
|
||||
'
|
||||
readblockc(byteloc >> SECTORSHIFT)
|
||||
return @buf2 + (byteloc & constant(SECTORSIZE - 1))
|
||||
|
||||
pri readfat(clust)
|
||||
'
|
||||
' Read a fat location and return a pointer to the location of that
|
||||
' entry.
|
||||
'
|
||||
fatptr := (fat1 << SECTORSHIFT) + (clust << 1)
|
||||
return readbytec(fatptr)
|
||||
|
||||
pri followchain | clust
|
||||
'
|
||||
' Follow the fat chain and update the writelink.
|
||||
'
|
||||
clust := brword(readfat(fclust))
|
||||
writelink := fatptr
|
||||
return clust
|
||||
|
||||
pri nextcluster | clust
|
||||
'
|
||||
' Read the next cluster and return it. Set up writelink to
|
||||
' point to the cluster we just read, for later updating. If the
|
||||
' cluster number is bad, return a negative number.
|
||||
'
|
||||
clust := followchain
|
||||
if (clust < 2 or clust => totclusters)
|
||||
abort(-9) ' bad cluster value
|
||||
return clust
|
||||
|
||||
pri freeclusters(clust) | bp
|
||||
'
|
||||
' Free an entire cluster chain. Used by remove and by overwrite.
|
||||
' Assumes the pointer has already been cleared/set to $ffff.
|
||||
'
|
||||
repeat while (clust < $fff0)
|
||||
if (clust < 2)
|
||||
abort(-26) ' bad cluster number")
|
||||
bp := readfat(clust)
|
||||
clust := brword(bp)
|
||||
brwword(bp, 0)
|
||||
flushifdirty
|
||||
|
||||
pri datablock
|
||||
'
|
||||
' Calculate the block address of the current data location.
|
||||
'
|
||||
return (fclust << clustershift) + dataregion + ((floc >> SECTORSHIFT) & ((1 << clustershift) - 1))
|
||||
|
||||
pri uc(c)
|
||||
'
|
||||
' Compute the upper case version of a character.
|
||||
'
|
||||
if ("a" =< c and c =< "z")
|
||||
return c - 32
|
||||
return c
|
||||
|
||||
pri pflushbuf(r, metadata) | cluststart, newcluster, count, i
|
||||
'
|
||||
' Flush the current buffer, if we are open for write. This may
|
||||
' allocate a new cluster if needed. If metadata is true, the
|
||||
' metadata is written through to disk including any FAT cluster
|
||||
' allocations and also the file size in the directory entry.
|
||||
'
|
||||
if (direntry == 0)
|
||||
abort(-27) ' not open for writing
|
||||
if (r > 0) ' must *not* allocate cluster if flushing an empty buffer
|
||||
if (frem < SECTORSIZE)
|
||||
' find a new clustercould be anywhere! If possible, stay on the
|
||||
' same page used for the last cluster.
|
||||
newcluster := -1
|
||||
cluststart := fclust & constant(!((SECTORSIZE >> 1) - 1))
|
||||
count := 2
|
||||
repeat
|
||||
readfat(cluststart)
|
||||
repeat i from 0 to constant(SECTORSIZE - 2) step 2
|
||||
if (buf2[i]==0 and buf2[i+1]==0)
|
||||
newcluster := cluststart + (i >> 1)
|
||||
if (newcluster => totclusters)
|
||||
newcluster := -1
|
||||
quit
|
||||
if (newcluster > 1)
|
||||
brwword(@buf2+i, -1)
|
||||
brwword(readbytec(writelink), newcluster)
|
||||
writelink := fatptr + i
|
||||
fclust := newcluster
|
||||
frem := SECTORSIZE << clustershift
|
||||
quit
|
||||
else
|
||||
cluststart += constant(SECTORSIZE >> 1)
|
||||
if (cluststart => totclusters)
|
||||
cluststart := 0
|
||||
count--
|
||||
if (count < 0)
|
||||
r := -5 ' No space left on device
|
||||
quit
|
||||
if (frem => SECTORSIZE)
|
||||
sdspi.writeblock(datablock, @buf)
|
||||
if (r == SECTORSIZE) ' full buffer, clear it
|
||||
floc += r
|
||||
frem -= r
|
||||
bufat := 0
|
||||
bufend := r
|
||||
else
|
||||
' not a full blockleave pointers alone
|
||||
if (r < 0 or metadata) ' update metadata even if error
|
||||
readblockc(direntry >> SECTORSHIFT) ' flushes unwritten FAT too
|
||||
brwlong(@buf2+(direntry & constant(SECTORSIZE-1))+28, floc+bufat)
|
||||
flushifdirty
|
||||
if (r < 0)
|
||||
abort(r)
|
||||
return r
|
||||
|
||||
pub pflush
|
||||
{{
|
||||
' Call flush with the current data buffer location, and the flush
|
||||
' metadata flag set.
|
||||
}}
|
||||
return pflushbuf(bufat, 1)
|
||||
|
||||
pri pfillbuf | r
|
||||
'
|
||||
' Get some data into an empty buffer. If no more data is available,
|
||||
' return -1. Otherwise return the number of bytes read into the
|
||||
' buffer.
|
||||
'
|
||||
if (floc => filesize)
|
||||
return -1
|
||||
if (frem == 0)
|
||||
fclust := nextcluster 'nächster cluster
|
||||
frem := SECTORSIZE << clustershift
|
||||
if (frem + floc > filesize)
|
||||
frem := filesize - floc
|
||||
sdspi.readblock(datablock, @buf) 'cluster einlesen
|
||||
r := SECTORSIZE
|
||||
if (floc + r => filesize)
|
||||
r := filesize - floc
|
||||
floc += r
|
||||
frem -= r
|
||||
bufat := 0
|
||||
bufend := r
|
||||
return r
|
||||
|
||||
pub pclose | r
|
||||
{{
|
||||
' Flush and close the currently open file if any. Also reset the
|
||||
' pointers to valid values. If there is no error, 0 will be returned.
|
||||
}}
|
||||
r := 0
|
||||
if (direntry)
|
||||
r := pflush
|
||||
bufat := 0
|
||||
bufend := 0
|
||||
filesize := 0
|
||||
floc := 0
|
||||
frem := 0
|
||||
writelink := 0
|
||||
direntry := 0
|
||||
fclust := 0
|
||||
return r
|
||||
|
||||
pri pdate
|
||||
{{
|
||||
' Get the current date and time, as a long, in the format required
|
||||
' by FAT16. Right now it"s hardwired to return the date this
|
||||
' software was created on (April 7, 2007). You can change this
|
||||
' to return a valid date/time if you have access to this data in
|
||||
' your setup.
|
||||
}}
|
||||
return constant(((2007-1980) << 25) + (1 << 21) + (7 << 16) + (4 << 11))
|
||||
|
||||
pub popen(s, mode) | i, sentinel, dirptr, freeentry
|
||||
{{
|
||||
' Close any currently open file, and open a new one with the given
|
||||
' file name and mode. Mode can be "r" "w" "a" or "d" (delete).
|
||||
' If the file is opened successfully, 0 will be returned. If the
|
||||
' file did not exist, and the mode was not "w" or "a", -1 will be
|
||||
' returned. Otherwise abort will be called with a negative error
|
||||
' code.
|
||||
'
|
||||
' s - zeiger auf string mit dateinamen
|
||||
' mode - r, w, a, d
|
||||
}}
|
||||
pclose
|
||||
' ----------------------------------------------------------- dateinamen aufbereiten
|
||||
i := 0
|
||||
repeat while (i<8 and byte[s] and byte[s] <> ".") 'kopiert dateinamen ohne extender
|
||||
padname[i++] := uc(byte[s++]) 'uc wandelt in kleinbuchstaben
|
||||
repeat while (i<8)
|
||||
padname[i++] := " "
|
||||
repeat while (byte[s] and byte[s] <> ".")
|
||||
s++
|
||||
if (byte[s] == ".")
|
||||
s++
|
||||
repeat while (i<11 and byte[s])
|
||||
padname[i++] := uc(byte[s++])
|
||||
repeat while (i < 11)
|
||||
padname[i++] := " "
|
||||
' ----------------------------------------------------------- datei im verzeichnis suchen
|
||||
sentinel := 0
|
||||
freeentry := 0
|
||||
repeat dirptr from rootdir to rootdirend - DIRSIZE step DIRSIZE
|
||||
s := readbytec(dirptr)
|
||||
if (freeentry == 0 and (byte[s] == 0 or byte[s] == $e5))
|
||||
freeentry := dirptr
|
||||
if (byte[s] == 0)
|
||||
sentinel := dirptr
|
||||
quit
|
||||
repeat i from 0 to 10 'vergleicht eintrag mit dateinamen
|
||||
if (padname[i] <> byte[s][i]) 'bei gleichheit i == 11
|
||||
quit
|
||||
if (i == 11 and 0 == (byte[s][$0b] & $18)) 'dateiname gefunden und kein verzeichnis/volume
|
||||
fclust := brword(s+$1a) 'startcluster der datei lesen und als aktuell setzen
|
||||
filesize := brlong(s+$1c) 'dateigröße der datei lesen
|
||||
fsize := filesize 'dateigröße der datei lesen
|
||||
|
||||
if (mode == "r") 'DATEI LESEN
|
||||
frem := SECTORSIZE << clustershift
|
||||
if (frem > filesize)
|
||||
frem := filesize
|
||||
return 0
|
||||
|
||||
if (byte[s][11] & $d9) ' datei ist schreibgeschützt
|
||||
abort(-6) ' no permission to write
|
||||
|
||||
if (mode == "d") 'DATEI LÖSCHEN
|
||||
brwword(s, $e5) 'verzeichniseintrag als gelöscht markieren
|
||||
freeclusters(fclust) 'cluster freigeben
|
||||
flushifdirty
|
||||
return 0
|
||||
|
||||
if (mode == "w") 'DATEI SCHREIBEN/ÜBERSCHREIBEN
|
||||
brwword(s+26, -1) 'bestehende clusterreferenz ungültig machen
|
||||
brwlong(s+28, 0) 'größe der neuen datei auf 0 setzen
|
||||
writelink := dirptr + 26
|
||||
direntry := dirptr
|
||||
freeclusters(fclust) 'bestehende clusterkette freigeben
|
||||
bufend := SECTORSIZE
|
||||
fclust := 0
|
||||
filesize := 0
|
||||
frem := 0
|
||||
return 0
|
||||
|
||||
elseif (mode == "a") 'DATEI ANHÄNGEN
|
||||
' this code will eventually be moved to seek
|
||||
frem := filesize
|
||||
freeentry := SECTORSIZE << clustershift 'freeentry = clustergröße in bytes
|
||||
if (fclust => $fff0)
|
||||
fclust := 0
|
||||
repeat while (frem > freeentry) 'bis zum letzten cluster springen
|
||||
if (fclust < 2)
|
||||
abort(-7) ' eof repeat while following chain
|
||||
fclust := nextcluster 'springe zum nächsten cluster
|
||||
frem -= freeentry 'berechne neue größe bis dateiende
|
||||
'in frem bleiben anzahl bytes im letzten cluster
|
||||
floc := filesize & constant(!(SECTORSIZE - 1)) 'sektornummer dateiende berechnen
|
||||
bufend := SECTORSIZE
|
||||
bufat := frem & constant(SECTORSIZE - 1)
|
||||
writelink := dirptr + 26
|
||||
direntry := dirptr
|
||||
if (bufat)
|
||||
sdspi.readblock(datablock, @buf)
|
||||
frem := freeentry - (floc & (freeentry - 1))
|
||||
else
|
||||
if (fclust < 2 or frem == freeentry)
|
||||
frem := 0
|
||||
else
|
||||
frem := freeentry - (floc & (freeentry - 1))
|
||||
if (fclust => 2)
|
||||
followchain
|
||||
return 0
|
||||
else
|
||||
abort(-3) ' bad argument
|
||||
|
||||
' ----------------------------------------------------------- datei nicht gefunden, neue datei erzeugen
|
||||
|
||||
if (mode <> "w" and mode <> "a")
|
||||
return -1 ' not found
|
||||
direntry := freeentry
|
||||
if (direntry == 0)
|
||||
abort(-2) ' no empty directory entry
|
||||
' write (or new append): create valid directory entry
|
||||
s := readbytec(direntry)
|
||||
bytefill(s, 0, DIRSIZE)
|
||||
bytemove(s, @padname, 11)
|
||||
brwword(s+26, -1)
|
||||
i := pdate
|
||||
brwlong(s+$e, i) ' write create time and date
|
||||
brwlong(s+$16, i) ' write last modified date and time
|
||||
if (direntry == sentinel and direntry + DIRSIZE < rootdirend)
|
||||
brwword(readbytec(direntry+DIRSIZE), 0)
|
||||
flushifdirty
|
||||
writelink := direntry + 26
|
||||
fclust := 0
|
||||
bufend := SECTORSIZE
|
||||
return 0
|
||||
|
||||
pub pseek(bytenr) | freeentry,dirptr 'setzt zeiger auf position
|
||||
{{
|
||||
- springt erst alle ganzen cluster weiter
|
||||
- restbytes im letzten cluster werden geladen
|
||||
|
||||
- code funktioniert nicht!!!
|
||||
}}
|
||||
|
||||
{{
|
||||
frem := bytenr
|
||||
freeentry := SECTORSIZE << clustershift 'freeentry = clustergröße in bytes
|
||||
if (fclust => $fff0)
|
||||
fclust := 0
|
||||
repeat while (frem > freeentry) 'bis zum cluster springen
|
||||
if (fclust < 2)
|
||||
abort(-7) 'eof repeat while following chain
|
||||
fclust := nextcluster 'springe zum nächsten cluster
|
||||
frem -= freeentry 'berechne neue größe bis dateiende
|
||||
'in frem bleiben anzahl bytes im letzten cluster
|
||||
floc := frem & constant(!(SECTORSIZE - 1)) 'sektornummer berechnen
|
||||
bufend := SECTORSIZE
|
||||
bufat := frem & constant(SECTORSIZE - 1) 'restbytes über clustergrenze berechnen
|
||||
writelink := dirptr + 26
|
||||
direntry := dirptr
|
||||
if (bufat)
|
||||
sdspi.readblock(datablock, @buf) 'restbytes einlesen in buf
|
||||
frem := freeentry - (floc & (freeentry - 1))
|
||||
else
|
||||
if (fclust < 2 or frem == freeentry)
|
||||
frem := 0
|
||||
else
|
||||
frem := freeentry - (floc & (freeentry - 1))
|
||||
if (fclust => 2)
|
||||
followchain
|
||||
return 0
|
||||
}}
|
||||
|
||||
|
||||
pub pread(ubuf, count) | r, t
|
||||
{{
|
||||
' Read count bytes into the buffer ubuf. Returns the number of bytes
|
||||
' successfully read, or a negative number if there is an error.
|
||||
' The buffer may be as large as you want.
|
||||
}}
|
||||
r := 0
|
||||
repeat while (count > 0)
|
||||
if (bufat => bufend)
|
||||
t := pfillbuf
|
||||
if (t =< 0)
|
||||
if (r > 0)
|
||||
return r
|
||||
return t
|
||||
t := bufend - bufat
|
||||
if (t > count)
|
||||
t := count
|
||||
bytemove(ubuf, @buf+bufat, t)
|
||||
bufat += t
|
||||
r += t
|
||||
ubuf += t
|
||||
count -= t
|
||||
return r
|
||||
|
||||
pub pgetc | t
|
||||
{{
|
||||
' Read and return a single character. If the end of file is
|
||||
' reached, -1 will be returned. If an error occurs, a negative
|
||||
' number will be returned.
|
||||
}}
|
||||
if (bufat => bufend)
|
||||
t := pfillbuf
|
||||
if (t =< 0)
|
||||
return -1
|
||||
return (buf[bufat++])
|
||||
|
||||
pub pwrite(ubuf, count) | r, t
|
||||
{{
|
||||
' Write count bytes from the buffer ubuf. Returns the number of bytes
|
||||
' successfully written, or a negative number if there is an error.
|
||||
' The buffer may be as large as you want.
|
||||
}}
|
||||
t := 0
|
||||
repeat while (count > 0)
|
||||
if (bufat => bufend)
|
||||
t := pflushbuf(bufat, 0)
|
||||
t := bufend - bufat
|
||||
if (t > count)
|
||||
t := count
|
||||
bytemove(@buf+bufat, ubuf, t)
|
||||
r += t
|
||||
bufat += t
|
||||
ubuf += t
|
||||
count -= t
|
||||
return t
|
||||
|
||||
pub pputc(c)
|
||||
{{
|
||||
' Write a single character into the file open for write. Returns
|
||||
' 0 if successful, or a negative number if some error occurred.
|
||||
}}
|
||||
if (bufat == SECTORSIZE) 'ist sectorende erreicht?
|
||||
pflushbuf(SECTORSIZE, 0)
|
||||
buf[bufat++] := c
|
||||
return 0
|
||||
|
||||
pub opendir | off
|
||||
{{
|
||||
' Close the currently open file, and set up the read buffer for
|
||||
' calls to nextfile.
|
||||
}}
|
||||
pclose
|
||||
off := rootdir - (dataregion << SECTORSHIFT)
|
||||
fclust := off >> (clustershift + SECTORSHIFT)
|
||||
floc := off - (fclust << (clustershift + SECTORSHIFT))
|
||||
frem := rootdirend - rootdir
|
||||
filesize := floc + frem
|
||||
return 0
|
||||
|
||||
pub nextfile(fbuf) | i, t, at, lns
|
||||
{{
|
||||
' Find the next file in the root directory and extract its
|
||||
' (8.3) name into fbuf. Fbuf must be sized to hold at least
|
||||
' 13 characters (8 + 1 + 3 + 1). If there is no next file,
|
||||
' -1 will be returned. If there is, 0 will be returned.
|
||||
}}
|
||||
repeat
|
||||
if (bufat => bufend)
|
||||
t := pfillbuf
|
||||
if (t < 0)
|
||||
return t
|
||||
if (((floc >> SECTORSHIFT) & ((1 << clustershift) - 1)) == 0)
|
||||
fclust++
|
||||
at := @buf + bufat
|
||||
|
||||
if (byte[at] == 0) 'verzeichnisende erreicht
|
||||
return -1
|
||||
|
||||
bufat += DIRSIZE
|
||||
if (byte[at] <> $e5 and (byte[at][$0b] & $18) == 0)
|
||||
fsize := brlong(at+$1c) 'dateigröße der datei lesen
|
||||
fattrib := byte[at][$0b] 'attribute setzen
|
||||
ftime := brlong(at+$0e) 'zeitstempel setzen
|
||||
lns := fbuf
|
||||
repeat i from 0 to 10
|
||||
byte[fbuf] := byte[at][i]
|
||||
fbuf++
|
||||
if (byte[at][i] <> " ")
|
||||
lns := fbuf
|
||||
if (i == 7 or i == 10)
|
||||
fbuf := lns
|
||||
if (i == 7)
|
||||
byte[fbuf] := "."
|
||||
fbuf++
|
||||
byte[fbuf] := 0
|
||||
return 0
|
||||
|
||||
pub getfsize 'dateigröße übergeben
|
||||
return fsize
|
||||
|
||||
pub getfattrib 'attribute übergeben
|
||||
return fattrib
|
||||
|
||||
pub getftime 'zeitstempel übergeben
|
||||
return ftime
|
||||
|
||||
|
||||
{{
|
||||
' Permission is hereby granted, free of charge, to any person obtaining
|
||||
' a copy of this software and associated documentation files
|
||||
' (the "Software"), to deal in the Software without restriction,
|
||||
' including without limitation the rights to use, copy, modify, merge,
|
||||
' publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
' and to permit persons to whom the Software is furnished to do so,
|
||||
' subject to the following conditions:
|
||||
'
|
||||
' The above copyright notice and this permission notice shall be included
|
||||
' in all copies or substantial portions of the Software.
|
||||
'
|
||||
' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
' EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
' MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
' IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
' CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
' TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
' SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
}}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue