1
0
mirror of https://github.com/dschmenk/PLASMA.git synced 2024-11-04 11:07:00 +00:00

Merge pull request #14 from dschmenk/master

Merge latest upstream changes to master
This commit is contained in:
ZornsLemma 2019-04-28 11:47:14 +01:00 committed by GitHub
commit 112d5f4639
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 697 additions and 608 deletions

View File

@ -106,7 +106,7 @@ Different projects have led to the architecture of PLASMA, most notably Apple Pa
## PLASMA Cross-Compiler
The first step in writing PLASMA code is to get a build environment working. If you have Unix-like environment, then this is a fairly easy exercise. Windows users may want to install the [Cygwin](https://www.cygwin.com/) environment to replicate a Unix-like environment under Windows. When installing Cygwin, make sure **gcc-core**, **make**, and **git** are installed under the **Devel** packages. Mac OS X users may have to install the **Xcode** from the App Store.
The first step in writing PLASMA code is to get a build environment working. If you have Unix-like environment, then this is a fairly easy exercise. Windows users may want to install the [Linux Subsystem for Windows](https://docs.microsoft.com/en-us/windows/wsl/install-win10) or the [Cygwin](https://www.cygwin.com/) environment to replicate a Unix-like environment under Windows. When installing Cygwin, make sure **gcc-core**, **make**, and **git** are installed under the **Devel** packages. Mac OS X users may have to install the **Xcode** from the App Store. Linux users should make sure the development packages are installed.
Launch the command-line/terminal application for your environment to download and build PLASMA. Create a source code directory and change the working directory to it, something like:
@ -518,7 +518,7 @@ else
fin
```
The `when`/`is`/`otherwise`/`wend` statement is similar to the `if`/`elsif`/`else`/`fin` construct except that it is more efficient. It selects one path based on the evaluated expressions, then merges the code path back together at the end. Only the `when` value is compared against a list of expressions. The expressions do not need to be constants, they can be any valid expression. The list of expressions is evaluated in order, so for efficiency sake, place the most common cases earlier in the list. Just as in C programs, a `break` statement is required to keep one clause from falling through to the next. Falling through from one clause to the next can have its uses, so this behavior has been added to PLASMA.
The `when`/`is`/`otherwise`/`wend` statement is similar to the `if`/`elsif`/`else`/`fin` construct except that it is more efficient. It selects one path based on the evaluated expressions, then merges the code path back together at the end. Only the `when` value is compared against a list of constant. Just as in C programs, a `break` statement is required to keep one clause from falling through to the next. Falling through from one clause to the next can have its uses, so this behavior has been added to PLASMA.
```
when keypressed
@ -1139,7 +1139,7 @@ The common `if` test can have optional `elsif` and/or `else` clauses. Any expres
#### WHEN/IS/[OTHERWISE]/WEND
The complex test case is handled with `when`. Basically an `if`, `elsif`, `else` list of comparisons, it is generally more efficient. The `is` value can be any expression. It is evaluated and tested for equality to the `when` value.
The complex test case is handled with `when`. Basically an `if`, `elsif`, `else` list of comparisons, it is generally more efficient. The `is` value must be a constant.
```
when key
@ -1162,26 +1162,6 @@ when key
wend
```
With a little "Yoda-Speak", some fairly complex test can be made:
```
const FALSE = 0
const TRUE = NOT FALSE
byte a
when TRUE
is (a <= 10)
// 10 or less
break
is (a > 10) AND (a < 20)
// between 10 and 20
break
is (a >= 20)
// 20 or greater
wend
```
A `when` clause can fall-through to the following clause, just like C `switch` statements by leaving out the `break`.
#### FOR \<TO,DOWNTO\> [STEP]/NEXT

BIN
images/apple/PLASMA.2mg Normal file

Binary file not shown.

View File

@ -1,5 +1,4 @@
include "inc/cmdsys.plh"
sysflags nojitc // It's file I/O. No need to hurry up and wait.
//
// CFFA1 addresses.
//

View File

@ -18,6 +18,15 @@ end
const jitcomp = $03E2
const jitcodeptr = $03E4
const codemax = $BEE0
const estkh8 = $C000
const estkh = $00C0
const estkl8 = $D000
const estkl = $00D0
const ifpl8 = $E000
const ifph8 = $E100
const jmptmp = $00E6
const tmpl8 = $E700
const tmph8 = $E800
//
// Bytecode interpreter entrypoints
//

View File

@ -18,6 +18,20 @@ end
const jitcomp = $03E2
const jitcodeptr = $03E4
const codemax = $BEE0
const estkh8 = $C000
const estkh = $00C0
const estkl8 = $D000
const estkl = $00D0
const ifp8 = $E000
const ifpl8 = $E000
const ifph8 = $E100
const jmptmp = $00E6
const tmp8 = $E700
const tmpl8 = $E700
const tmph8 = $E800
const fetchop = $00F1
const ip8 = $F200
const ip = $00F2
//
// Bytecode interpreter entrypoints
//

View File

@ -50,6 +50,10 @@ asm updateMouse
LDY #$40
JMP $C400 ; IIGS REQUIRES THIS HAPPEN IN IRQ
end
asm serviceCYA#0
CLC
RTS
end
//
// Check for VBL (timer) and Mouse events (atomic read and reset)
//
@ -175,6 +179,13 @@ for rom = $C100 to $C700 step $0100
params:2 = @serviceMouse
syscall($40, @params)
//
// Hook CYA IRQ handler into ProDOS IRQ chain
//
params.0 = 2
params.1 = 3
params:2 = @serviceCYA
syscall($40, @params)
//
// Set values
//
slot = rom >> 8

View File

@ -75,7 +75,7 @@ word[] rom
word saveidx
byte regidx
byte regdata
byte[] slot
byte slot
//
// Wiznet MAC address
//
@ -144,9 +144,9 @@ const ICMP_ECHO_REPLY = 0
// ICMP message format
//
struc t_icmp
byte icmp_type
byte icmp_code
word icmp_chksm
byte icmp_type
byte icmp_code
word icmp_chksm
word[2] icmp_header
end
//
@ -155,9 +155,9 @@ end
struc t_piphdr
byte[IP4ADR_SIZE] pip_src
byte[IP4ADR_SIZE] pip_dst
byte pip_zero
byte pip_proto
word pip_len
byte pip_zero
byte pip_proto
word pip_len
end
//
// UDP header
@ -180,15 +180,15 @@ end
//
// Local network parameters
//
const MAX_WIZ_CHANNELS = 4
const MAX_WIZ_CHANNELS = 4
//
// Channel protocols
//
const WIZ_PROTO_CLOSED = 0
const WIZ_PROTO_TCP = 1
const WIZ_PROTO_UDP = 2
const WIZ_PROTO_IP = 3
const WIZ_PROTO_RAW = 4
const WIZ_PROTO_CLOSED = 0
const WIZ_PROTO_TCP = 1
const WIZ_PROTO_UDP = 2
const WIZ_PROTO_IP = 3
const WIZ_PROTO_RAW = 4
//
// State transistions
//
@ -221,7 +221,7 @@ export word hookICMP
// Defines for ASM routines
//
asm equates
!SOURCE "vmsrc/plvmzp.inc"
!SOURCE "vmsrc/plvmzp.inc"
end
//
// Swap bytes in word
@ -474,9 +474,9 @@ def wizOpenUDP(localport, callback, param)
wiz=>channel_lclport = localport
wiz=>channel_recv_func = callback
wiz=>channel_recv_parm = param
pokereg(wiz=>channel_regs + WIZ_SnMR, $02) // UDP protocol
pokeregw(wiz=>channel_regs + WIZ_SnPORT, localport)
pokereg(wiz=>channel_regs + WIZ_SnMR, $02) // UDP protocol
pokereg(wiz=>channel_regs + WIZ_SnCR, $01) // OPEN
pokereg(wiz=>channel_regs + WIZ_SnCR, $01) // OPEN
return wiz
end
//
@ -541,9 +541,9 @@ def wizListenTCP(lclport, callback, param)
wiz=>channel_lclport = lclport
wiz=>channel_recv_func = callback
wiz=>channel_recv_parm = param
pokereg(wiz=>channel_regs + WIZ_SnMR, $01) // TCP protocol
pokereg(wiz=>channel_regs + WIZ_SnMR, $01) // TCP protocol
pokeregw(wiz=>channel_regs + WIZ_SnPORT, lclport)
pokereg(wiz=>channel_regs + WIZ_SnCR, $01) // OPEN
pokereg(wiz=>channel_regs + WIZ_SnCR, $01) // OPEN
while peekreg(wiz=>channel_regs + WIZ_SnSR) <> $13; loop // Wait for init
pokereg(wiz=>channel_regs + WIZ_SnCR, $02) // LISTEN
return wiz
@ -623,7 +623,7 @@ def wizSendTCP(wiz, data, len)
pokeregs(wizdata + txrr, data, splitlen)
pokeregs(wizdata, data + splitlen, len - splitlen)
//putc('(');puti(splitlen);putc(',');puti(len-splitlen);putc(')')
else
else
pokeregs(wizdata + txrr, data, len)
fin
//
@ -638,9 +638,9 @@ end
//
def wizCloseTCP(wiz)
if isuge(wiz, @wizChannel) and isult(wiz, @wizChannel + MAX_WIZ_CHANNELS * t_channel)
//
// Clear notiications on this port
//
//
// Clear notiications on this port
//
if wiz->channel_proto == WIZ_PROTO_TCP
pokereg(wiz=>channel_regs + WIZ_SnCR, $10) // CLOSE
wiz->channel_proto = WIZ_PROTO_CLOSED
@ -702,7 +702,7 @@ def wizServiceIP
wizregs = wiz=>channel_regs
wizdata = wiz=>channel_rxmem
sir = peekreg(wizregs + WIZ_SnIR)
pokereg(wiz=>channel_regs + WIZ_SnIR, sir) // Clear SnIR
pokereg(wizregs + WIZ_SnIR, sir) // Clear SnIR
when wiz->channel_proto
is WIZ_PROTO_UDP
if sir & $04
@ -739,54 +739,54 @@ def wizServiceIP
wiz->channel_state = TCP_STATE_OPEN
wend
fin
if sir & $04
//
// Receive TCP packet
//
if wiz->channel_state == TCP_STATE_OPEN
rxlen = peekregw(wizregs + WIZ_SnRSR)
rxrr = peekregw(wizregs + WIZ_SnRXRD)
rxwr = rxrr & WIZ_RXMASK
rxpkt = heapalloc(rxlen)
if rxwr + rxlen > WIZ_RXSIZE
splitlen = WIZ_RXSIZE - rxwr
peekregs(wizdata + rxwr, rxpkt, splitlen)
peekregs(wizdata, rxpkt + splitlen, rxlen - splitlen)
else
peekregs(wizdata + rxwr, rxpkt, rxlen)
if sir & $04
//
// Receive TCP packet
//
if wiz->channel_state == TCP_STATE_OPEN
rxlen = peekregw(wizregs + WIZ_SnRSR)
rxrr = peekregw(wizregs + WIZ_SnRXRD)
rxwr = rxrr & WIZ_RXMASK
rxpkt = heapalloc(rxlen)
if rxwr + rxlen > WIZ_RXSIZE
splitlen = WIZ_RXSIZE - rxwr
peekregs(wizdata + rxwr, rxpkt, splitlen)
peekregs(wizdata, rxpkt + splitlen, rxlen - splitlen)
else
peekregs(wizdata + rxwr, rxpkt, rxlen)
fin
pokeregw(wizregs + WIZ_SnRXRD, rxrr + rxlen)
pokereg(wizregs + WIZ_SnCR, $40) // RECV
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,wiz=>channel_lclport,rxpkt,rxlen,wiz=>channel_recv_parm)
heaprelease(rxpkt)
fin
pokeregw(wizregs + WIZ_SnRXRD, rxrr + rxlen)
pokereg(wizregs + WIZ_SnCR, $40) // RECV
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,wiz=>channel_lclport,rxpkt,rxlen,wiz=>channel_recv_parm)
heaprelease(rxpkt)
fin
fin
if sir & $02
//
// Close TCP socket
//
if wiz->channel_state == TCP_STATE_OPEN // Notify callback w/ len = 0
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,0,wiz=>channel_lclport,0,wiz=>channel_recv_parm)
if sir & $02
//
// Close TCP socket
//
if wiz->channel_state == TCP_STATE_OPEN // Notify callback w/ len = 0
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,0,wiz=>channel_lclport,0,wiz=>channel_recv_parm)
fin
wiz->channel_state = TCP_STATE_CLOSED
pokereg(wiz=>channel_regs + WIZ_SnCR, $10) // CLOSE
fin
if sir & $08
//
// Timeout on TCP socket
//
when wiz->channel_state
is TCP_STATE_OPEN
wiz->channel_state = TCP_STATE_CLOSING
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,wiz=>channel_lclport,0,0,wiz=>channel_recv_parm)
break
is TCP_STATE_CONNECT
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,wiz=>channel_lclport,0,0,wiz=>channel_recv_parm)
is TCP_STATE_CLOSING
wiz->channel_state = TCP_STATE_CLOSED
pokereg(wiz=>channel_regs + WIZ_SnCR, $10) // CLOSE
wend
fin
wiz->channel_state = TCP_STATE_CLOSED
pokereg(wiz=>channel_regs + WIZ_SnCR, $10) // CLOSE
fin
if sir & $08
//
// Timeout on TCP socket
//
when wiz->channel_state
is TCP_STATE_OPEN
wiz->channel_state = TCP_STATE_CLOSING
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,wiz=>channel_lclport,0,0,wiz=>channel_recv_parm)
break
is TCP_STATE_CONNECT
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,wiz=>channel_lclport,0,0,wiz=>channel_recv_parm)
is TCP_STATE_CLOSING
wiz->channel_state = TCP_STATE_CLOSED
pokereg(wiz=>channel_regs + WIZ_SnCR, $10) // CLOSE
wend
fin
wend
fin
wiz = wiz + t_channel
@ -860,7 +860,9 @@ for slot = $90 to $F0 step $10
regdata = slot + 3
_pokedata.1 = regdata
_peekdata.1 = regdata
pokeio(slot, $03) // Auto-increment indirect I/F + enable ping
repeat
pokeio(slot, $03) // Auto-increment indirect I/F + enable ping
until peekio(slot) == $03
//
// The following looks redundant, but it sets up the peek/poke locations
// for peekreg(s)/pokereg(s)
@ -871,6 +873,7 @@ for slot = $90 to $F0 step $10
//
// Initialize common registers
//
wizMAC[5] = slot >> 4 // Slighty unique MAC address
pokeregs(WIZ_SHAR, @wizMAC, 6) // MAC addr
pokeregw(WIZ_RTR, 5000) // Timeout period to 500ms
pokereg(WIZ_RMSR, $55) // 2K Rx memory/channel

View File

@ -206,7 +206,7 @@ repeat
optsSRV = 255
DHCP.dhcp_secs.1 = retry
iNet:sendUDP(portDHCP, 0, DHCP_SERVER_PORT, @DHCP, @optsSRV - @DHCP + 1)
for timeout = 0 to 1000
for timeout = 0 to 4000
iNet:serviceIP()
if optsOP.2 == DHCP_ACK
break

View File

@ -276,7 +276,7 @@ def compiler(defptr)#0
^codeptr = $48; codeptr++ // PHA
fin
if not X_IS_IFP
*codeptr = $E0A6 // LDX IFP
*codeptr = ifp8+$A6 // LDX IFP
codeptr = codeptr + 2
X_IS_IFP = TRUE
fin
@ -450,9 +450,9 @@ def compiler(defptr)#0
fin
codeptr->0 = $A0 // LDY #$0000
codeptr=>1 = $0000
codeptr=>3 = $E785 // STA TMP
codeptr=>3 = tmp8+$85 // STA TMP
codeptr=>5 = $3868 // PLA; SEC
codeptr=>7 = $E7E5 // SBC TMP
codeptr=>7 = tmp8+$E5 // SBC TMP
codeptr=>9 = $0350 // BVC +3
codeptr->11 = $49 // EOR #$8000
codeptr=>12 = $8000
@ -562,10 +562,10 @@ def compiler(defptr)#0
codeptr=>0 = $10E2 // SEP #$10 -> 8 BIT X/Y
codeptr->2 = $A9 // LDA #imm
codeptr=>3 = codeptr + 12
codeptr=>5 = $F285 // STA IP
codeptr=>5 = ip8+$85 // STA IP
codeptr=>7 = $00A0 // LDY #$00
codeptr->9 = $4C // JMP FETCHOP
codeptr=>10 = $00F1 // FETCHOP
codeptr=>10 = fetchop // FETCHOP
codeptr->12 = opcode // OP
when opcode
is $54 // CALL
@ -611,9 +611,9 @@ def compiler(defptr)#0
if not A_IS_TOS
^codeptr = $68; codeptr++ // PLA
fin
codeptr=>0 = $E785 // STA TMP
codeptr=>0 = tmp8+$85 // STA TMP
codeptr=>2 = $20E2 // SEP #$20 -> 8 BIT ACCUM/MEM
codeptr=>4 = $E7B2 // LDA (TMP)
codeptr=>4 = tmp8+$B2 // LDA (TMP)
codeptr=>6 = $20C2 // REP #$20 -> 16 BIT ACCUM/MEM
codeptr->8 = $29 // AND #$00FF
codeptr=>9 = $00FF
@ -625,8 +625,8 @@ def compiler(defptr)#0
if not A_IS_TOS
^codeptr = $68; codeptr++ // PLA
fin
codeptr=>0 = $E785 // STA TMP
codeptr=>2 = $E7B2 // LDA (TMP)
codeptr=>0 = tmp8+$85 // STA TMP
codeptr=>2 = tmp8+$B2 // LDA (TMP)
codeptr = codeptr + 4
A_IS_TOS = TRUE // PHA
break
@ -638,7 +638,7 @@ def compiler(defptr)#0
^codeptr = $48; codeptr++ // PHA
fin
if not X_IS_IFP
*codeptr = $E0A6 // LDX IFP
*codeptr = ifp8+$A6 // LDX IFP
codeptr = codeptr + 2
X_IS_IFP = TRUE
fin
@ -656,7 +656,7 @@ def compiler(defptr)#0
^codeptr = $48; codeptr++ // PHA
fin
if not X_IS_IFP
*codeptr = $E0A6 // LDX IFP
*codeptr = ifp8+$A6 // LDX IFP
codeptr = codeptr + 2
X_IS_IFP = TRUE
fin
@ -675,21 +675,21 @@ def compiler(defptr)#0
//
// Ensure we only do byte sized accesses to H/W
//
codeptr=>0 = $20E2 // SEP #$20 -> 8 BIT ACCUM/MEM
codeptr->2 = $AD // LDA abs
codeptr=>0 = $20E2 // SEP #$20 -> 8 BIT ACCUM/MEM
codeptr->2 = $AD // LDA abs
codeptr=>3 = dest
codeptr=>5 = $20C2 // REP #$20 -> 16 BIT ACCUM/MEM
codeptr->7 = $29 // AND #$00FF
codeptr=>5 = $20C2 // REP #$20 -> 16 BIT ACCUM/MEM
codeptr->7 = $29 // AND #$00FF
codeptr=>8 = $00FF
codeptr = codeptr + 10
else
codeptr->0 = $AD // LDA abs
codeptr->0 = $AD // LDA abs
codeptr=>1 = dest
codeptr->3 = $29 // AND #$00FF
codeptr->3 = $29 // AND #$00FF
codeptr=>4 = $00FF
codeptr = codeptr + 6
fin
A_IS_TOS = TRUE // PHA
A_IS_TOS = TRUE // PHA
break
is $6A // LAW
dest = *(bytecode+i+1)
@ -711,7 +711,7 @@ def compiler(defptr)#0
^codeptr = $68; codeptr++ // PLA
fin
if not X_IS_IFP
*codeptr = $E0A6 // LDX IFP
*codeptr = ifp8+$A6 // LDX IFP
codeptr = codeptr + 2
X_IS_IFP = TRUE
fin
@ -738,7 +738,7 @@ def compiler(defptr)#0
^codeptr = $68; codeptr++ // PLA
fin
if not X_IS_IFP
*codeptr = $E0A6 // LDX IFP
*codeptr = ifp8+$A6 // LDX IFP
codeptr = codeptr + 2
X_IS_IFP = TRUE
fin
@ -757,10 +757,10 @@ def compiler(defptr)#0
if not A_IS_TOS
^codeptr = $68; codeptr++ // PLA
fin
codeptr=>0 = $E785 // STA TMP
codeptr=>0 = tmp8+$85 // STA TMP
codeptr->2 = $68 // PLA
codeptr=>3 = $20E2 // SEP #$20 -> 8 BIT ACCUM/MEM
codeptr=>5 = $E792 // STA (TMP)
codeptr=>5 = tmp8+$92 // STA (TMP)
codeptr=>7 = $20C2 // REP #$20 -> 16 BIT ACCUM/MEM
codeptr = codeptr + 9
A_IS_TOS = FALSE
@ -770,9 +770,9 @@ def compiler(defptr)#0
if not A_IS_TOS
^codeptr = $68; codeptr++ // PLA
fin
codeptr=>0 = $E785 // STA TMP
codeptr=>0 = tmp8+$85 // STA TMP
codeptr->2 = $68 // PLA
codeptr=>3 = $E792 // STA (TMP)
codeptr=>3 = tmp8+$92 // STA (TMP)
codeptr = codeptr + 5
A_IS_TOS = FALSE
break
@ -848,9 +848,9 @@ def compiler(defptr)#0
if not A_IS_TOS
^codeptr = $68; codeptr++ // PLA
fin
codeptr=>0 = $E785 // STA TMP
codeptr=>0 = tmp8+$85 // STA TMP
codeptr=>2 = $3868 // PLA; SEC
codeptr=>4 = $E7E5 // SBC TMP
codeptr=>4 = tmp8+$E5 // SBC TMP
codeptr = codeptr + 6
A_IS_TOS = TRUE
break
@ -881,10 +881,10 @@ def compiler(defptr)#0
codeptr=>0 = $10E2 // SEP #$10 -> 8 BIT X/Y
codeptr->2 = $A9 // LDA #imm
codeptr=>3 = codeptr + 12
codeptr=>5 = $F285 // STA IP
codeptr=>5 = ip8+$85 // STA IP
codeptr=>7 = $00A0 // LDY #$00
codeptr->9 = $4C // JMP FETCHOP
codeptr=>10 = $00F1 // FETCHOP
codeptr=>10 = fetchop // FETCHOP
codeptr=>12 = $C000+opcode // OPCODE; NATV CODE
codeptr = codeptr + 14
X_IS_IFP = FALSE
@ -1076,10 +1076,10 @@ def compiler(defptr)#0
// SUB
//
//puts("SUBBRGE "); puti(dest)
codeptr=>0 = $E785 // STA TMP
codeptr=>0 = tmp8+$85 // STA TMP
codeptr=>2 = $A3+(TOS<<8) // LDA S,TOS
codeptr->4 = $68 // SEC
codeptr=>5 = $E7E5 // SBC TMP
codeptr->4 = $38 // SEC
codeptr=>5 = tmp8+$E5 // SBC TMP
codeptr=>7 = $83+(TOS<<8) // STA S,TOS
codeptr = codeptr + 9
fin
@ -1133,16 +1133,16 @@ def compiler(defptr)#0
^codeptr = $68; codeptr++ // PLA
fin
if not X_IS_IFP
*codeptr = $E0A6 // LDX IFP
*codeptr = ifp8+$A6 // LDX IFP
codeptr = codeptr + 2
X_IS_IFP = TRUE
fin
codeptr=>0 = $E785 // STA TMP
codeptr=>0 = tmp8+$85 // STA TMP
codeptr=>2 = $B5+(j<<8) // LDA dp,X
codeptr->4 = $29 // AND #$00FF
codeptr=>5 = $00FF
codeptr->7 = $18 // CLC
codeptr=>8 = $E765 // ADC TMP
codeptr=>8 = tmp8+$65 // ADC TMP
codeptr = codeptr + 10
A_IS_TOS = TRUE // PHA
break
@ -1154,7 +1154,7 @@ def compiler(defptr)#0
^codeptr = $68; codeptr++ // PLA
fin
if not X_IS_IFP
*codeptr = $E0A6 // LDX IFP
*codeptr = ifp8+$A6 // LDX IFP
codeptr = codeptr + 2
X_IS_IFP = TRUE
fin
@ -1174,7 +1174,7 @@ def compiler(defptr)#0
//
// Ensure only byte sized accesses to H/W addresses
//
codeptr=>0 = $E785 // STA TMP
codeptr=>0 = tmp8+$85 // STA TMP
codeptr=>2 = $20E2 // SEP #$20 -> 8 BIT ACCUM/MEM
codeptr->4 = $AD // LDA abs
codeptr=>5 = dest
@ -1182,16 +1182,16 @@ def compiler(defptr)#0
codeptr->9 = $29 // AND #$00FF
codeptr=>10 = $00FF
codeptr->12 = $18 // CLC
codeptr=>13 = $E765 // ADC TMP
codeptr=>13 = tmp8+$65 // ADC TMP
codeptr = codeptr + 15
else
codeptr=>0 = $E785 // STA TMP
codeptr=>0 = tmp8+$85 // STA TMP
codeptr->2 = $AD // LDA abs
codeptr=>3 = dest
codeptr->5 = $29 // AND #$00FF
codeptr=>6 = $00FF
codeptr->8 = $18 // CLC
codeptr=>9 = $E765 // ADC TMP
codeptr=>9 = tmp8+$65 // ADC TMP
codeptr = codeptr + 11
fin
A_IS_TOS = TRUE // PHA
@ -1215,16 +1215,16 @@ def compiler(defptr)#0
^codeptr = $68; codeptr++ // PLA
fin
if not X_IS_IFP
*codeptr = $E0A6 // LDX IFP
*codeptr = ifp8+$A6 // LDX IFP
codeptr = codeptr + 2
X_IS_IFP = TRUE
fin
codeptr=>0 = $E785 // STA TMP
codeptr=>0 = tmp8+$85 // STA TMP
codeptr=>2 = $B5+(j<<8) // LDA dp,X
codeptr->4 = $29 // AND #$00FF
codeptr=>5 = $00FF
codeptr->7 = $0A // ASL
codeptr=>8 = $E765 // ADC TMP
codeptr=>8 = tmp8+$65 // ADC TMP
codeptr = codeptr + 10
A_IS_TOS = TRUE // PHA
break
@ -1236,7 +1236,7 @@ def compiler(defptr)#0
^codeptr = $68; codeptr++ // PLA
fin
if not X_IS_IFP
*codeptr = $E0A6 // LDX IFP
*codeptr = ifp8+$A6 // LDX IFP
codeptr = codeptr + 2
X_IS_IFP = TRUE
fin
@ -1258,7 +1258,7 @@ def compiler(defptr)#0
//
// Ensure only byte sized accesses to H/W addresses
//
codeptr=>0 = $E785 // STA TMP
codeptr=>0 = tmp8+$85 // STA TMP
codeptr=>2 = $20E2 // SEP #$20 -> 8 BIT ACCUM/MEM
codeptr->4 = $AD // LDA abs
codeptr=>5 = dest
@ -1266,16 +1266,16 @@ def compiler(defptr)#0
codeptr->9 = $29 // AND #$00FF
codeptr=>10 = $00FF
codeptr->12 = $0A // ASL
codeptr=>13 = $E765 // ADC TMP
codeptr=>13 = tmp8+$65 // ADC TMP
codeptr = codeptr + 15
else
codeptr=>0 = $E785 // STA TMP
codeptr=>0 = tmp8+$85 // STA TMP
codeptr->2 = $AD // LDA abs
codeptr=>3 = dest
codeptr->5 = $29 // AND #$00FF
codeptr=>6 = $00FF
codeptr->8 = $0A // ASL
codeptr=>9 = $E765 // ADC TMP
codeptr=>9 = tmp8+$65 // ADC TMP
codeptr = codeptr + 11
fin
A_IS_TOS = TRUE // PHA
@ -1292,7 +1292,7 @@ def compiler(defptr)#0
codeptr=>4 = $6D18 // CLC; ADC abs
codeptr=>6 = dest
codeptr = codeptr + 8
A_IS_TOS = TRUE // PHA
A_IS_TOS = TRUE // PHA
break
is $FE // NOPed out earlier by SELect
break

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,7 @@ JITUNE = rel/apple/JITUNE\#FE1000
SOS = rel/apple/SOS\#FE1000
ROD = rel/ROD\#FE1000
SIEVE = rel/SIEVE\#FE1000
PRIMEGAP = rel/PRIMEGAP\#FE1000
ARGS = rel/ARGS\#FE1000
SPIPORT = rel/apple/SPIPORT\#FE1000
SDFAT = rel/apple/SDFAT\#FE1000
@ -85,7 +86,7 @@ TXTTYPE = .TXT
#SYSTYPE = \#FF2000
#TXTTYPE = \#040000
apple: $(PLVMZP_APL) $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVMJIT) $(PLVM802) $(PLVM03) $(CMD) $(CMDJIT) $(JIT) $(JIT16) $(JITUNE) $(SOSCMD) $(PLASMAPLASM) $(CODEOPT) $(ARGS) $(MEMMGR) $(MEMTEST) $(FIBER) $(FIBERTEST) $(LONGJMP) $(ED) $(MON) $(SOS) $(ROD) $(SIEVE) $(MOUSE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(TFTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(GRAFIX) $(GFXDEMO) $(DGR) $(DGRTEST) $(FILEIO_APL) $(CONIO_APL) $(JOYBUZZ) $(PORTIO) $(SPIPORT) $(SDFAT) $(FATCAT) $(FATGET) $(FATPUT) $(FATWDSK) $(FATRDSK) $(SANE) $(FPSTR) $(FPU) $(SANITY) $(LZ4) $(LZ4CAT) $(RPNCALC) $(SNDSEQ) $(PLAYSEQ)
apple: $(PLVMZP_APL) $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVMJIT) $(PLVM802) $(PLVM03) $(CMD) $(CMDJIT) $(JIT) $(JIT16) $(JITUNE) $(SOSCMD) $(PLASMAPLASM) $(CODEOPT) $(ARGS) $(MEMMGR) $(MEMTEST) $(FIBER) $(FIBERTEST) $(LONGJMP) $(ED) $(MON) $(SOS) $(ROD) $(SIEVE) $(PRIMEGAP) $(MOUSE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(TFTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(GRAFIX) $(GFXDEMO) $(DGR) $(DGRTEST) $(FILEIO_APL) $(CONIO_APL) $(JOYBUZZ) $(PORTIO) $(SPIPORT) $(SDFAT) $(FATCAT) $(FATGET) $(FATPUT) $(FATWDSK) $(FATRDSK) $(SANE) $(FPSTR) $(FPU) $(SANITY) $(LZ4) $(LZ4CAT) $(RPNCALC) $(SNDSEQ) $(PLAYSEQ)
-rm vmsrc/plvmzp.inc
c64: $(PLVMZP_C64) $(PLASM) $(PLVM) $(PLVMC64)
@ -243,6 +244,10 @@ $(SIEVE): samplesrc/sieve.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMW < samplesrc/sieve.pla > samplesrc/sieve.a
acme --setpc 4094 -o $(SIEVE) samplesrc/sieve.a
$(PRIMEGAP): samplesrc/primegap.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMW < samplesrc/primegap.pla > samplesrc/primegap.a
acme --setpc 4094 -o $(PRIMEGAP) samplesrc/primegap.a
$(SANE): libsrc/sane.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < libsrc/sane.pla > libsrc/sane.a
acme --setpc 4094 -o $(SANE) libsrc/sane.a

View File

@ -56,6 +56,7 @@ cp rel/apple/DGRTEST#FE1000 prodos/demos/DGRTEST.REL
cp rel/RPNCALC#FE1000 prodos/demos/RPNCALC.REL
cp rel/LZ4CAT#FE1000 prodos/demos/LZ4CAT.REL
cp rel/ROD#FE1000 prodos/demos/ROD.REL
cp rel/PRIMEGAP#FE1000 prodos/demos/PRIMEGAP.REL
mkdir prodos/demos/rogue
cp rel/ROGUE#FE1000 prodos/demos/rogue/ROGUE.REL

View File

@ -0,0 +1,41 @@
include "inc/cmdsys.plh"
var a, b, i,loprim,hiprim
def getnum
var str, num
num = 0
str = gets(':'|$80) + 1
while ^str >= '0' and ^str <= '9'
num = num * 10 + (^str - '0')
str++
loop
return num
end
def prim(x)
var i
i = 3
while i*i < x and x % i; i = i + 2; loop
return x < i*i
end
puts("Geben Sie den oberen Grenzwert ein")
a = getnum
puts("Geben Sie die minimale Differenz ein")
b = getnum
loprim, hiprim, i = 1, 1, 3
while i <= a and hiprim-loprim < b
if prim(i)
loprim = hiprim
hiprim = i
fin
i = i + 2
loop
if hiprim-loprim < b
puts("keine Loesung gefunden !")
else
puti(hiprim); putc(' '); puti(loprim); putc(' '); puti(hiprim-loprim)
fin
putln
done

View File

@ -260,7 +260,7 @@ def writeUDP(ipsrc, portsrc, data, len, param)
end
def servUDP(ipsrc, portsrc, data, len, param)
byte info[24]
when *data
is RRQ // Read request
//
@ -345,7 +345,7 @@ end
if !iNet:initIP()
return -1
fin
puts("TFTP Server Version 0.1\n")
puts("TFTP Server Version 2.0 Dev\n")
portTFTP = iNet:openUDP(TFTP_PORT, @servUDP, 0)
//
// Alloc aligned file/io buffers

View File

@ -50,7 +50,6 @@ t_token keywords[] = {
BYTE_TOKEN, 'R', 'E', 'S',
BYTE_TOKEN, 'B', 'Y', 'T', 'E',
BYTE_TOKEN, 'C', 'H', 'A', 'R',
BYTE_TOKEN, 'R', 'E', 'S',
WORD_TOKEN, 'W', 'O', 'R', 'D',
WORD_TOKEN, 'V', 'A', 'R',
CONST_TOKEN, 'C', 'O', 'N', 'S', 'T',

View File

@ -651,9 +651,13 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
cfnparms = 0; cfnvals = 1;
type &= ~FUNC_TYPE;
}
else if (type & (BYTE_TYPE | BPTR_TYPE))
else if (type & (BPTR_TYPE)) // Prefer the pointer type.
valseq = gen_lb(valseq);
else if (type & (WORD_TYPE | WPTR_TYPE))
else if (type & (WPTR_TYPE))
valseq = gen_lw(valseq);
else if (type & (BYTE_TYPE))
valseq = gen_lb(valseq);
else if (type & (WORD_TYPE))
valseq = gen_lw(valseq);
else
parse_error("What are we dereferencing?");

View File

@ -461,9 +461,13 @@ def parse_value(codeseq, r_val)#2
valseq = gen_op(valseq, ICAL_CODE)
stackdepth = stackdepth + cfnvals - 1
type = type & ~FUNC_TYPE
elsif type & (BYTE_TYPE | BPTR_TYPE)
elsif type & (BPTR_TYPE) // Prefer the pointer type.
valseq = gen_op(valseq, LB_CODE)
elsif type & (WORD_TYPE | WPTR_TYPE)
elsif type & (WPTR_TYPE)
valseq = gen_op(valseq, LW_CODE)
elsif type & (BYTE_TYPE)
valseq = gen_op(valseq, LB_CODE)
elsif type & (WORD_TYPE)
valseq = gen_op(valseq, LW_CODE)
else
exit_err(ERR_INVAL|ERR_CODE)

View File

@ -152,7 +152,6 @@ byte = "AND", LOGIC_AND_TKN
byte = "NOT", LOGIC_NOT_TKN
byte = "RES", BYTE_TKN
byte = "VAR", WORD_TKN
byte = "RES", BYTE_TKN
byte = "WORD", WORD_TKN
byte = "CHAR", BYTE_TKN
byte = "BYTE", BYTE_TKN

View File

@ -1328,6 +1328,7 @@ end
// Command line processor
//
def docmds#0
strcpy(getlnbuf, @cmdln)
while 1
if ^getlnbuf
strcpy(@cmdln, getlnbuf)
@ -1398,7 +1399,7 @@ loop
//
// Set system path
//
strcat(strcpy(@sysmods, $280), "SYS/")) // This is the path to CMD
strcat(strcpy(@sysmods, $300), "SYS/")) // This is the path to CMD
syspath = @sysmods // Update external interface table
syscmdln = @cmdln
//
@ -1406,7 +1407,7 @@ syscmdln = @cmdln
//
autorun = open(@autorun)
if autorun
^getlnbuf = read(autorun, getlnbuf + 1, 128)
cmdln = read(autorun, @cmdln+1, 81)
close(0)
else
//
@ -1414,6 +1415,6 @@ else
//
prstr("MEM FREE:$"); prword(availheap); crout
fin
perr = 0
pfxop(@prefix, GET_PFX)
docmds
done

View File

@ -41,7 +41,7 @@ end
//
const jitcomp = $03E2
const jitcodeptr = $03E4
const jitmod = $02E0
const jitmod = $02F0
//
// Pedefined functions.
//
@ -1399,6 +1399,7 @@ def docmds#0
loadmod(jitmod) // Cannot do this in init code - it will overwrite it!
xheap = $0400 // Reset heap to point at low memory
xheaptop = $A000 // Top below JITC
strcpy(getlnbuf, @cmdln)
while 1
if ^getlnbuf
strcpy(@cmdln, getlnbuf)
@ -1469,7 +1470,7 @@ loop
//
// Set system path
//
strcat(strcpy(@sysmods, $280), "SYS/")) // This is the path to CMD
strcat(strcpy(@sysmods, $300), "SYS/")) // This is the path to CMD
syspath = @sysmods // Update external interface table
syscmdln = @cmdln
//
@ -1477,7 +1478,7 @@ syscmdln = @cmdln
//
autorun = open(@autorun)
if autorun
^getlnbuf = read(autorun, getlnbuf + 1, 128)
cmdln = read(autorun, @cmdln+1, 81)
close(0)
else
//
@ -1485,6 +1486,6 @@ else
//
prstr("MEM FREE:$"); prword(availheap); crout
fin
perr = 0
pfxop(@prefix, GET_PFX)
docmds
done

View File

@ -8,10 +8,16 @@ LCBNK1 = $08
JITCOMP = $03E2
JITCODE = $03E4
!SOURCE "vmsrc/plvmzp.inc"
JMP CMDMOVE
_CMDBEGIN = *
!PSEUDOPC $1000 {
!SOURCE "vmsrc/apple/cmdjit.a"
_CMDEND = *
}
;*
;* MOVE CMD DOWN TO $1000-$2000
;*
LDA #<_CMDBEGIN
CMDMOVE LDA #<_CMDBEGIN
STA SRCL
LDA #>_CMDBEGIN
STA SRCH
@ -19,6 +25,7 @@ JITCODE = $03E4
STY DSTL
LDX #$10
STX DSTH
INX
- LDA (SRC),Y
STA (DST),Y
INY
@ -44,8 +51,3 @@ JITCODE = $03E4
TXS
LDX #ESTKSZ/2 ; INIT EVAL STACK INDEX
JMP $1000
_CMDBEGIN = *
!PSEUDOPC $1000 {
!SOURCE "vmsrc/apple/cmdjit.a"
_CMDEND = *
}

View File

@ -1095,7 +1095,7 @@ PAGE0 = *
;*
INX ; DROP
INY ; NEXTOP
LDA $FFFF,Y ; FETCHOP @ $F3, IP MAPS OVER $FFFF @ $F4
LDA $FFFF,Y ; FETCHOP @ $F1, IP MAPS OVER $FFFF @ $F2
STA OPIDX
JMP (OPTBL)
}

View File

@ -38,7 +38,7 @@ IPL = IP
IPH = IPL+1
OPIDX = FETCHOP+6
OPPAGE = OPIDX+1
STRBUF = $0280
STRBUF = $0300
INTERP = $03D0
;******************************
;* *
@ -285,7 +285,7 @@ PAGE0 = *
!PSEUDOPC DROP {
INX ; DROP @ $EF
INY ; NEXTOP @ $F0
LDA $FFFF,Y ; FETCHOP @ $F3, IP MAPS OVER $FFFF @ $F4
LDA $FFFF,Y ; FETCHOP @ $F1, IP MAPS OVER $FFFF @ $F2
STA OPIDX
JMP (OPTBL) ; OPIDX AND OPPAGE MAP OVER OPTBL
}

View File

@ -126,7 +126,7 @@ PAGE0 = *
;*
INX ; DROP
INY ; NEXTOP
LDA $FFFF,Y ; FETCHOP @ $F3, IP MAPS OVER $FFFF @ $F4
LDA $FFFF,Y ; FETCHOP @ $F1, IP MAPS OVER $FFFF @ $F2
STA OPIDX
JMP (OPTBL)
}

View File

@ -63,8 +63,8 @@ OPPAGE = OPIDX+1
;
; BUFFER ADDRESSES
;
STRBUF = $0280
JITMOD = $02E0
STRBUF = $0300
JITMOD = $02F0
INTERP = $03D0
JITCOMP = $03E2
JITCODE = $03E4

View File

@ -50,8 +50,8 @@ IPL = IP
IPH = IPL+1
OPIDX = FETCHOP+6
OPPAGE = OPIDX+1
STRBUF = $0280
JITMOD = $02E0
STRBUF = $0300
JITMOD = $02F0
INTERP = $03D0
JITCOMP = $03E2
JITCODE = $03E4
@ -371,7 +371,7 @@ PAGE0 = *
!PSEUDOPC DROP {
INX ; DROP @ $EF
INY ; NEXTOP @ $F0
LDA $FFFF,Y ; FETCHOP @ $F3, IP MAPS OVER $FFFF @ $F4
LDA $FFFF,Y ; FETCHOP @ $F1, IP MAPS OVER $FFFF @ $F2
STA OPIDX
JMP (OPTBL) ; OPIDX AND OPPAGE MAP OVER OPTBL
}

View File

@ -23,6 +23,15 @@ const jitcodeptr = $A0F4
const sinterp = $A0F6
const xinterp = $A0F8
const jitinterp = $A0FA
const estkh8 = $C000
const estkh = $00C0
const estkl8 = $D000
const estkl = $00D0
const ifpl8 = $E000
const ifph8 = $E100
const jmptmp = $00E6
const tmpl8 = $E700
const tmph8 = $E800
word directentry, indirectentry
//
// COPY FROM EXT MEM TO MAIN MEM.

View File

@ -502,13 +502,17 @@ void call(uword pc)
case 8: // LIBRARY STDLIB::GETS
c = POP;
putchar(c);
gets(sz);
fgets(sz, 63, stdin);
for (i = 0; sz[i]; i++)
mem_data[0x200 + i] = sz[i];
mem_data[0x200 + i] = 0;
mem_data[0x1FF] = i;
PUSH(0x1FF);
break;
case 10: // LIBRARY STDLIB::PUTH
i = UPOP;
printf("%04X", i);
break;
case 24: // LIBRARY CMDSYS::DIVMOD
a = POP;
b = POP;
@ -557,7 +561,7 @@ void interp(code *ip)
while (dsp >= esp)
printf("$%04X ", (*dsp--) & 0xFFFF);
printf("]\n");
gets(cmdline);
fgets(cmdline, 15, stdin);
}
previp = ip;
switch (*ip++)
@ -640,19 +644,23 @@ void interp(code *ip)
case 0x36: // DIVMOD
break;
case 0x38: // ADDI
PUSH(POP + BYTE_PTR(ip));
val = POP + BYTE_PTR(ip);
PUSH(val);
ip++;
break;
case 0x3A: // SUBI
PUSH(POP - BYTE_PTR(ip));
val = POP - BYTE_PTR(ip);
PUSH(val);
ip++;
break;
case 0x3C: // ANDI
PUSH(POP & BYTE_PTR(ip));
val = POP & BYTE_PTR(ip);
PUSH(val);
ip++;
break;
case 0x3E: // ORI
PUSH(POP | BYTE_PTR(ip));
val = POP | BYTE_PTR(ip);
PUSH(val);
ip++;
break;
/*