1
0
mirror of https://github.com/dschmenk/PLASMA.git synced 2024-08-22 13:29:01 +00:00
This commit is contained in:
dschmenk 2016-08-16 13:15:17 -07:00
commit 92bbeb2c0a
17 changed files with 1328 additions and 28 deletions

View File

@ -200,7 +200,7 @@ Three tools are required to build and run this program: **acme**, **plasm**, and
```
./plasm -AM < hello.pla > hello.a
acme --setpc 4094 -o HELLO hello.a
acme --setpc 4094 -o HELLO#FE1000 hello.a
./plvm HELLO
```

3
src/inc/args.plh Normal file
View File

@ -0,0 +1,3 @@
import args
predef argFirst, argNext
end

View File

@ -1,25 +1,45 @@
import cmdsys
predef putc, putln, puts, getc, gets
predef call, syscall
predef heapmark, heapallocallign, heapalloc, heaprelease, heapavail
predef memset, memcpy
predef isugt, isuge, isult, isule
predef modload, modexec, modaddr
word MACHID, sysvars
//
// System flags: memory allocator screen holes.
//
const restxt1 = $0001
const restxt2 = $0002
const resxtxt1 = $0004
const resxtxt2 = $0008
const reshgr1 = $0010
const reshgr2 = $0020
const resxhgr1 = $0040
const resxhgr2 = $0080
//
// Module don't free memory
//
const modkeep = $2000
const modinitkeep = $4000
const MACHID_CLOCK = $01
const MACHID_80COL = $02
const MACHID_MEM = $03
const MACHID_48K = $10
const MACHID_64K = $20
const MACHID_128K = $30
const MACHID_MODEL = $C8
const MACHID_II = $00
const MACHID_IIPLUS= $40
const MACHID_IIE = $80
const MACHID_III = $C0
const MACHID_IIC = $88
const MACHID_I = $08
word MACHID
//
// System flags: memory allocator screen holes.
//
const restxt1 = $0001
const restxt2 = $0002
const resxtxt1 = $0004
const resxtxt2 = $0008
const reshgr1 = $0010
const reshgr2 = $0020
const resxhgr1 = $0040
const resxhgr2 = $0080
//
// Module don't free memory
//
const modkeep = $2000
const modinitkeep = $4000
//
// System vars
//
word sysvars
//
// CMD exported functions
//
predef putc, putln, puts, getc, gets
predef call, syscall
predef heapmark, heapallocalign, heapalloc, heaprelease, heapavail
predef memset, memcpy
predef isugt, isuge, isult, isule
predef modload, modexec, modaddr
end

36
src/inc/fileio.plh Normal file
View File

@ -0,0 +1,36 @@
import fileio
//
// Useful ProDOS values
//
// MACHID is defined in cmdsys.plh
// Which slot has a ROM
const SLTBYT = $BF99
// Prefix active
const PFIXPTR = $BF9A
// Memory alocate bitmap
const MEMTABL = $BF58
//
// ProDOS error codes
//
const PRODOS_ERR_OK = $00
const PRODOS_ERR_BAD_CALL_NUM = $01
const PRODOS_ERR_BAD_PARAM_CNT = $04
const PRODOS_ERR_INT_TBL_FULL = $25
const PRODOS_ERR_IO = $27
//
// System I/O buffer for PLASMA. Used when loading modules, free otherwise
//
const sysbuf = $0800
//
// File functions
//
predef getpfx, setpfx, open, close, read, write, create, destroy, newline
//
// Block level I/O functions
//
predef readblock, writeblock
//
// Globally accessible error code
//
byte perr
end

45
src/inc/sdfat.plh Normal file
View File

@ -0,0 +1,45 @@
//
// FAT I/O object
//
import sdFAT
//
// Open flags
//
const O_READ = $01
const O_WRITE = $02
const O_APPEND = $04
const O_SYNC = $08
const O_TRUNC = $10
const O_AT_END = $20
const O_CREAT = $40
const O_EXCL = $80
const MAX_FAT_BUF_SIZE = 512
//
// Interface
//
struc t_fatio
word dirGet
word dirSet
word dirNew
word dirRemove
word fileRename
word fileRemove
word fileExists
word fileOpenFirst
word fileOpenNext
word fileOpen
word fileClose
word fileRead
word fileWrite
word fileSync
word fileRewind
word fileSeek
word fileSeekOffset
word filePos
word fileSize
word fileTruncate
word fileIsDir
word fileIsFile
end
word sdFAT // sdFAT interface
end

6
src/inc/spiport.plh Normal file
View File

@ -0,0 +1,6 @@
import spiport
const SPI_SLAVE_READY = '@'
const SPI_SLAVE_ERROR = '!'
const SPI_SLAVE_BUSY = $FF
predef spiXferByte, spiSend, spiRecv, spiWriteBuf, spiReadBuf, spiDelay, spiReady
end

23
src/inc/wireio.plh Normal file
View File

@ -0,0 +1,23 @@
//
// Wiring constants for Arduino
//
const PINHIGH = 1
const PINLOW = 0
const PINOUTPUT = 1
const PININPUT = 0
const PINPULLUP = 2
//
// SPI commands to Wiring functions on Arduino
//
const CMDPINMODE = 3
const CMDDIGREAD = 4
const CMDDIGWRITE = 5
const CMDANAREAD = 6
const CMDANAWRITE = 7
//
// SPI commands to serial functions on Arduino
//
const CMDSERMODE = 8
const CMDSERAVAIL = 9
const CMDSERREAD = 10
const CMDSERWRITE = 11

34
src/libsrc/args.pla Normal file
View File

@ -0,0 +1,34 @@
include "inc/cmdsys.plh"
const cmdline = $01FF
def argDelim(str)
byte n
// Strip leading spaces
while ^str and ^(str + 1) == ' '
memcpy(str + 1, str + 2, ^str - 1)
^str--
loop
// Scan to trailing spaces (if any)
for n = 1 to ^str
if ^(str + n) <= ' '
^(str + n) = ^str - n
^str = n - 1
break
fin
next
return str
end
export def argNext(str)
str = str + ^str + 1
return argDelim(str)
end
export def argFirst
// NULL terminate command line
^(cmdline + ^cmdline + 1) = 0
return argDelim(cmdline)
end
done

119
src/libsrc/fileio.pla Normal file
View File

@ -0,0 +1,119 @@
include "inc/cmdsys.plh"
//
// ProDOS error code
//
export byte perr
//
// ProDOS routines
//
export def getpfx(path)
byte params[3]
^path = 0
params.0 = 1
params:1 = path
perr = syscall($C7, @params)
return path
end
export def setpfx(path)
byte params[3]
params.0 = 1
params:1 = path
perr = syscall($C6, @params)
return path
end
export def open(path, buf)
byte params[6]
params.0 = 3
params:1 = path
params:3 = buf
params.5 = 0
perr = syscall($C8, @params)
return params.5
end
export def close(refnum)
byte params[2]
params.0 = 1
params.1 = refnum
perr = syscall($CC, @params)
return perr
end
export def read(refnum, buf, len)
byte params[8]
params.0 = 4
params.1 = refnum
params:2 = buf
params:4 = len
params:6 = 0
perr = syscall($CA, @params)
return params:6
end
export def write(refnum, buf, len)
byte params[8]
params.0 = 4
params.1 = refnum
params:2 = buf
params:4 = len
params:6 = 0
perr = syscall($CB, @params)
return params:6
end
export def create(path, access, type, aux)
byte params[12]
params.0 = 7
params:1 = path
params.3 = access
params.4 = type
params:5 = aux
params.7 = $1
params:8 = 0
params:10 = 0
perr = syscall($C0, @params)
return perr
end
export def destroy(path)
byte params[3]
params.0 = 1
params:1 = path
perr = syscall($C1, @params)
return perr
end
export def newline(refnum, emask, nlchar)
byte params[4]
params.0 = 3
params.1 = refnum
params.2 = emask
params.3 = nlchar
perr = syscall($C9, @params)
return perr
end
export def readblock(unit, buf, block)
byte params[6]
params.0 = 3
params.1 = unit
params:2 = buf
params:4 = block
perr = syscall($80, @params)
return perr
end
export def writeblock(unit, buf, block)
byte params[6]
params.0 = 3
params.1 = unit
params:2 = buf
params:4 = block
perr = syscall($81, @params)
return perr
end
done

151
src/libsrc/sdfat.pla Normal file
View File

@ -0,0 +1,151 @@
include "inc/spiport.plh"
import cmdsys
predef call, putc, puts, putln
end
//
// FAT I/O object
//
predef cwd, chdir, mkdir, rmdir, rename, remove, exists, openFirst, openNext, open
predef close, read, write, sync, rewind, seek, seekOfs, pos
predef size, truncate, isDir, isFile
//
// SD card FAT filesystem interface
//
export byte[] sdFAT
word[] = @cwd, @chdir, @mkdir, @rmdir, @rename, @remove, @exists, @openFirst, @openNext, @open
word[] = @close, @read, @write, @sync, @rewind, @seek, @seekOfs, @pos
word[] = @size, @truncate, @isDir, @isFile
//
// Directory related functions
//
def cwd(pathname)
byte namelen
namelen = 0
spiSend(15) // CWD
namelen = spiRecv
if namelen
spiReadBuf(pathname+1, namelen)
fin
^pathname = namelen
return namelen
end
def chdir(path)
spiWriteBuf(path + 1, ^path)
spiSend(16) // CHGDIR
return spiRecv
end
def mkdir(path)
end
def rmdir(path)
end
def rename(newpath)
end
def remove
end
def exists(path)
end
def openDir(cmd, filename)
byte namelen
namelen = 0
spiSend(cmd)
namelen = spiRecv
if namelen == 0xFF
namelen = 0
fin
if namelen
spiReadBuf(filename+1, namelen)
fin
^filename = namelen
return namelen
end
def openFirst(filename) // return filename in buffer
return openDir(22, filename) // OPENFIRST
end
def openNext(filename) // return filename i buffer
return openDir(23, filename) // OPENNEXT
end
//
// File related functions
//
def open(path, mode)
spiWriteBuf(path + 1, ^path) // send filename
spiSend(21) // OPEN
spiSend(mode)
return spiRecv // status
end
def close
return spiSend(24) // CLOSE
end
def read(buf, len)
if len > 512
len = 512
fin
spiSend(25) // READ
spiSend(len >> 8); spiSend(len)
len = (spiRecv << 8) | spiRecv
if len > 0
spiReadBuf(buf, len)
fin
return len
end
def write(buf, len)
if len > 512
len = 512
fin
spiWriteBuf(buf, len)
spiSend(26) // WRITE
spiSend(len >> 8); spiSend(len)
len = (spiRecv << 8) | spiRecv
return len
end
def sync
end
def rewind
end
def seek
end
def seekOfs
end
def pos
end
def size
end
def truncate
end
def isDir
spiSend(35) // ISDIR
return spiRecv
end
def isFile
end
//
// Init SD card FAT filesystem
//
spiSend(14) // SDINIT
return spiReady <> 0 // Is Arduino READY?
done

249
src/libsrc/spiport.pla Normal file
View File

@ -0,0 +1,249 @@
import cmdsys
predef call, putc, puts, putln
end
//
// Bit banged spi over gameport
//
const SPI_SLAVE_READY = '@'
const SPI_SLAVE_ERROR = '!'
const SPI_SLAVE_BUSY = $FF
asm spiInc
!SOURCE "vmsrc/plvmzp.inc"
end
export asm spiXferByte(outbyte)
STA $C05A ; ENABLE SLAVE
LDY #0 ; ASSUME MSB IS ZERO
LDA ESTKL,X ; GET ARGUMENT
BPL + ; CHECK MSB
INY ; IT'S A ONE
+ STA $C058,Y ; WRITE BIT 7
STA $C040 ; CLOCK
LDY #0 ; DOING THIS HERE GIVES TIME FOR OUTPUT TO BECOME STABLE - NOT REALLY NEEDEDd
ASL $C061 ; READ BIT 7 INTO CARRY
ROL ; ROTATE INTO ACC
BPL + ; REPEAT FOR ALL BITS
INY
+ STA $C058,Y
STA $C040
LDY #0
ASL $C061
ROL
BPL +
INY
+ STA $C058,Y
STA $C040
LDY #0
ASL $C061
ROL
BPL +
INY
+ STA $C058,Y
STA $C040
LDY #0
ASL $C061
ROL
BPL +
INY
+ STA $C058,Y
STA $C040
LDY #0
ASL $C061
ROL
BPL +
INY
+ STA $C058,Y
STA $C040
LDY #0
ASL $C061
ROL
BPL +
INY
+ STA $C058,Y
STA $C040
LDY #0
ASL $C061
ROL
BPL +
INY
+ STA $C058,Y
STA $C040
NOP
ASL $C061
STA $C05B ; DISABLE SLAVE
ROL
STA ESTKL,X ; SAVE RETURN PARAMETER
RTS
end
asm spiReadBytes(buf, len)
LDA ESTKL+1,X
STA DSTL
LDA ESTKH+1,X
STA DSTH
LDA ESTKL,X
BEQ +
INC ESTKH,X
+ LDY #$00
- STA $C05A ; ENABLE SLAVE
STA $C040 ; CLOCK
NOP
ASL $C061 ; SHIFT IN ALL BITS STARTING WITH MSB
STA $C040
ROL
ASL $C061
STA $C040
ROL
ASL $C061
STA $C040
ROL
ASL $C061
STA $C040
ROL
ASL $C061
STA $C040
ROL
ASL $C061
STA $C040
ROL
ASL $C061
STA $C040
ROL
ASL $C061
STA $C05B ; DISABLE SLAVE
ROL
STA (DST),Y ; SAVE TO BUFFER
INY
BNE +
INC DSTH
+ DEC ESTKL,X
BNE -
DEC ESTKH,X
BNE -
INX ; REMOVE AN ARGUMENT
RTS
end
asm spiWriteBytes(buf, len)
LDA ESTKL+1,X
STA SRCL
LDA ESTKH+1,X
STA SRCH
LDA ESTKL,X
BEQ +
INC ESTKH,X
+
- STA $C05A ; ENABLE SLAVE
LDY #0 ; ASSUME MSB IS ZERO
LDA (SRC),Y ; GET BYTE
BPL + ; CHECK MSB
INY ; IT'S A ONE
+ STA $C058,Y ; WRITE BIT 7
STA $C040 ; CLOCK
LDY #0 ; DOING THIS HERE GIVES TIME FOR OUTPUT TO BECOME STABLE
ROL ; ROTATE NEXT BIT TO SEND
BPL + ; REPEAT FOR ALL BITS
INY
+ STA $C058,Y
STA $C040
LDY #0
ROL
BPL +
INY
+ STA $C058,Y
STA $C040
LDY #0
ROL
BPL +
INY
+ STA $C058,Y
STA $C040
LDY #0
ROL
BPL +
INY
+ STA $C058,Y
STA $C040
LDY #0
ROL
BPL +
INY
+ STA $C058,Y
STA $C040
LDY #0
ROL
BPL +
INY
+ STA $C058,Y
STA $C040
LDY #0
ROL
BPL +
INY
+ STA $C058,Y
STA $C040
STA $C05B ; DISABLE SLAVE
INC SRCL
BNE +
INC SRCH
+ DEC ESTKL,X
BNE -
DEC ESTKH,X
BNE -
INX ; REMOVE AN ARGUMENT
RTS
end
export def spiDelay(time)
return call($FCA8, time, 0, 0, 0) // DELAY
end
export def spiSend(data)
byte timeout, status
for timeout = 1 to 100 step 10
status = spiXferByte(data)
if status <> SPI_SLAVE_BUSY
return status
fin
spiDelay(timeout)
next
putc(status);putc('0'+data/10);putc('0'+data%10)
return status
end
export def spiRecv
return spiSend(0)
end
export def spiWriteBuf(buf, len)
spiSend(13) // CMD_BUF_WRITE
spiSend(len >> 8); spiSend(len)
return spiWriteBytes(buf, len)
end
export def spiReadBuf(buf, len)
spiSend(12) // CMD_BUF_READ
spiSend(len >> 8); spiSend(len)
return spiReadBytes(buf, len)
end
export def spiReady
byte timeout
timeout = 0xFF
while spiXferByte(0) <> SPI_SLAVE_READY and timeout // WAIT FOR READY
timeout--
spiDelay(10)
loop
return timeout
end
export def spiReset
^$C05B
return spiReady
end
return spiReset <> 0
done

View File

@ -9,6 +9,14 @@ ED = ED\#FF2000
SB = SB\#FF2000
ROD = ROD\#FE1000
SIEVE = SIEVE\#FE1000
ARGS = ARGS\#FE1000
SPIPORT = SPIPORT\#FE1000
SDFAT = SDFAT\#FE1000
FATCAT = FATCAT\#FE1000
FATGET = FATGET\#FE1000
FATWDSK = FATWRITEDSK\#FE1000
FATRDSK = FATREADDSK\#FE1000
FILEIO = FILEIO\#FE1000
WIZNET = WIZNET\#FE1000
UTHERNET2= UTHERNET2\#FE1000
UTHERNET= UTHERNET\#FE1000
@ -53,7 +61,7 @@ TXTTYPE = .TXT
#SYSTYPE = \#FF2000
#TXTTYPE = \#040000
all: $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03) $(CMD) $(MEMMGR) $(MEMTEST) $(FIBER) $(SB) $(MON) $(ROD) $(SIEVE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(ROGUEIO) $(HGR1) $(TONE) $(DGR) $(DGRTEST) $(PORTIO)
all: $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03) $(CMD) $(ARGS) $(MEMMGR) $(MEMTEST) $(FIBER) $(SB) $(MON) $(ROD) $(SIEVE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(ROGUEIO) $(HGR1) $(TONE) $(DGR) $(DGRTEST) $(FILEIO) $(PORTIO) $(SPIPORT) $(SDFAT) $(FATCAT) $(FATGET) $(FATWDSK) $(FATRDSK)
clean:
-rm *FE1000 *FF2000 $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03)
@ -110,6 +118,10 @@ $(SB): toolsrc/sb.pla $(PLVM02) $(PLASM) toolsrc/sb.pla
./$(PLASM) -A < toolsrc/sb.pla > toolsrc/sb.a
acme --setpc 8192 -o $(SB) toolsrc/sb.a
$(ARGS): libsrc/args.pla $(PLVM02) $(PLASM)
./$(PLASM) -AM < libsrc/args.pla > libsrc/args.a
acme --setpc 4094 -o $(ARGS) libsrc/args.a
$(MEMMGR): libsrc/memmgr.pla $(PLVM02) $(PLASM)
./$(PLASM) -AM < libsrc/memmgr.pla > libsrc/memmgr.a
acme --setpc 4094 -o $(MEMMGR) libsrc/memmgr.a
@ -158,10 +170,38 @@ $(HTTPD): samplesrc/httpd.pla $(PLVM02) $(PLASM)
./$(PLASM) -AM < samplesrc/httpd.pla > samplesrc/httpd.a
acme --setpc 4094 -o $(HTTPD) samplesrc/httpd.a
$(FILEIO): libsrc/fileio.pla $(PLVM02) $(PLASM)
./$(PLASM) -AM < libsrc/fileio.pla > libsrc/fileio.a
acme --setpc 4094 -o $(FILEIO) libsrc/fileio.a
$(TONE): libsrc/tone.pla $(PLVM02) $(PLASM)
./$(PLASM) -AM < libsrc/tone.pla > libsrc/tone.a
acme --setpc 4094 -o $(TONE) libsrc/tone.a
$(FATCAT): samplesrc/fatcat.pla $(PLVM02) $(PLASM)
./$(PLASM) -AM < samplesrc/fatcat.pla > samplesrc/fatcat.a
acme --setpc 4094 -o $(FATCAT) samplesrc/fatcat.a
$(FATGET): samplesrc/fatget.pla $(PLVM02) $(PLASM)
./$(PLASM) -AM < samplesrc/fatget.pla > samplesrc/fatget.a
acme --setpc 4094 -o $(FATGET) samplesrc/fatget.a
$(FATWDSK): samplesrc/fatwritedsk.pla $(PLVM02) $(PLASM)
./$(PLASM) -AM < samplesrc/fatwritedsk.pla > samplesrc/fatwritedsk.a
acme --setpc 4094 -o $(FATWDSK) samplesrc/fatwritedsk.a
$(FATRDSK): samplesrc/fatreaddsk.pla $(PLVM02) $(PLASM)
./$(PLASM) -AM < samplesrc/fatreaddsk.pla > samplesrc/fatreaddsk.a
acme --setpc 4094 -o $(FATRDSK) samplesrc/fatreaddsk.a
$(SDFAT): libsrc/sdfat.pla $(PLVM02) $(PLASM)
./$(PLASM) -AM < libsrc/sdfat.pla > libsrc/sdfat.a
acme --setpc 4094 -o $(SDFAT) libsrc/sdfat.a
$(SPIPORT): libsrc/spiport.pla $(PLVM02) $(PLASM)
./$(PLASM) -AM < libsrc/spiport.pla > libsrc/spiport.a
acme --setpc 4094 -o $(SPIPORT) libsrc/spiport.a
$(PORTIO): libsrc/portio.pla $(PLVM02) $(PLASM)
./$(PLASM) -AM < libsrc/portio.pla > libsrc/portio.a
acme --setpc 4094 -o $(PORTIO) libsrc/portio.a

49
src/samplesrc/fatcat.pla Normal file
View File

@ -0,0 +1,49 @@
include "inc/cmdsys.plh"
include "inc/args.plh"
include "inc/sdfat.plh"
word arg
byte[64] cwd
byte[64] pathname
def fatCat(path)
byte filename[32]
sdFAT:dirSet(path)
puts("Directory of "); puts(path); puts(":\n")
sdFAT:fileOpenFirst(@filename)
while filename
puts(" "); puts(@filename)
if sdFAT:fileIsDir(); putc('/'); fin
putln
sdFAT:fileClose()
sdFAT:fileOpenNext(@filename)
loop
end
sdFAT:dirGet(@cwd)
if cwd[cwd] <> '/' // append '/' to cwd if needed
cwd++
cwd[cwd] = '/'
fin
arg = argNext(argFirst)
if ^arg
while ^arg
if ^(arg + 1) <> '/' // relative path argument - append to cwd
memcpy(@pathname, @cwd, cwd + 1)
else
pathname = 0 // absolute path
fin
memcpy(@pathname + pathname + 1, arg + 1, ^arg) // append path argument
pathname = pathname + ^arg
if pathname[pathname] <> '/'
pathname++
pathname[pathname] = '/'
fin
fatCat(@pathname)
arg = argNext(arg)
loop
else
fatCat(@cwd)
fin
done

183
src/samplesrc/fatget.pla Normal file
View File

@ -0,0 +1,183 @@
include "inc/cmdsys.plh"
include "inc/fileio.plh"
include "inc/args.plh"
include "inc/sdfat.plh"
const COPY_BUF_SIZE = 8192 // 8K
const LOWER_DIFF = 'a' - 'A'
byte[17] proname
byte protype
word proaux
word arg
def putByte(val)
byte c
c = ((val >> 4) & $0F) + '0'
if c > '9'
c = c + 7
fin
putc(c)
c = (val & $0F) + '0'
if c > '9'
c = c + 7
fin
return putc(c)
end
def putWord(val)
putByte(val.1)
return putByte(val.0)
end
def charUpper(c)
if c >= 'a' and c <= 'z'
return c - LOWER_DIFF
fin
return c
end
def hexByte(hexChars)
byte lo, hi
lo = charUpper(^(hexChars + 1)) - '0'
if lo > 9
lo = lo - 7
fin
hi = charUpper(^hexChars) - '0'
if hi > 9
hi = hi - 7
fin
return (hi << 4) | lo
end
def hexWord(hexChars)
return (hexByte(hexChars) << 8) | hexByte(hexChars + 2)
end
def mkProName(fatName, proName, proType, proAux)
byte n, l
^proType = $02 // default to BIN
*proAux = $0000 // default to 0
//
// Check for CiderPress style extension
//
l = ^fatName
if l > 7 and ^(fatName + l - 6) == '#'
^proType = hexByte(fatName + l - 5)
*proAux = hexWord(fatName + l - 3)
l = l - 7
fin
//
// Scan backward looking for dir seperator
//
for n = l downto 1
if ^(fatName + n) == '/'
break
fin
next
if l - n > 15
l = n + 15
fin
memcpy(proName + 1, fatName + 1 + n, l - n)
^proName = l - n
end
def getYN(prompt)
byte yn
puts(prompt)
yn = getc
return yn == 'Y' or yn == 'y'
end
def bigFatRead(buf, len)
word xferLen, fatLen
xferLen = 0
repeat
if len > MAX_FAT_BUF_SIZE
fatLen = MAX_FAT_BUF_SIZE
else
fatLen = len
fin
fatLen = sdFAT:fileRead(buf, fatLen)
if fatLen > 0 and fatLen <= 512
xferLen = xferLen + fatLen
len = len - fatLen
buf = buf + fatLen
else
len = 0
fin
until len == 0
return xferLen
end
def fatCopyFrom(src, dst, type, aux)
word copyBuf, copyLen, freeAddr
byte ref
copyBuf = heapallocalign(COPY_BUF_SIZE, 8, @freeAddr)
if not copyBuf
puts("Not enough free memory!\n"); putln
return -1
fin
//
// Check if dst already exists
//
ref = open(dst, sysbuf)
if ref
close(ref)
puts("Overwrite "); puts(dst)
if not getYN("(Y/N)?")
heaprelease(freeAddr)
return -1
fin
putln
destroy(dst)
fin
//
// Create dst file
//
if create(dst, $C3, type, aux)
puts("Create file error: "); putByte(perr); putln
fin
ref = open(dst, sysbuf)
if not ref
puts("Error opening file: "); puts(dst); putln
puts("Open file error: "); putByte(perr); putln
return -1
fin
//
// Copy FAT file over in big chunks
//
if sdFAT:fileOpen(src, O_READ)
repeat
copyLen = bigFatRead(copyBuf, COPY_BUF_SIZE)
if copyLen
if write(ref, copyBuf, copyLen) <> copyLen
puts("Error writing file:"); puts(dst); putln
puts("Write file error: "); putByte(perr); putln
copyLen = 0 // Force end of copy
fin
fin
until copyLen == 0
sdFAT:fileClose()
else
puts("Error opening FAT file:"); puts(src); putln
fin
close(ref)
heaprelease(freeAddr)
end
arg = argNext(argFirst)
if ^arg
mkProName(arg, @proname, @protype, @proaux)
puts(arg);puts("==>");puts(@proname)
putc(' ');putByte(protype);putc(',');putWord(proaux);putln
fatCopyFrom(arg, @proname, protype, proaux)
else
puts("Usage: +FATGET <FAT filename>"); putln
fin
done

View File

@ -0,0 +1,170 @@
include "inc/cmdsys.plh"
include "inc/fileio.plh"
include "inc/args.plh"
include "inc/sdfat.plh"
const COPY_BUF_SIZE = 4096 // 4K
const COPY_BLK_SIZE = COPY_BUF_SIZE/512
const COPY_BLK_CNT = COPY_BLK_SIZE-1
const DRIVE1 = $60 // drive 1, slot 6
const DRIVE2 = $D0 // drive 2, slot 6
const LOWER_DIFF = 'a' - 'A'
word arg, image
byte unit = DRIVE1
def putb(b)
byte c
c = ((b >> 4) & $0F) + '0'
if c > '9'
c = c + 7
fin
putc(c)
c = (b & $0F) + '0'
if c > '9'
c = c + 7
fin
return putc(c)
end
def puti(i)
word tt, th, h, t
byte p
p =0
if i < 0
putc('-')
i = -i
fin
tt = i / 10000
i = i % 10000
th = i / 1000
i = i % 1000
h = i / 100
i = i % 100
t = i / 10
i = i % 10
if tt > 0
putc(tt + '0'); p = 1
fin
if p or th > 0
putc(th + '0'); p = 1
fin
if p or h > 0
putc(h + '0'); p = 1
fin
if p or t > 0
putc(t + '0'); p = 1
fin
return putc(i + '0')
end
def charUpper(c)
if c >= 'a' and c <= 'z'
return c - LOWER_DIFF
fin
return c
end
def getYN(prompt)
byte yn
puts(prompt)
yn = getc
putln
return yn == 'Y' or yn == 'y'
end
def bigFatWrite(buf, len)
word xferLen, fatLen
xferLen = 0
repeat
if len > MAX_FAT_BUF_SIZE
fatLen = MAX_FAT_BUF_SIZE
else
fatLen = len
fin
fatLen = sdFAT:fileWrite(buf, fatLen)
if fatLen > 0
xferLen = xferLen + fatLen
len = len - fatLen
buf = buf + fatLen
else
len = 0
fin
until len == 0
return xferLen
end
def fatReadImage(src, drv)
word copyBuf, copyLen, freeAddr
word blocknum, bufblk
copyBuf = heapallocalign(COPY_BUF_SIZE, 8, @freeAddr)
if not copyBuf
puts("Not enough free memory!\n"); putln
return -1
fin
//
// Copy FAT image over one track at a time
//
if sdFAT:fileOpen(src, O_READ | O_WRITE | O_CREAT)
if !drv; putc(7); fin
for blocknum = 0 to 279 step COPY_BLK_SIZE
if drv
^$24=^$20 // Move cursor to left edge
puts("Reading blocks: "); puti(blocknum)
for bufblk = 0 to COPY_BLK_CNT
if readblock(drv, copyBuf + (bufblk << 9), blocknum + bufblk)
puts("Read disk error: $"); putb(perr); putln
break
fin
next
fin
copyLen = bigFatWrite(copyBuf, COPY_BUF_SIZE)
if copyLen <> COPY_BUF_SIZE
puts("Write image file error\n");
fin
if copyLen < COPY_BUF_SIZE or perr
puts("Error creating image: "); puts(src); putln
break
fin
next
if !drv; putc(7);fin
putln
sdFAT:fileClose()
else
puts("Error opening image file:"); puts(src); putln
fin
heaprelease(freeAddr)
end
arg = argNext(argFirst)
if ^arg
image = arg
arg = argNext(arg)
if ^arg
when ^(arg + 1)
is '2' // Drive 2 option
unit = DRIVE2
break
is 'T' // Test speed option
is 't'
unit = 0
break
wend
fin
if unit
puts("Reading "); puts(image); puts(" from Drive "); putc((unit >> 7) + '1')
else
puts("Speed test writing 143K to SD card");
fin
if getYN("\nContinue? (Y/N)")
fatReadImage(image, unit)
fin
else
puts("Read DSK image from floppy disk drive\n")
puts("Usage: +FATREADDSK <DSK image file> [1,2,T]\n")
fin
done

View File

@ -0,0 +1,171 @@
include "inc/cmdsys.plh"
include "inc/fileio.plh"
include "inc/args.plh"
include "inc/sdfat.plh"
const COPY_BUF_SIZE = 4096 // 4K
const COPY_BLK_SIZE = COPY_BUF_SIZE/512
const COPY_BLK_CNT = COPY_BLK_SIZE-1
const DRIVE1 = $60 // drive 1, slot 6
const DRIVE2 = $D0 // drive 2, slot 6
const LOWER_DIFF = 'a' - 'A'
word arg, image
byte unit = DRIVE1
def putb(b)
byte c
c = ((b >> 4) & $0F) + '0'
if c > '9'
c = c + 7
fin
putc(c)
c = (b & $0F) + '0'
if c > '9'
c = c + 7
fin
return putc(c)
end
def puti(i)
word tt, th, h, t
byte p
p =0
if i < 0
putc('-')
i = -i
fin
tt = i / 10000
i = i % 10000
th = i / 1000
i = i % 1000
h = i / 100
i = i % 100
t = i / 10
i = i % 10
if tt > 0
putc(tt + '0'); p = 1
fin
if p or th > 0
putc(th + '0'); p = 1
fin
if p or h > 0
putc(h + '0'); p = 1
fin
if p or t > 0
putc(t + '0'); p = 1
fin
return putc(i + '0')
end
def charUpper(c)
if c >= 'a' and c <= 'z'
return c - LOWER_DIFF
fin
return c
end
def getYN(prompt)
byte yn
puts(prompt)
yn = getc
putln
return yn == 'Y' or yn == 'y'
end
def bigFatRead(buf, len)
word xferLen, fatLen
xferLen = 0
repeat
if len > MAX_FAT_BUF_SIZE
fatLen = MAX_FAT_BUF_SIZE
else
fatLen = len
fin
fatLen = sdFAT:fileRead(buf, fatLen)
if fatLen > 0
xferLen = xferLen + fatLen
len = len - fatLen
buf = buf + fatLen
else
len = 0
fin
until len == 0
return xferLen
end
def fatWriteImage(src, drv)
word copyBuf, copyLen, freeAddr
word blocknum, bufblk
copyBuf = heapallocalign(COPY_BUF_SIZE, 8, @freeAddr)
if not copyBuf
puts("Not enough free memory!\n"); putln
return -1
fin
//
// Copy FAT image over one track at a time
//
if sdFAT:fileOpen(src, O_READ)
if !drv; putc(7); fin
for blocknum = 0 to 279 step COPY_BLK_SIZE
copyLen = bigFatRead(copyBuf, COPY_BUF_SIZE)
if copyLen == COPY_BUF_SIZE
if drv
^$24=^$20 // Move cursor to left edge
puts("Writing blocks: "); puti(blocknum)
for bufblk = 0 to COPY_BLK_CNT
if writeblock(drv, copyBuf + (bufblk << 9), blocknum + bufblk)
puts("Write disk error: $"); putb(perr); putln
break
fin
next
fin
else
puts("Read image file error\n");
fin
if copyLen < COPY_BUF_SIZE or perr
puts("Error creating floppy: "); puts(src); putln
break
fin
next
if !drv; putc(7);fin
putln
sdFAT:fileClose()
else
puts("Error opening image file:"); puts(src); putln
fin
heaprelease(freeAddr)
end
arg = argNext(argFirst)
if ^arg
image = arg
arg = argNext(arg)
if ^arg
when ^(arg + 1)
is '2' // Drive 2 option
unit = DRIVE2
break
is 'T' // Test speed option
is 't'
unit = 0
break
wend
fin
if unit
puts("Writing "); puts(image); puts(" to Drive "); putc((unit >> 7) + '1')
else
puts("Speed test reading 143K from SD card");
fin
if getYN("\nContinue? (Y/N)")
fatWriteImage(image, unit)
fin
else
puts("Write DSK image to floppy disk drive\n")
puts("Usage: +FATWRITEDSK <DSK image file> [1,2,T]\n")
fin
done

View File

@ -33,7 +33,7 @@ predef loadmod, execmod, lookupstrmod
//
// System variable.
//
word version = $0092 // 00.92
word version = $0093 // 00.93
word systemflags = 0
word heap
word xheap = $0800
@ -1188,9 +1188,10 @@ def striptrail(strptr)
for i = 1 to ^strptr
if ^(strptr + i) <= ' '
^strptr = i - 1
return
return strptr
fin
next
return strptr
end
def parsecmd(strptr)
byte cmd
@ -1317,7 +1318,7 @@ while 1
execsys(@cmdln)
break
is '+'
execmod(@cmdln)
execmod(striptrail(@cmdln))
break
otherwise
cout('?')