mirror of
https://github.com/dschmenk/PLASMA.git
synced 2024-08-21 21:29:08 +00:00
FileIO library for Apple 1 and ///, divmod function in cmdsys
This commit is contained in:
parent
40ae932940
commit
f5ea22af02
@ -37,14 +37,23 @@ import fileio
|
||||
//
|
||||
// File functions
|
||||
//
|
||||
predef getpfx, setpfx, getfileinfo
|
||||
predef open, close, read, write, create, destroy, newline
|
||||
//
|
||||
// Block level I/O functions
|
||||
//
|
||||
predef readblock, writeblock
|
||||
struc t_fileio
|
||||
word getpfx
|
||||
word setpfx
|
||||
word getfileinfo
|
||||
word open
|
||||
word close
|
||||
word read
|
||||
word write
|
||||
word create
|
||||
word destroy
|
||||
word newline
|
||||
word readblock
|
||||
word writeblock
|
||||
end
|
||||
word fileio
|
||||
//
|
||||
// Globally accessible error code
|
||||
//
|
||||
byte perr
|
||||
end
|
||||
end
|
||||
|
@ -1,12 +1,61 @@
|
||||
include "inc/cmdsys.plh"
|
||||
//
|
||||
// ProDOS error code
|
||||
// CFFA1 addresses.
|
||||
//
|
||||
const CFFA1Dest = $00
|
||||
const CFFA1FileName = $02
|
||||
const CFFA1OldName = $04
|
||||
const CFFA1FileType = $06
|
||||
const CFFA1AuxType = $07
|
||||
const CFFA1FileSize = $09
|
||||
const CFFA1EntryPtr = $0B
|
||||
//
|
||||
// All our file I/O routines
|
||||
//
|
||||
struc t_fileio
|
||||
word getpfx
|
||||
word setpfx
|
||||
word getfileinfo
|
||||
word open
|
||||
word close
|
||||
word read
|
||||
word write
|
||||
word create
|
||||
word destroy
|
||||
word newline
|
||||
word readblock
|
||||
word writeblock
|
||||
end
|
||||
predef a1getpfx, a1setpfx, a1getfileinfo, a1open, a1close, a1read, a1write, a1create, a1destroy
|
||||
predef a1newline, a13readblock, a13writeblock
|
||||
predef a2getpfx, a23setpfx, a2getfileinfo, a2open, a23close, a23read, a2write, a2create, a23destroy
|
||||
predef a23newline, a2readblock, a2writeblock
|
||||
predef a3getpfx, a3getfileinfo, a3open, a3write, a3create
|
||||
//
|
||||
// Exported function table.
|
||||
//
|
||||
export word fileio[]
|
||||
//
|
||||
// Platform specific function pointers (default to Apple II).
|
||||
//
|
||||
word a2io[] = @a2getpfx, @a23setpfx, @a2getfileinfo, @a2open, @a23close, @a23read, @a2write, @a2create, @a23destroy
|
||||
word = @a23newline, @a2readblock, @a2writeblock
|
||||
word a3io[] = @a3getpfx, @a23setpfx, @a3getfileinfo, @a3open, @a23close, @a23read, @a3write, @a3create, @a23destroy
|
||||
word = @a23newline, @a13readblock, @a13writeblock
|
||||
word a1io[] = @a1getpfx, @a1setpfx, @a1getfileinfo, @a1open, @a1close, @a1read, @a1write, @a1create, @a1destroy
|
||||
word = @a1newline, @a13readblock, @a13writeblock
|
||||
//
|
||||
// SOS/ProDOS error code
|
||||
//
|
||||
export byte perr
|
||||
//
|
||||
// ProDOS routines
|
||||
// ProDOS/SOS routines
|
||||
//
|
||||
export def getpfx(path)
|
||||
def a1getpfx(path)
|
||||
^path = 0
|
||||
return path
|
||||
end
|
||||
def a2getpfx(path)
|
||||
byte params[3]
|
||||
|
||||
^path = 0
|
||||
@ -15,7 +64,19 @@ export def getpfx(path)
|
||||
perr = syscall($C7, @params)
|
||||
return path
|
||||
end
|
||||
export def setpfx(path)
|
||||
def a3getpfx(path)
|
||||
byte params[3]
|
||||
|
||||
params.0 = 2
|
||||
params:1 = path
|
||||
params.3 = 64
|
||||
perr = syscall($C7, @params)
|
||||
return path
|
||||
end
|
||||
def a1setpfx(path)
|
||||
return path
|
||||
end
|
||||
def a23setpfx(path)
|
||||
byte params[3]
|
||||
|
||||
params.0 = 1
|
||||
@ -23,7 +84,11 @@ export def setpfx(path)
|
||||
perr = syscall($C6, @params)
|
||||
return path
|
||||
end
|
||||
export def getfileinfo(path, fileinfo)
|
||||
def a1getfileinfo(path, fileinfo)
|
||||
perr = $01
|
||||
return perr
|
||||
end
|
||||
def a2getfileinfo(path, fileinfo)
|
||||
byte params[18]
|
||||
|
||||
params.0 = 10
|
||||
@ -32,7 +97,22 @@ export def getfileinfo(path, fileinfo)
|
||||
memcpy(fileinfo, @params + 3, 15)
|
||||
return perr
|
||||
end
|
||||
export def open(path, buf)
|
||||
def a3getfileinfo(path, fileinfo)
|
||||
byte params[6]
|
||||
|
||||
params.0 = 3
|
||||
params:1 = path
|
||||
params:3 = fileinfo
|
||||
params.5 = 15
|
||||
perr = syscall($C4, @params)
|
||||
return perr
|
||||
end
|
||||
def a1open(path, buf)
|
||||
*CFFA1FileName = path
|
||||
*CFFA1Dest = buf
|
||||
return 0
|
||||
end
|
||||
def a2open(path, buf)
|
||||
byte params[6]
|
||||
|
||||
params.0 = 3
|
||||
@ -42,7 +122,21 @@ export def open(path, buf)
|
||||
perr = syscall($C8, @params)
|
||||
return params.5
|
||||
end
|
||||
export def close(refnum)
|
||||
def a3open(path, access)
|
||||
byte params[7]
|
||||
|
||||
params.0 = 4
|
||||
params:1 = path
|
||||
params.3 = 0
|
||||
params:4 = @access
|
||||
params.6 = 1
|
||||
syscall($C8, @params)
|
||||
return params.3
|
||||
end
|
||||
def a1close(refnum)
|
||||
return perr
|
||||
end
|
||||
def a23close(refnum)
|
||||
byte params[2]
|
||||
|
||||
params.0 = 1
|
||||
@ -50,7 +144,11 @@ export def close(refnum)
|
||||
perr = syscall($CC, @params)
|
||||
return perr
|
||||
end
|
||||
export def read(refnum, buf, len)
|
||||
def a1read(refnum, buf, len)
|
||||
perr = syscall($22) // This reads the entire file on CFFA
|
||||
return perr
|
||||
end
|
||||
def a23read(refnum, buf, len)
|
||||
byte params[8]
|
||||
|
||||
params.0 = 4
|
||||
@ -61,7 +159,10 @@ export def read(refnum, buf, len)
|
||||
perr = syscall($CA, @params)
|
||||
return params:6
|
||||
end
|
||||
export def write(refnum, buf, len)
|
||||
def a1write(refnum, buf, len)
|
||||
return perr
|
||||
end
|
||||
def a2write(refnum, buf, len)
|
||||
byte params[8]
|
||||
|
||||
params.0 = 4
|
||||
@ -72,7 +173,20 @@ export def write(refnum, buf, len)
|
||||
perr = syscall($CB, @params)
|
||||
return params:6
|
||||
end
|
||||
export def create(path, access, type, aux)
|
||||
def a3write(refnum, buff, len)
|
||||
byte params[6]
|
||||
|
||||
params.0 = 3
|
||||
params.1 = refnum
|
||||
params:2 = buff
|
||||
params:4 = len
|
||||
perr = syscall($CB, @params)
|
||||
return perr
|
||||
end
|
||||
def a1create(path, access, type, aux)
|
||||
return perr
|
||||
end
|
||||
def a2create(path, access, type, aux)
|
||||
byte params[12]
|
||||
|
||||
params.0 = 7
|
||||
@ -86,7 +200,23 @@ export def create(path, access, type, aux)
|
||||
perr = syscall($C0, @params)
|
||||
return perr
|
||||
end
|
||||
export def destroy(path)
|
||||
def a3create(path, access, type, aux)
|
||||
byte params[6]
|
||||
byte options[4]
|
||||
|
||||
params.0 = 3
|
||||
params:1 = path
|
||||
params:3 = @options
|
||||
params.5 = 3
|
||||
options.0 = type
|
||||
options:1 = aux
|
||||
perr = syscall($C0, @params)
|
||||
return perr
|
||||
end
|
||||
def a1destroy(path)
|
||||
return perr
|
||||
end
|
||||
def a23destroy(path)
|
||||
byte params[3]
|
||||
|
||||
params.0 = 1
|
||||
@ -94,7 +224,10 @@ export def destroy(path)
|
||||
perr = syscall($C1, @params)
|
||||
return perr
|
||||
end
|
||||
export def newline(refnum, emask, nlchar)
|
||||
def a1newline(refnum, emask, nlchar)
|
||||
return perr
|
||||
end
|
||||
def a23newline(refnum, emask, nlchar)
|
||||
byte params[4]
|
||||
|
||||
params.0 = 3
|
||||
@ -104,7 +237,11 @@ export def newline(refnum, emask, nlchar)
|
||||
perr = syscall($C9, @params)
|
||||
return perr
|
||||
end
|
||||
export def readblock(unit, buf, block)
|
||||
def a13readblock(unit, buf, block)
|
||||
perr = $27 // IOERR
|
||||
return perr
|
||||
end
|
||||
def a2readblock(unit, buf, block)
|
||||
byte params[6]
|
||||
|
||||
params.0 = 3
|
||||
@ -114,7 +251,11 @@ export def readblock(unit, buf, block)
|
||||
perr = syscall($80, @params)
|
||||
return perr
|
||||
end
|
||||
export def writeblock(unit, buf, block)
|
||||
def a13writeblock(unit, buf, block)
|
||||
perr = $27 // IOERR
|
||||
return perr
|
||||
end
|
||||
def a2writeblock(unit, buf, block)
|
||||
byte params[6]
|
||||
|
||||
params.0 = 3
|
||||
@ -124,5 +265,16 @@ export def writeblock(unit, buf, block)
|
||||
perr = syscall($81, @params)
|
||||
return perr
|
||||
end
|
||||
|
||||
//
|
||||
// Machine specific initialization.
|
||||
//
|
||||
when MACHID & $C8
|
||||
is $08 // Apple 1
|
||||
memcpy(fileio, a1io, t_fileio)
|
||||
break
|
||||
is $C0 // Apple ///
|
||||
memcpy(fileio, a3io, t_fileio)
|
||||
break
|
||||
otherwise // Apple ][
|
||||
wend
|
||||
done
|
||||
|
@ -703,14 +703,14 @@ def loadcode(codefile)
|
||||
|
||||
//puts(codefile); puts(":\n")
|
||||
pcode = 0
|
||||
ref = open(codefile, sysbuf)
|
||||
ref = fileio:open(codefile, sysbuf)
|
||||
if ref
|
||||
pcode = heapmark
|
||||
read(ref, pcode, 512)
|
||||
fileio:read(ref, pcode, 512)
|
||||
//dumpheader(pcode)
|
||||
//putname(pcode + segname + 8); putc('='); prword(pcode); putln
|
||||
seglen = read(ref, pcode, (pcode + t_diskinfo)=>codeaddr)
|
||||
close(ref)
|
||||
seglen = fileio:read(ref, pcode, (pcode + t_diskinfo)=>codeaddr)
|
||||
fileio:close(ref)
|
||||
if !fp6502 and (MACHID & $30 == $30)
|
||||
seglen = fixup(AUXADDR, pcode + seglen - 2) - pcode
|
||||
auxmove(AUXADDR, pcode, seglen)
|
||||
|
@ -126,9 +126,9 @@ def fatCopyFrom(src, dst, type, aux)
|
||||
//
|
||||
// Check if dst already exists
|
||||
//
|
||||
ref = open(dst, sysbuf)
|
||||
ref = fileio:open(dst, sysbuf)
|
||||
if ref
|
||||
close(ref)
|
||||
fileio:close(ref)
|
||||
puts("Overwrite "); puts(dst)
|
||||
if not getYN("(Y/N)?")
|
||||
heaprelease(freeAddr)
|
||||
@ -140,10 +140,10 @@ def fatCopyFrom(src, dst, type, aux)
|
||||
//
|
||||
// Create dst file
|
||||
//
|
||||
if create(dst, $C3, type, aux)
|
||||
if fileio:create(dst, $C3, type, aux)
|
||||
puts("Create file error: "); putByte(perr); putln
|
||||
fin
|
||||
ref = open(dst, sysbuf)
|
||||
ref = fileio:open(dst, sysbuf)
|
||||
if not ref
|
||||
puts("Error opening file: "); puts(dst); putln
|
||||
puts("Open file error: "); putByte(perr); putln
|
||||
@ -156,7 +156,7 @@ def fatCopyFrom(src, dst, type, aux)
|
||||
repeat
|
||||
copyLen = bigFatRead(copyBuf, COPY_BUF_SIZE)
|
||||
if copyLen
|
||||
if write(ref, copyBuf, copyLen) <> copyLen
|
||||
if fileio: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
|
||||
@ -167,7 +167,7 @@ def fatCopyFrom(src, dst, type, aux)
|
||||
else
|
||||
puts("Error opening FAT file:"); puts(src); putln
|
||||
fin
|
||||
close(ref)
|
||||
fileio:close(ref)
|
||||
heaprelease(freeAddr)
|
||||
end
|
||||
|
||||
@ -180,4 +180,4 @@ if ^arg
|
||||
else
|
||||
puts("Usage: +FATGET <FAT filename>"); putln
|
||||
fin
|
||||
done
|
||||
done
|
||||
|
@ -43,7 +43,7 @@ def mkFatName(proName, fatName)
|
||||
word l, n
|
||||
byte fileinfo[t_fileinfo]
|
||||
|
||||
if !getfileinfo(proName, @fileinfo)
|
||||
if !fileio:getfileinfo(proName, @fileinfo)
|
||||
//
|
||||
// Scan backward looking for dir seperator
|
||||
//
|
||||
@ -110,7 +110,7 @@ def fatCopyTo(src, dst)
|
||||
puts("Not enough free memory!\n"); putln
|
||||
return -1
|
||||
fin
|
||||
ref = open(src, sysbuf)
|
||||
ref = fileio:open(src, sysbuf)
|
||||
if not ref
|
||||
puts("Error opening file: "); puts(src); putln
|
||||
puts("Open file error: "); putByte(perr); putln
|
||||
@ -121,7 +121,7 @@ def fatCopyTo(src, dst)
|
||||
//
|
||||
if sdFAT:fileOpen(dst, O_READ | O_WRITE | O_CREAT)
|
||||
repeat
|
||||
copyLen = read(ref, copyBuf, COPY_BUF_SIZE)
|
||||
copyLen = fileio:read(ref, copyBuf, COPY_BUF_SIZE)
|
||||
if copyLen
|
||||
copyLen = bigFatWrite(copyBuf, copyLen)
|
||||
if !copyLen
|
||||
@ -132,7 +132,7 @@ def fatCopyTo(src, dst)
|
||||
else
|
||||
puts("Error opening FAT file:"); puts(dst); putln
|
||||
fin
|
||||
close(ref)
|
||||
fileio:close(ref)
|
||||
heaprelease(freeAddr)
|
||||
end
|
||||
|
||||
@ -144,4 +144,4 @@ if ^arg
|
||||
else
|
||||
puts("Usage: +FATPUT <filename>"); putln
|
||||
fin
|
||||
done
|
||||
done
|
||||
|
@ -107,7 +107,7 @@ def fatReadImage(src, drv, order)
|
||||
^$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)
|
||||
if fileio:readblock(drv, inBuf + (bufblk << 9), blocknum + bufblk)
|
||||
puts("Read disk error: $"); putb(perr); putln
|
||||
break
|
||||
fin
|
||||
|
@ -113,7 +113,7 @@ def fatWriteImage(src, drv, order)
|
||||
trkSecToBlk(inBuf, outBuf)
|
||||
fin
|
||||
for bufblk = 0 to COPY_BLK_CNT
|
||||
if writeblock(drv, outBuf + (bufblk << 9), blocknum + bufblk)
|
||||
if fileio:writeblock(drv, outBuf + (bufblk << 9), blocknum + bufblk)
|
||||
puts("Write disk error: $"); putb(perr); putln
|
||||
break
|
||||
fin
|
||||
|
@ -263,7 +263,7 @@ when MACHID & $C8
|
||||
gotoxy = @a3gotoxy
|
||||
grmode = @a3grmode
|
||||
textmode = @a3textmode
|
||||
if modaddr(@cmdsys):0 == $0010
|
||||
if modaddr(@cmdsys):0 == $0099
|
||||
devcons = modaddr(@cmdsys).5 // devcons variable from cmdsys
|
||||
else
|
||||
puts(@a3err)
|
||||
|
@ -34,7 +34,7 @@ predef syscall(cmd)#1, call(addr,areg,xreg,yreg,status)#1
|
||||
predef crout()#0, cout(c)#0, prstr(s)#0, print(i)#0, cin()#1, rdstr(p)#1, toupper(c)#1
|
||||
predef markheap()#1, allocheap(size)#1, allocalignheap(size, pow2, freeaddr), releaseheap(newheap)#1, availheap()#1
|
||||
predef memset(addr,value,size)#0, memcpy(dst,src,size)#0
|
||||
predef uword_isgt(a,b)#1, uword_isge(a,b)#1, uword_islt(a,b)#1, uword_isle(a,b)#1
|
||||
predef uword_isgt(a,b)#1, uword_isge(a,b)#1, uword_islt(a,b)#1, uword_isle(a,b)#1, divmod(a,b)#2
|
||||
predef loadmod(mod)#1, execmod(modfile)#1, lookupstrmod(str)#1
|
||||
//
|
||||
// System variables.
|
||||
@ -88,6 +88,7 @@ byte uisgtstr[] = "ISUGT"
|
||||
byte uisgestr[] = "ISUGE"
|
||||
byte uisltstr[] = "ISULT"
|
||||
byte uislestr[] = "ISULE"
|
||||
byte divmodstr[] = "DIVMOD"
|
||||
byte loadstr[] = "MODLOAD"
|
||||
byte execstr[] = "MODEXEC"
|
||||
byte modadrstr[] = "MODADDR"
|
||||
@ -112,6 +113,7 @@ word = @uisgtstr, @uword_isgt
|
||||
word = @uisgestr, @uword_isge
|
||||
word = @uisltstr, @uword_islt
|
||||
word = @uislestr, @uword_isle
|
||||
word = @divmodstr, @divmod
|
||||
word = @loadstr, @loadmod
|
||||
word = @execstr, @execmod
|
||||
word = @modadrstr, @lookupstrmod
|
||||
@ -348,6 +350,30 @@ asm uword_islt(a,b)#1
|
||||
INX
|
||||
RTS
|
||||
end
|
||||
asm divmod(a,b)#2
|
||||
LDA #>(_divmod-1)
|
||||
PHA
|
||||
LDA #<(_divmod-1)
|
||||
PHA
|
||||
JSR INTERP
|
||||
!BYTE $0A, $5C ; MOD, RET
|
||||
_divmod DEX
|
||||
LDA DSTL ; DVDNDL
|
||||
STA ESTKL,X
|
||||
LDA DSTH ; DVDNDH
|
||||
STA ESTKH,X
|
||||
LSR DVSIGN ; SIGN(RESULT) = (SIGN(DIVIDEND) + SIGN(DIVISOR)) & 1
|
||||
BCS +
|
||||
RTS
|
||||
+ LDA #$00
|
||||
; SEC
|
||||
SBC ESTKL,X
|
||||
STA ESTKL,X
|
||||
LDA #$00
|
||||
SBC ESTKH,X
|
||||
STA ESTKH,X
|
||||
RTS
|
||||
end
|
||||
//
|
||||
// Addresses of internal routines.
|
||||
//
|
||||
|
@ -28,7 +28,7 @@ predef syscall(cmd,params)#1, call(addr,areg,xreg,yreg,status)#1
|
||||
predef crout()#0, cout(c)#0, prstr(s)#0, print(i)#0, cin()#1, rdstr(p)#1, toupper(c)#1
|
||||
predef markheap()#1, allocheap(size)#1, allocalignheap(size, pow2, freeaddr)#1, releaseheap(newheap)#1, availheap()#1
|
||||
predef memset(addr,value,size)#0, memcpy(dst,src,size)#0
|
||||
predef uword_isgt(a,b)#1, uword_isge(a,b)#1, uword_islt(a,b)#1, uword_isle(a,b)#1
|
||||
predef uword_isgt(a,b)#1, uword_isge(a,b)#1, uword_islt(a,b)#1, uword_isle(a,b)#1, divmod(a,b)#2
|
||||
predef loadmod(mod)#1, execmod(modfile)#1, lookupstrmod(str)#1
|
||||
//
|
||||
// System variable.
|
||||
@ -65,6 +65,7 @@ byte uisgtstr = "ISUGT"
|
||||
byte uisgestr = "ISUGE"
|
||||
byte uisltstr = "ISULT"
|
||||
byte uislestr = "ISULE"
|
||||
byte divmodstr = "DIVMOD"
|
||||
byte loadstr = "MODLOAD"
|
||||
byte execstr = "MODEXEC"
|
||||
byte modadrstr = "MODADDR"
|
||||
@ -91,6 +92,7 @@ word = @uisgtstr, @uword_isgt
|
||||
word = @uisgestr, @uword_isge
|
||||
word = @uisltstr, @uword_islt
|
||||
word = @uislestr, @uword_isle
|
||||
word = @divmodstr, @divmod
|
||||
word = @loadstr, @loadmod
|
||||
word = @execstr, @execmod
|
||||
word = @modadrstr, @lookupstrmod
|
||||
@ -499,6 +501,30 @@ asm uword_islt(a,b)#1
|
||||
INX
|
||||
RTS
|
||||
end
|
||||
asm divmod(a,b)#2
|
||||
LDA #>(_divmod-1)
|
||||
PHA
|
||||
LDA #<(_divmod-1)
|
||||
PHA
|
||||
JSR $03D0 ; CALL DINTERP
|
||||
!BYTE $0A, $5C ; MOD, RET
|
||||
_divmod DEX
|
||||
LDA DSTL ; DVDNDL
|
||||
STA ESTKL,X
|
||||
LDA DSTH ; DVDNDH
|
||||
STA ESTKH,X
|
||||
LSR DVSIGN ; SIGN(RESULT) = (SIGN(DIVIDEND) + SIGN(DIVISOR)) & 1
|
||||
BCS +
|
||||
RTS
|
||||
+ LDA #$00
|
||||
; SEC
|
||||
SBC ESTKL,X
|
||||
STA ESTKL,X
|
||||
LDA #$00
|
||||
SBC ESTKH,X
|
||||
STA ESTKH,X
|
||||
RTS
|
||||
end
|
||||
//
|
||||
// Utility routines.
|
||||
//
|
||||
|
@ -138,6 +138,10 @@ DIV JSR _DIV
|
||||
;* MOD TOS-1 BY TOS
|
||||
;*
|
||||
MOD JSR _DIV
|
||||
LDA ESTKL,X ; SAVE IN CASE OF DIVMOD
|
||||
STA DSTL
|
||||
LDA ESTKH,X
|
||||
STA DSTH
|
||||
LDA TMPL ; REMNDRL
|
||||
STA ESTKL,X
|
||||
LDA TMPH ; REMNDRH
|
||||
|
@ -560,6 +560,10 @@ DIV JSR _DIV
|
||||
;* MOD TOS-1 BY TOS
|
||||
;*
|
||||
MOD JSR _DIV
|
||||
LDA ESTKL,X ; SAVE IN CASE OF DIVMOD
|
||||
STA DSTL
|
||||
LDA ESTKH,X
|
||||
STA DSTH
|
||||
LDA TMPL ; REMNDRL
|
||||
STA ESTKL,X
|
||||
LDA TMPH ; REMNDRH
|
||||
|
@ -286,6 +286,10 @@ DIV JSR _DIV
|
||||
;* MOD TOS-1 BY TOS
|
||||
;*
|
||||
MOD JSR _DIV
|
||||
LDA ESTKL,X ; SAVE IN CASE OF DIVMOD
|
||||
STA DSTL
|
||||
LDA ESTKH,X
|
||||
STA DSTH
|
||||
LDA TMPL ; REMNDRL
|
||||
STA ESTKL,X
|
||||
LDA TMPH ; REMNDRH
|
||||
|
@ -613,6 +613,8 @@ DIV JSR _DIV
|
||||
MOD JSR _DIV
|
||||
STA NOS,S ; REMNDR
|
||||
PLA
|
||||
STA DST ; SAVE IN CASE OF DIVMOD
|
||||
STX DVSIGN
|
||||
TXA
|
||||
AND #$0080 ; REMAINDER IS SIGN OF DIVIDEND
|
||||
BNE NEG
|
||||
|
@ -29,7 +29,7 @@ predef syscall(cmd,params)#1, call(addr,areg,xreg,yreg,status)#1
|
||||
predef crout()#0, cout(c)#0, prstr(s)#0, print(i)#0, cin()#1, rdstr(p)#1, toupper(c)#1
|
||||
predef markheap()#1, allocheap(size)#1, allocalignheap(size, pow2, freeaddr), releaseheap(newheap)#1, availheap()#1
|
||||
predef memset(addr,value,size)#0, memcpy(dst,src,size)#0
|
||||
predef uword_isgt(a,b)#1, uword_isge(a,b)#1, uword_islt(a,b)#1, uword_isle(a,b)#1
|
||||
predef uword_isgt(a,b)#1, uword_isge(a,b)#1, uword_islt(a,b)#1, uword_isle(a,b)#1, divmod(a,b)#2
|
||||
predef loadmod(mod)#1, execmod(modfile)#1, lookupstrmod(str)#1
|
||||
//
|
||||
// System variables.
|
||||
@ -83,6 +83,7 @@ byte uisgtstr[] = "ISUGT"
|
||||
byte uisgestr[] = "ISUGE"
|
||||
byte uisltstr[] = "ISULT"
|
||||
byte uislestr[] = "ISULE"
|
||||
byte divmodstr[] = "DIVMOD"
|
||||
byte loadstr[] = "MODLOAD"
|
||||
byte execstr[] = "MODEXEC"
|
||||
byte modadrstr[] = "MODADDR"
|
||||
@ -108,6 +109,7 @@ word = @uisgtstr, @uword_isgt
|
||||
word = @uisgestr, @uword_isge
|
||||
word = @uisltstr, @uword_islt
|
||||
word = @uislestr, @uword_isle
|
||||
word = @divmodstr, @divmod
|
||||
word = @loadstr, @loadmod
|
||||
word = @execstr, @execmod
|
||||
word = @modadrstr, @lookupstrmod
|
||||
@ -232,9 +234,9 @@ asm memcpy(dst,src,size)#0
|
||||
;
|
||||
; FORWARD COPY
|
||||
;
|
||||
LDA ESTKL-2,X
|
||||
LDA ESTKL-1,X
|
||||
STA DSTL
|
||||
LDA ESTKH-2,X
|
||||
LDA ESTKH-1,X
|
||||
STA DSTH
|
||||
LDA ESTKL-2,X
|
||||
STA SRCL
|
||||
@ -410,6 +412,30 @@ asm uword_islt(a,b)#1
|
||||
INX
|
||||
RTS
|
||||
end
|
||||
asm divmod(a,b)#2
|
||||
LDA #>(_divmod-1)
|
||||
PHA
|
||||
LDA #<(_divmod-1)
|
||||
PHA
|
||||
JSR INTERP
|
||||
!BYTE $0A, $5C ; MOD, RET
|
||||
_divmod DEX
|
||||
LDA DSTL ; DVDNDL
|
||||
STA ESTKL,X
|
||||
LDA DSTH ; DVDNDH
|
||||
STA ESTKH,X
|
||||
LSR DVSIGN ; SIGN(RESULT) = (SIGN(DIVIDEND) + SIGN(DIVISOR)) & 1
|
||||
BCS +
|
||||
RTS
|
||||
+ LDA #$00
|
||||
; SEC
|
||||
SBC ESTKL,X
|
||||
STA ESTKL,X
|
||||
LDA #$00
|
||||
SBC ESTKH,X
|
||||
STA ESTKH,X
|
||||
RTS
|
||||
end
|
||||
//
|
||||
// Addresses of internal routines.
|
||||
//
|
||||
@ -960,9 +986,9 @@ def loadmod(mod)#1
|
||||
if refnum > 0
|
||||
rdlen = read(refnum, @header, 128)
|
||||
modsize = header:0
|
||||
moddep = @header.1
|
||||
defofst = modsize
|
||||
init = 0
|
||||
//moddep = @header.1
|
||||
//defofst = modsize
|
||||
//init = 0
|
||||
if rdlen > 4 and header:2 == $DA7F // DAVE+1 = magic number :-)
|
||||
//
|
||||
// This is an EXTended RELocatable (data+bytecode) module.
|
||||
|
Loading…
Reference in New Issue
Block a user