mirror of
https://github.com/dschmenk/PLASMA.git
synced 2025-01-09 13:33:26 +00:00
Merge branch 'master' of https://github.com/dschmenk/PLASMA
This commit is contained in:
commit
5e7408c980
@ -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
3
src/inc/args.plh
Normal file
@ -0,0 +1,3 @@
|
||||
import args
|
||||
predef argFirst, argNext
|
||||
end
|
@ -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
|
||||
|
50
src/inc/fileio.plh
Normal file
50
src/inc/fileio.plh
Normal file
@ -0,0 +1,50 @@
|
||||
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 info struc
|
||||
struc t_fileinfo
|
||||
byte file_access
|
||||
byte file_type
|
||||
word aux_type
|
||||
byte storage_type
|
||||
word blocks_used
|
||||
word mod_date
|
||||
word mod_time
|
||||
word create_date
|
||||
word create_time
|
||||
end
|
||||
//
|
||||
// File functions
|
||||
//
|
||||
predef getpfx, setpfx, getfileinfo
|
||||
predef 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
45
src/inc/sdfat.plh
Normal 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
6
src/inc/spiport.plh
Normal 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
23
src/inc/wireio.plh
Normal 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
34
src/libsrc/args.pla
Normal 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
|
128
src/libsrc/fileio.pla
Normal file
128
src/libsrc/fileio.pla
Normal file
@ -0,0 +1,128 @@
|
||||
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 getfileinfo(path, fileinfo)
|
||||
byte params[18]
|
||||
|
||||
params.0 = 10
|
||||
params:1 = path
|
||||
perr = syscall($C4, @params)
|
||||
memcpy(fileinfo, @params + 3, 15)
|
||||
return perr
|
||||
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
151
src/libsrc/sdfat.pla
Normal 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
249
src/libsrc/spiport.pla
Normal 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
|
47
src/makefile
47
src/makefile
@ -9,6 +9,15 @@ 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
|
||||
FATPUT = FATPUT\#FE1000
|
||||
FATWDSK = FATWRITEDSK\#FE1000
|
||||
FATRDSK = FATREADDSK\#FE1000
|
||||
FILEIO = FILEIO\#FE1000
|
||||
WIZNET = WIZNET\#FE1000
|
||||
UTHERNET2= UTHERNET2\#FE1000
|
||||
UTHERNET= UTHERNET\#FE1000
|
||||
@ -53,7 +62,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) $(FATPUT) $(FATWDSK) $(FATRDSK)
|
||||
|
||||
clean:
|
||||
-rm *FE1000 *FF2000 $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03)
|
||||
@ -110,6 +119,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 +171,42 @@ $(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
|
||||
|
||||
$(FATPUT): samplesrc/fatput.pla $(PLVM02) $(PLASM)
|
||||
./$(PLASM) -AM < samplesrc/fatput.pla > samplesrc/fatput.a
|
||||
acme --setpc 4094 -o $(FATPUT) samplesrc/fatput.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
49
src/samplesrc/fatcat.pla
Normal 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
183
src/samplesrc/fatget.pla
Normal 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
|
||||
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
|
147
src/samplesrc/fatput.pla
Normal file
147
src/samplesrc/fatput.pla
Normal file
@ -0,0 +1,147 @@
|
||||
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'
|
||||
|
||||
word arg
|
||||
byte[24] fatName
|
||||
|
||||
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 hexChars(cptr, b)
|
||||
byte h
|
||||
|
||||
h = ((b >> 4) & $0F) + '0'
|
||||
if h > '9'
|
||||
h = h + 7
|
||||
fin
|
||||
^cptr = h
|
||||
cptr++
|
||||
h = (b & $0F) + '0'
|
||||
if h > '9'
|
||||
h = h + 7
|
||||
fin
|
||||
^cptr = h
|
||||
end
|
||||
|
||||
def mkFatName(proName, fatName)
|
||||
word l, n
|
||||
byte fileinfo[t_fileinfo]
|
||||
|
||||
if !getfileinfo(proName, @fileinfo)
|
||||
//
|
||||
// Scan backward looking for dir seperator
|
||||
//
|
||||
l = ^proName
|
||||
for n = l downto 1
|
||||
if ^(proName + n) == '/'
|
||||
break
|
||||
fin
|
||||
next
|
||||
memcpy(fatName + 1, proName + 1 + n, l - n)
|
||||
^fatName = l - n + 7
|
||||
//
|
||||
// Build CiderPress style extension
|
||||
//
|
||||
n = fatName + ^fatName - 6
|
||||
^n = '#'
|
||||
hexChars(n + 1, fileinfo.file_type)
|
||||
hexChars(n + 3, fileinfo.aux_type.1)
|
||||
hexChars(n + 5, fileinfo.aux_type)
|
||||
else
|
||||
//
|
||||
// Error getting info on file
|
||||
//
|
||||
puts("Error reading "); puts(proName); putln
|
||||
fin
|
||||
end
|
||||
|
||||
def getYN(prompt)
|
||||
byte yn
|
||||
|
||||
puts(prompt)
|
||||
yn = getc
|
||||
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 fatCopyTo(src, dst)
|
||||
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
|
||||
ref = open(src, sysbuf)
|
||||
if not ref
|
||||
puts("Error opening file: "); puts(src); putln
|
||||
puts("Open file error: "); putByte(perr); putln
|
||||
return -1
|
||||
fin
|
||||
//
|
||||
// Copy file over in big chunks
|
||||
//
|
||||
if sdFAT:fileOpen(dst, O_READ | O_WRITE | O_CREAT)
|
||||
repeat
|
||||
copyLen = read(ref, copyBuf, COPY_BUF_SIZE)
|
||||
if copyLen
|
||||
copyLen = bigFatWrite(copyBuf, copyLen)
|
||||
if !copyLen
|
||||
fin
|
||||
fin
|
||||
until copyLen == 0
|
||||
sdFAT:fileClose()
|
||||
else
|
||||
puts("Error opening FAT file:"); puts(dst); putln
|
||||
fin
|
||||
close(ref)
|
||||
heaprelease(freeAddr)
|
||||
end
|
||||
|
||||
arg = argNext(argFirst)
|
||||
if ^arg
|
||||
mkFatName(arg, @fatName)
|
||||
puts(arg); puts(" ==> "); puts(@fatName); putln
|
||||
fatCopyTo(arg, @fatName)
|
||||
else
|
||||
puts("Usage: +FATPUT <filename>"); putln
|
||||
fin
|
||||
done
|
207
src/samplesrc/fatreaddsk.pla
Normal file
207
src/samplesrc/fatreaddsk.pla
Normal file
@ -0,0 +1,207 @@
|
||||
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'
|
||||
//
|
||||
// Track sector order
|
||||
//
|
||||
const ORDER_DOS = 0
|
||||
const ORDER_PRODOS = 1
|
||||
|
||||
word arg, image
|
||||
byte unit = DRIVE1
|
||||
byte order
|
||||
//
|
||||
// DOS to ProDOS sector ordering
|
||||
//
|
||||
byte[] secOrder = $0,$E,$D,$C,$B,$A,$9,$8,$7,$6,$5,$4,$3,$2,$1,$F
|
||||
|
||||
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 trkSecToBlk(bufSec, bufBlk)
|
||||
byte sector
|
||||
|
||||
for sector = 0 to 15
|
||||
memcpy(bufBlk + (sector << 8), bufSec + (secOrder[sector] << 8), 256)
|
||||
next
|
||||
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, order)
|
||||
word inBuf, outBuf, copyLen, freeAddr
|
||||
word blocknum, bufblk
|
||||
|
||||
inBuf = heapallocalign(COPY_BUF_SIZE * 2, 8, @freeAddr)
|
||||
if not inBuf
|
||||
puts("Not enough free memory!\n"); putln
|
||||
return -1
|
||||
fin
|
||||
if order == ORDER_DOS
|
||||
outBuf = inBuf + COPY_BUF_SIZE
|
||||
else
|
||||
outBuf = inBuf
|
||||
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, inBuf + (bufblk << 9), blocknum + bufblk)
|
||||
puts("Read disk error: $"); putb(perr); putln
|
||||
break
|
||||
fin
|
||||
next
|
||||
fin
|
||||
if order == ORDER_DOS
|
||||
trkSecToBlk(inBuf, outBuf)
|
||||
fin
|
||||
copyLen = bigFatWrite(outBuf, 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
|
||||
//
|
||||
// Figure sector ordering from filename
|
||||
//
|
||||
puts("\nUsing ")
|
||||
if charUpper(^(image + ^image)) == 'O' and charUpper(^(image + ^image - 1)) == 'P'
|
||||
order = ORDER_PRODOS
|
||||
puts("ProDOS")
|
||||
else
|
||||
order = ORDER_DOS
|
||||
puts("DOS 3.3")
|
||||
fin
|
||||
if getYN(" order. Continue? (Y/N)")
|
||||
fatReadImage(image, unit, order)
|
||||
fin
|
||||
else
|
||||
puts("Read DSK image from floppy disk drive\n")
|
||||
puts("Usage: +FATREADDSK <DSK image file> [1,2,T]\n")
|
||||
fin
|
||||
done
|
209
src/samplesrc/fatwritedsk.pla
Normal file
209
src/samplesrc/fatwritedsk.pla
Normal file
@ -0,0 +1,209 @@
|
||||
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'
|
||||
//
|
||||
// Track sector order
|
||||
//
|
||||
const ORDER_DOS = 0
|
||||
const ORDER_PRODOS = 1
|
||||
|
||||
word arg, image
|
||||
byte unit = DRIVE1
|
||||
byte order
|
||||
|
||||
//
|
||||
// DOS to ProDOS sector ordering
|
||||
//
|
||||
byte[] secOrder = $0,$E,$D,$C,$B,$A,$9,$8,$7,$6,$5,$4,$3,$2,$1,$F
|
||||
|
||||
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 trkSecToBlk(bufSec, bufBlk)
|
||||
byte sector
|
||||
|
||||
for sector = 0 to 15
|
||||
memcpy(bufBlk + (sector << 8), bufSec + (secOrder[sector] << 8), 256)
|
||||
next
|
||||
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, order)
|
||||
word inBuf, outBuf, copyLen, freeAddr
|
||||
word blocknum, bufblk
|
||||
|
||||
outBuf = heapallocalign(COPY_BUF_SIZE * 2, 8, @freeAddr)
|
||||
if not outBuf
|
||||
puts("Not enough free memory!\n"); putln
|
||||
return -1
|
||||
fin
|
||||
if order == ORDER_DOS
|
||||
inBuf = outBuf + COPY_BUF_SIZE
|
||||
else
|
||||
inBuf = outBuf
|
||||
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(inBuf, COPY_BUF_SIZE)
|
||||
if copyLen == COPY_BUF_SIZE
|
||||
if drv
|
||||
^$24=^$20 // Move cursor to left edge
|
||||
puts("Writing blocks: "); puti(blocknum)
|
||||
if order == ORDER_DOS
|
||||
trkSecToBlk(inBuf, outBuf)
|
||||
fin
|
||||
for bufblk = 0 to COPY_BLK_CNT
|
||||
if writeblock(drv, outBuf + (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
|
||||
//
|
||||
// Figure sector ordering from filename
|
||||
//
|
||||
puts("\nUsing ")
|
||||
if charUpper(^(image + ^image)) == 'O' and charUpper(^(image + ^image - 1)) == 'P'
|
||||
order = ORDER_PRODOS
|
||||
puts("ProDOS")
|
||||
else
|
||||
order = ORDER_DOS
|
||||
puts("DOS 3.3")
|
||||
fin
|
||||
if getYN(" order. Continue? (Y/N)")
|
||||
fatWriteImage(image, unit, order)
|
||||
fin
|
||||
else
|
||||
puts("Write DSK image to floppy disk drive\n")
|
||||
puts("Usage: +FATWRITEDSK <DSK image file> [1,2,T]\n")
|
||||
fin
|
||||
done
|
@ -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('?')
|
||||
|
Loading…
x
Reference in New Issue
Block a user