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

Add prelim ethernet, improve value parsing.

This commit is contained in:
David Schmenk 2015-01-06 13:51:12 -08:00
parent 06da0d260a
commit 55f4035122
8 changed files with 825 additions and 400 deletions

View File

@ -9,6 +9,8 @@ ED = ED\#FF2000
SB = SB\#FF2000
ROD = ROD\#FE1000
SIEVE = SIEVE\#FE1000
UTHERNET= UTHERNET\#FE1000
ETHERIP = ETHERIP\#FE1000
ROGUE = ROGUE\#FE1000
ROGUEIO = ROGUEIO\#FE1000
ROGUEMAP= ROGUEMAP\#FE1000
@ -38,7 +40,7 @@ TXTTYPE = .TXT
#SYSTYPE = \#FF2000
#TXTTYPE = \#040000
all: $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03) $(CMD) $(PROFILE) $(ED) $(SB) $(ROD) $(SIEVE) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(ROGUEIO) $(HGR1)
all: $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03) $(CMD) $(PROFILE) $(ED) $(SB) $(ROD) $(SIEVE) $(UTHERNET) $(ETHERIP) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(ROGUEIO) $(HGR1)
clean:
-rm *FE1000 *FF2000 $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03)
@ -103,6 +105,14 @@ $(SIEVE): samplesrc/sieve.pla $(PLVM02) $(PLASM)
./$(PLASM) -AM < samplesrc/sieve.pla > samplesrc/sieve.a
acme --setpc 4094 -o $(SIEVE) samplesrc/sieve.a
$(UTHERNET): samplesrc/uthernet.pla $(PLVM02) $(PLASM)
./$(PLASM) -AM < samplesrc/uthernet.pla > samplesrc/uthernet.a
acme --setpc 4094 -o $(UTHERNET) samplesrc/uthernet.a
$(ETHERIP): samplesrc/etherip.pla $(PLVM02) $(PLASM)
./$(PLASM) -AM < samplesrc/etherip.pla > samplesrc/etherip.a
acme --setpc 4094 -o $(ETHERIP) samplesrc/etherip.a
$(ROGUE): samplesrc/rogue.pla $(PLVM02) $(PLASM)
./$(PLASM) -AM < samplesrc/rogue.pla > samplesrc/rogue.a
acme --setpc 4094 -o $(ROGUE) samplesrc/rogue.a

173
src/samplesrc/etherip.pla Normal file
View File

@ -0,0 +1,173 @@
import STDLIB
predef syscall, call, memset, getc, gets, putc, puts, putln
predef memset, memcpy, modaddr, modexec
predef heapmark, heapallocalign, heapalloc, heaprelease, heapavail
byte MACHID
end
//
// Ethernet adapter driver
//
byte etherlib = "UTHERNET", 0
struc t_edrvr
word fillMAC
word writeFrame
word readFrame
word nextEvent
end
word edrvr
//
// IP datagram header
//
const HW_ETHER = $0100 // BE format
const PROTO_IP = $0008 // BE format
struc t_ip
byte ip_vers_hlen
byte ip_service
word ip_length
word ip_id
word ip_flags_fragofst
byte ip_ttl
byte ip_proto
word ip_checksum
byte[4] ip_src
byte[4] ip_dst
byte[] ip_options
end
//
// ARP packet
//
const PAYLOAD_ARP = $0608 // BE format
const ARP_REQST = $0100 // BE format
const ARP_REPLY = $0200 // BE format
struc t_arp
word arp_hw
word arp_proto
byte arp_hlen
byte arp_plen
word arp_op
byte[6] arp_senderha
byte[4] arp_senderip
byte[6] arp_targha
byte[4] arp_ragip
end
byte hARP = $FF,$FF,$FF,$FF,$FF,$FF // BCAST
byte MAC = $00,$0A,$99,$1E,$02,$00
byte = $08, $06 // ARP payload
byte pARP = $00, $01 // HW TYPE
byte = $08, $00 // PROTO TYPE
byte = 6 // HLEN
byte = 4 // PLEN
byte = $00, $01 // OP
byte[6] senderha = $00,$0A,$99,$1E,$02,$00
byte[4] senderip = 192,168,123,10
byte[6] targha
byte[4] targip = 192,168,123,1
const maxesize = 1518
const ehdrsize = 14
//
// Receive packet
//
byte[maxesize] recvpkt
//
// Defines for ASM routines
//
asm equates
!SOURCE "vmsrc/plvmzp.inc"
end
//
// ASM utility functions
//
// Swap bytes in word
//
asm swab
LDA ESTKL,X
LDY ESTKH,X
STA ESTKH,X
STY ESTKL,X
RTS
end
//
// CHECKSUM BE format
// checksum(BUF, LEN)
//
asm checksum
LDY #$00
LDA ESTKL+1,X
STY ESTKL+1,X
STA SRCL
LDA ESTKH+1,X
STY ESTKH+1,X
STA SRCH
LSR ESTKH,X ; CONVERT BYTE LEN TO WORD LEN
LDA ESTKL,X
ROR
ADC #$00
STA ESTKL,X
BEQ CHKLP
INC ESTKH,X
CHKLP LDA (SRC),Y
PHA
INY
BNE +
INC SRCH
+ LDA (SRC),Y
CLC
ADC ESTKH+1,X
STA ESTKH+1,X
PLA
ADC ESTKL+1,X
STA ESTKL+1,X
INY
BNE +
INC SRCH
+ DEC ESTKL,X
BNE CHKLP
DEC ESTKH,X
BNE CHKLP
INX
LDA ESTKL,X
EOR #$FF
STA ESTKL,X
LDA ESTKH,X
EOR #$FF
STA ESTKH,X
RTS
end
//
// DEBUG
//
def putln
return putc($0D)
end
def putb(hexb)
return call($FDDA, hexb, 0, 0, 0)
end
def puth(hex)
return call($F941, hex >> 8, hex, 0, 0)
end
def dumpfrm(packet, len)
word i
if len > 64
len = 64
fin
len = len - 1
for i = 0 to len
if (i & 7) == 0
putln
else
putc(' ')
fin
putb(^(packet+i))
next
end
if modexec(@etherlib) == 0
edrvr = modaddr(@etherlib)
edrvr=>writeFrame(@hARP, @pARP, 28)
repeat; until edrvr=>nextEvent() or ^$C000 > 127
^$C010
dumpfrm(@recvpkt, edrvr=>readFrame(@recvpkt))
fin
done

252
src/samplesrc/uthernet.pla Normal file
View File

@ -0,0 +1,252 @@
import STDLIB
predef syscall, call, memset, getc, gets, putc, puts, putln
predef memset, memcpy, modaddr, modexec
predef heapmark, heapallocalign, heapalloc, heaprelease, heapavail
byte MACHID
end
//
// Module don't free memory
//
const modkeep = $2000
const modinitkeep = $4000
//
// Module interface defined by first 4 fields:
// word fillMAC
// word writeFrame
// word readFrame
// word nextEvent
//
predef fillmac, writefrm, readfrm, nextevt
word = @fillmac, @writefrm, @readfrm, @nextevt, 0
//
// Uthernet register offsets
//
const TXDATA = $00
const RXDATA = $00
const TXCMD = $04
const TXLEN = $06
const INT_STATUS = $08
const PREG_INDEX = $0A
const PREG_DATA = $0C
const AUTO_INC = $8000
//
// Uthernet register addresses
//
word slot
byte txcmd
byte txlen
byte isq
byte pregidx
byte pregdata
//
// MAC address
//
byte MAC = $00,$0A,$99,$1E,$02,$00
//
// Ethernet header
//
struc t_ehdr
byte[6] ehdr_dstaddr
byte[6] ehdr_srcaddr
word ehdr_type
end
//
// Defines for ASM routines
//
asm equates
!SOURCE "vmsrc/plvmzp.inc"
end
//
// I/O access
//
//
// POKE WORD INTO I/O SPACE
// _pokeiow(DATA)
//
asm _pokeiow
LDA ESTKL,X
end
asm _pokeiowl
STA $C000
LDA ESTKH,X
end
asm _pokeiowh
STA $C000
RTS
end
//
// PEEK WORD FROM I/O SPACE
// _peekiow()
//
asm _peekiow
DEX
end
asm _peekiowl
LDA $C000
STA ESTKL,X
end
asm _peekiowh
LDA $C000
STA ESTKH,X
RTS
end
//
// POKE PACKET FRAME INTO I/O SPACE
// _pokefrm(BUF, LEN)
//
asm pokefrm
LDY #$00
LDA ESTKL+1,X
STA SRCL
LDA ESTKH+1,X
STA SRCH
LSR ESTKH,X ; CONVERT BYTE LEN TO WORD LEN
LDA ESTKL,X
ROR
ADC #$00
STA ESTKL,X
BEQ POKELP
INC ESTKH,X
POKELP LDA (SRC),Y
end
asm _pokefrml
STA $C000
INY
BNE +
INC SRCH
+ LDA (SRC),Y
end
asm _pokefrmh
STA $C000
INY
BNE +
INC SRCH
+ DEC ESTKL,X
BNE POKELP
DEC ESTKH,X
BNE POKELP
INX
RTS
end
//
// PEEK PACKET FRAME FROM I/O SPACE
// _peekfrm(BUF, LEN)
//
asm peekfrm
LDA ESTKL+1,X
STA DSTL
LDA ESTKH+1,X
STA DSTH
LDY ESTKL,X
BEQ PEEKLP
LDY #$00
INC ESTKH,X
end
asm _peekfrmh
PEEKLP LDA $C000
PHA
end
asm _peekfrml
LDA $C000
STA (DST),Y
PLA
INY
BNE +
INC DSTH
+ DEC ESTKL,X
BNE +
DEC ESTKH,X
BEQ EXPSW
+ STA (DST),Y
INY
BNE +
INC DSTH
+ DEC ESTKL,X
BNE PEEKLP
DEC ESTKH,X
BNE PEEKLP
EXPSW INX
RTS
end
def pokeiow(io, data)
_pokeiowl.1 = io
_pokeiowh.1 = io+1
return _pokeiow(data)
end
def peekiow(io)
_peekiowl.1 = io
_peekiowh.1 = io+1
return _peekiow()
end
def pokepreg(reg, data)
pokeiow(pregidx, reg)
return pokeiow(pregdata, data)
end
def peekpreg(reg)
pokeiow(pregidx, reg)
return peekiow(pregdata)
end
//
// Uthernet interface
//
def fillmac(pmac)
pmac=>0 = MAC:0
pmac=>2 = MAC:2
pmac=>4 = MAC:4
return pmac + 6
end
def writefrm(header, payload, size)
pokeiow(txcmd, $C0)
pokeiow(txlen, size + t_ehdr)
repeat; until peekpreg($0138) & $0100
pokefrm(header, t_ehdr)
pokefrm(payload, size)
end
def readfrm(packet)
word status, len
peekfrm(@status, 4)
if status & $0100
peekfrm(packet, len)
else
pokepreg($0102, $0140) // Skip pkt
len = 0
fin
return len
end
def nextevt
return peekiow(isq) & $3F
end
//
// Identify Uthernet card and initialize
//
for slot = $90 to $F0 step $10
if (peekiow(slot+TXCMD) & $CC3F) == $09
pokeiow(slot+PREG_INDEX, 0)
if peekiow(slot+PREG_DATA) == $630E
txcmd = slot + TXCMD
txlen = slot + TXLEN
isq = slot + INT_STATUS
pregidx = slot + PREG_INDEX
pregdata = slot + PREG_DATA
pokepreg($0114, $40) // RESET
_pokefrml.1 = slot
_pokefrmh.1 = slot+1
_peekfrml.1 = slot
_peekfrmh.1 = slot+1
pokepreg($0158, MAC:0) // MAC addr
pokepreg($015A, MAC:2) // MAC addr
pokepreg($015C, MAC:4) // MAC addr
pokepreg($0102, $0100) // Recv cfg
pokepreg($0104, $0D00) // Recv ctrl
pokepreg($0106, $8200) // Xmit cfg
pokepreg($0112, $00C0) // Line ctrl
return modkeep
fin
fin
next
//
// Not found
//
return -1
done

View File

@ -188,8 +188,8 @@ int parse_value(int rvalue)
int deref = rvalue;
int optos = opsptr;
int type = 0, value = 0, emit_value = 0;
int elem_size, elem_type;
long elem_offset = 0;
int ref_type, const_size;
long ref_offset, const_offset;
/*
* Parse pre operand operators.
*/
@ -286,6 +286,8 @@ int parse_value(int rvalue)
/*
* Parse post operand operators.
*/
ref_type = type;
ref_offset = 0;
while (scan() == OPEN_PAREN_TOKEN
|| scantoken == OPEN_BRACKET_TOKEN
|| scantoken == PTRB_TOKEN
@ -295,165 +297,14 @@ int parse_value(int rvalue)
{
switch (scantoken)
{
case OPEN_BRACKET_TOKEN:
/*
* Array
*/
if (!emit_value)
{
if (type & ADDR_TYPE)
{
if (type & LOCAL_TYPE)
emit_localaddr(value);
else
emit_globaladdr(value, 0, type);
}
else if (type & CONST_TYPE)
{
emit_const(value);
}
emit_value = 1;
}
if (type & PTR_TYPE)
emit_lw();
if (!parse_expr())
{
parse_error("Bad expression");
return (0);
}
if (scantoken != CLOSE_BRACKET_TOKEN)
{
parse_error("Missing closing bracket");
return (0);
}
if (type & WORD_TYPE)
{
//type |= WPTR_TYPE;
type = WPTR_TYPE;
emit_indexword();
}
else
{
//type |= BPTR_TYPE;
type = BPTR_TYPE;
emit_indexbyte();
}
//type &= ~(ADDR_TYPE | CONST_TYPE);
break;
case PTRB_TOKEN:
case PTRW_TOKEN:
if (!emit_value)
{
if (type & FUNC_TYPE)
emit_call(value, type);
else if (type & VAR_TYPE)
{
if (type & LOCAL_TYPE)
(type & BYTE_TYPE) ? emit_llb(value + elem_offset) : emit_llw(value + elem_offset);
else
(type & BYTE_TYPE) ? emit_lab(value, elem_offset, type) : emit_law(value, elem_offset, type);
}
else
(type & BPTR_TYPE) ? emit_lb() : emit_lw();
emit_value = 1;
}
else
(type & BPTR_TYPE) ? emit_lb() : emit_lw();
type &= ~(VAR_TYPE | ADDR_TYPE);
type |= WORD_TYPE;
scantoken = scantoken == PTRB_TOKEN ? DOT_TOKEN : COLON_TOKEN;
case DOT_TOKEN:
case COLON_TOKEN:
/*
* Structure member offset or array of arrays
*/
elem_type = (scantoken == DOT_TOKEN) ? BPTR_TYPE : WPTR_TYPE;
if (parse_constval(&elem_offset, &elem_size))
{
/*
* Constant member offset
*/
if (!emit_value)
{
if (type & VAR_TYPE)
{
elem_type = (type & ~VAR_TYPE) | (elem_type == BPTR_TYPE ? BYTE_TYPE : WORD_TYPE);
}
else if (type & CONST_TYPE)
{
value += elem_offset;
emit_const(value);
elem_offset = 0;
emit_value = 1;
}
else // FUNC_TYPE
{
emit_globaladdr(value, elem_offset, type);
elem_offset = 0;
emit_value = 1;
}
}
else
{
if (elem_offset != 0)
{
emit_const(elem_offset);
emit_op(ADD_TOKEN);
elem_offset = 0;
}
}
}
else if (scantoken == OPEN_BRACKET_TOKEN)
{
/*
* Array of arrays
*/
if (!emit_value)
{
if (type & ADDR_TYPE)
{
if (type & LOCAL_TYPE)
emit_localaddr(value + elem_offset);
else
emit_globaladdr(value, elem_offset, type);
}
else if (type & CONST_TYPE)
{
emit_const(value + elem_offset);
}
elem_offset = 0;
emit_value = 1;
}
while (parse_expr())
{
if (scantoken != COMMA_TOKEN)
break;
emit_indexword();
emit_lw();
}
if (scantoken != CLOSE_BRACKET_TOKEN)
{
parse_error("Missing closing bracket");
return (0);
}
if (elem_type & WPTR_TYPE)
emit_indexword();
else
emit_indexbyte();
}
else
{
parse_error("Invalid member offset");
return (0);
}
type = elem_type;
break;
case OPEN_PAREN_TOKEN:
/*
* Function call
*/
if (emit_value)
{
if (ref_type & PTR_TYPE)
(ref_type & BPTR_TYPE) ? emit_lb() : emit_lw();
if (scan_lookahead() != CLOSE_PAREN_TOKEN)
emit_push();
}
@ -469,21 +320,21 @@ int parse_value(int rvalue)
parse_error("Missing closing parenthesis");
return (0);
}
if (type & (FUNC_TYPE | CONST_TYPE))
emit_call(value, type);
if (ref_type & (FUNC_TYPE | CONST_TYPE))
emit_call(value, ref_type);
else
{
if (!emit_value)
{
if (type & VAR_TYPE)
if (ref_type & VAR_TYPE)
{
if (type & LOCAL_TYPE)
emit_llw(value + elem_offset);
emit_llw(value + ref_offset);
else
emit_law(value, elem_offset, type);
emit_law(value, ref_offset, type);
}
else if (type & PTR_TYPE)
emit_lw();
if (ref_type & PTR_TYPE)
(type & BPTR_TYPE) ? emit_lb() : emit_lw();
}
else
if (cparams)
@ -491,39 +342,160 @@ int parse_value(int rvalue)
emit_ical();
}
emit_value = 1;
type = WORD_TYPE; //(type & ~(FUNC_TYPE | CONST_TYPE)) | WORD_TYPE;
ref_type = WORD_TYPE;
break;
case OPEN_BRACKET_TOKEN:
/*
* Array of arrays
*/
if (!emit_value)
{
if (type & ADDR_TYPE)
{
if (type & LOCAL_TYPE)
emit_localaddr(value + ref_offset);
else
emit_globaladdr(value, ref_offset, type);
}
else if (type & CONST_TYPE)
{
emit_const(value);
}
if (type & PTR_TYPE)
(type & BPTR_TYPE) ? emit_lb() : emit_lw();
ref_offset = 0;
emit_value = 1;
}
else if (ref_type & PTR_TYPE)
(ref_type & BPTR_TYPE) ? emit_lb() : emit_lw();
while (parse_expr())
{
if (scantoken != COMMA_TOKEN)
break;
emit_indexword();
emit_lw();
}
if (scantoken != CLOSE_BRACKET_TOKEN)
{
parse_error("Missing closing bracket");
return (0);
}
if (ref_type & (WPTR_TYPE | WORD_TYPE))
{
emit_indexword();
ref_type = WPTR_TYPE;
}
else
{
emit_indexbyte();
ref_type = BPTR_TYPE;
}
break;
case PTRB_TOKEN:
case PTRW_TOKEN:
/*
* Structure member pointer
*/
if (!emit_value)
{
if (type & FUNC_TYPE)
emit_call(value, type);
else if (type & VAR_TYPE)
{
if (type & LOCAL_TYPE)
(type & BYTE_TYPE) ? emit_llb(value + ref_offset) : emit_llw(value + ref_offset);
else
(type & BYTE_TYPE) ? emit_lab(value, ref_offset, type) : emit_law(value, ref_offset, type);
}
else if (type & CONST_TYPE)
{
emit_const(value);
}
if (type & PTR_TYPE)
(type & BPTR_TYPE) ? emit_lb() : emit_lw();
emit_value = 1;
}
else
(ref_type & BPTR_TYPE) ? emit_lb() : emit_lw();
ref_type = (scantoken == PTRB_TOKEN) ? BPTR_TYPE : WPTR_TYPE;
ref_offset = 0;
if (!parse_constval(&ref_offset, &const_size))
scan_rewind(tokenstr);
if (ref_offset != 0)
{
emit_const(ref_offset);
emit_op(ADD_TOKEN);
ref_offset = 0;
}
break;
case DOT_TOKEN:
case COLON_TOKEN:
/*
* Structure member offset
*/
ref_type = (ref_type & VAR_TYPE)
? ((scantoken == DOT_TOKEN) ? BYTE_TYPE : WORD_TYPE)
: ((scantoken == DOT_TOKEN) ? BPTR_TYPE : WPTR_TYPE);
if (parse_constval(&const_offset, &const_size))
ref_offset += const_offset;
else
scan_rewind(tokenstr);
if (!emit_value)
{
if (type & FUNC_TYPE)
{
emit_globaladdr(value, ref_offset, type);
ref_offset = 0;
emit_value = 1;
}
else if (type & CONST_TYPE)
{
value += ref_offset;
ref_offset = 0;
ref_type = type;
}
}
else
{
if (ref_offset != 0)
{
emit_const(ref_offset);
emit_op(ADD_TOKEN);
ref_offset = 0;
}
}
break;
}
}
if (emit_value)
{
if (rvalue && deref && (type & PTR_TYPE))
(type & BPTR_TYPE) ? emit_lb() : emit_lw();
if (rvalue && deref && (ref_type & PTR_TYPE))
(ref_type & BPTR_TYPE) ? emit_lb() : emit_lw();
}
else
{
if (type & CONST_TYPE)
if (ref_type & CONST_TYPE)
emit_const(value);
else if (deref)
{
if (type & FUNC_TYPE)
emit_call(value, type);
if (ref_type & FUNC_TYPE)
emit_call(value, ref_type);
else if (type & VAR_TYPE)
{
if (type & LOCAL_TYPE)
(type & BYTE_TYPE) ? emit_llb(value + elem_offset) : emit_llw(value + elem_offset);
(ref_type & BYTE_TYPE) ? emit_llb(value + ref_offset) : emit_llw(value + ref_offset);
else
(type & BYTE_TYPE) ? emit_lab(value, elem_offset, type) : emit_law(value, elem_offset, type);
(ref_type & BYTE_TYPE) ? emit_lab(value, ref_offset, ref_type) : emit_law(value, ref_offset, ref_type);
}
else if (type & PTR_TYPE)
(type & BPTR_TYPE) ? emit_lb() : emit_lw();
else if (ref_type & PTR_TYPE)
(ref_type & BPTR_TYPE) ? emit_lb() : emit_lw();
}
else
{
if (type & LOCAL_TYPE)
emit_localaddr(value + elem_offset);
emit_localaddr(value + ref_offset);
else
emit_globaladdr(value, elem_offset, type);
emit_globaladdr(value, ref_offset, ref_type);
}
}
while (optos < opsptr)
@ -534,7 +506,7 @@ int parse_value(int rvalue)
return (0);
}
}
return (type ? type : WORD_TYPE);
return (ref_type ? ref_type : WORD_TYPE);
}
int parse_constexpr(long *value, int *size)
{

View File

@ -409,41 +409,41 @@ end
// SAVE VM STATE
//
asm save_vmstate
LDA $03F2
STA VMRESET
LDA $03F3
STA VMRESET+1
LDA $03F4
STA VMRESET+2
LDA #<RESETENTRY
STA $03F2
LDA #>RESETENTRY
STA $03F3
EOR #$A5
STA $03F4
DEX
RTS
LDA $03F2
STA VMRESET
LDA $03F3
STA VMRESET+1
LDA $03F4
STA VMRESET+2
LDA #<RESETENTRY
STA $03F2
LDA #>RESETENTRY
STA $03F3
EOR #$A5
STA $03F4
DEX
RTS
end
//
// RESTORE VM STATE
//
asm restore_vmstate
RESETENTRY
LDA VMRESET
STA $03F2
LDA VMRESET+1
STA $03F3
LDA VMRESET+2
STA $03F4
LDX #$00
STX IFPL
LDA #$BF
STA IFPH
LDX #$FE
TXS
LDX #ESTKSZ/2
BIT ROMEN
JMP $2000
LDA VMRESET
STA $03F2
LDA VMRESET+1
STA $03F3
LDA VMRESET+2
STA $03F4
LDX #$00
STX IFPL
LDA #$BF
STA IFPH
LDX #$FE
TXS
LDX #ESTKSZ/2
BIT ROMEN
JMP $2000
VMRESET !FILL 3
end
//
@ -467,7 +467,7 @@ REGVALS = SRC
INX
INX
INX
INX
INX
STX ESP
TAX
PLA
@ -495,124 +495,129 @@ end
// SYSCALL(CMD, PARAMS)
//
asm syscall
LDA ESTKL,X
LDY ESTKH,X
STA PARAMS
STY PARAMS+1
INX
LDA ESTKL,X
STA CMD
JSR $BF00
LDA ESTKL,X
LDY ESTKH,X
STA PARAMS
STY PARAMS+1
INX
LDA ESTKL,X
STA CMD
JSR $BF00
CMD: !BYTE 00
PARAMS: !WORD 0000
LDY #$00
STA ESTKL,X
STY ESTKH,X
RTS
LDY #$00
STA ESTKL,X
STY ESTKH,X
RTS
end
// SET MEMORY TO VALUE
// MEMSET(ADDR, SIZE, VALUE)
// With optimizations from Peter Ferrie
//
asm memset
LDY #$00
LDA ESTKL+2,X
STA DSTL
LDA ESTKH+2,X
STA DSTH
INC ESTKL+1,X
INC ESTKH+1,X
LDA ESTKL+2,X
STA DSTL
LDA ESTKH+2,X
STA DSTH
LDY ESTKL+1,X
BEQ +
INC ESTKH+1,X
LDY #$00
+ LDA ESTKH+1,X
BEQ SETMEX
SETMLPL CLC
LDA ESTKL,X
SETMLPH DEC ESTKL+1,X
BNE +
DEC ESTKH+1,X
BEQ SETMEX
+ STA (DST),Y
INY
BNE +
INC DSTH
+ BCS SETMLPL
SEC
LDA ESTKH,X
BCS SETMLPH
LDA ESTKL,X
SETMLPH STA (DST),Y
DEC ESTKL+1,X
BNE +
DEC ESTKH+1,X
BEQ SETMEX
+ INY
BNE +
INC DSTH
+ BCS SETMLPL
SEC
LDA ESTKH,X
BCS SETMLPH
SETMEX INX
INX
RTS
INX
RTS
end
//
// COPY MEMORY
// MEMCPY(DSTADDR, SRCADDR, SIZE)
//
asm memcpy
INX
INX
LDA ESTKL-2,X
ORA ESTKH-2,X
BEQ CPYMEX
LDA ESTKL-1,X
CMP ESTKL,X
LDA ESTKH-1,X
SBC ESTKH,X
BCC REVCPY
INX
INX
LDA ESTKL-2,X
ORA ESTKH-2,X
BEQ CPYMEX
LDA ESTKL-1,X
CMP ESTKL,X
LDA ESTKH-1,X
SBC ESTKH,X
BCC REVCPY
;
; FORWARD COPY
;
LDA ESTKL,X
STA DSTL
LDA ESTKH,X
STA DSTH
LDA ESTKL-1,X
STA SRCL
LDA ESTKH-1,X
STA SRCH
INC ESTKH-2,X
LDY #$00
LDA ESTKL,X
STA DSTL
LDA ESTKH,X
STA DSTH
LDA ESTKL-1,X
STA SRCL
LDA ESTKH-1,X
STA SRCH
LDY ESTKL-2,X
BEQ FORCPYLP
INC ESTKH-2,X
LDY #$00
FORCPYLP LDA (SRC),Y
STA (DST),Y
INY
BNE +
INC DSTH
INC SRCH
+ DEC ESTKL-2,X
BNE FORCPYLP
DEC ESTKH-2,X
BNE FORCPYLP
RTS
STA (DST),Y
INY
BNE +
INC DSTH
INC SRCH
+ DEC ESTKL-2,X
BNE FORCPYLP
DEC ESTKH-2,X
BNE FORCPYLP
RTS
;
; REVERSE COPY
;
REVCPY ;CLC
LDA ESTKL-2,X
ADC ESTKL,X
STA DSTL
LDA ESTKH-2,X
ADC ESTKH,X
STA DSTH
CLC
LDA ESTKL-2,X
ADC ESTKL-1,X
STA SRCL
LDA ESTKH-2,X
ADC ESTKH-1,X
STA SRCH
DEC DSTH
DEC SRCH
LDY #$FF
LDA ESTKL-2,X
BEQ REVCPYLP
INC ESTKH-2,X
LDA ESTKL-2,X
ADC ESTKL,X
STA DSTL
LDA ESTKH-2,X
ADC ESTKH,X
STA DSTH
CLC
LDA ESTKL-2,X
ADC ESTKL-1,X
STA SRCL
LDA ESTKH-2,X
ADC ESTKH-1,X
STA SRCH
DEC DSTH
DEC SRCH
LDY #$FF
LDA ESTKL-2,X
BEQ REVCPYLP
INC ESTKH-2,X
REVCPYLP LDA (SRC),Y
STA (DST),Y
DEY
CPY #$FF
BNE +
DEC DSTH
DEC SRCH
+ DEC ESTKL-2,X
BNE REVCPYLP
DEC ESTKH-2,X
BNE REVCPYLP
STA (DST),Y
DEY
CPY #$FF
BNE +
DEC DSTH
DEC SRCH
+ DEC ESTKL-2,X
BNE REVCPYLP
DEC ESTKH-2,X
BNE REVCPYLP
CPYMEX RTS
end
//
@ -620,56 +625,56 @@ end
// COUT(CHAR)
//
asm cout
LDA ESTKL,X
BIT $BF98
BMI +
JSR TOUPR
+ ORA #$80
BIT ROMEN
JSR $FDED
BIT LCRDEN+LCBNK2
RTS
LDA ESTKL,X
BIT $BF98
BMI +
JSR TOUPR
+ ORA #$80
BIT ROMEN
JSR $FDED
BIT LCRDEN+LCBNK2
RTS
end
//
// CHAR IN
// RDKEY()
//
asm cin
BIT ROMEN
JSR $FD0C
BIT LCRDEN+LCBNK2
DEX
LDY #$00
AND #$7F
STA ESTKL,X
STY ESTKH,X
RTS
BIT ROMEN
JSR $FD0C
BIT LCRDEN+LCBNK2
DEX
LDY #$00
AND #$7F
STA ESTKL,X
STY ESTKH,X
RTS
end
//
// PRINT STRING
// PRSTR(STR)
//
asm prstr
LDY #$00
LDA ESTKL,X
STA SRCL
LDA ESTKH,X
STA SRCH
LDA (SRC),Y
STA TMP
BEQ ++
BIT ROMEN
- INY
LDA (SRC),Y
BIT $BF98
BMI +
JSR TOUPR
+ ORA #$80
JSR $FDED
CPY TMP
BNE -
BIT LCRDEN+LCBNK2
++ RTS
LDY #$00
LDA ESTKL,X
STA SRCL
LDA ESTKH,X
STA SRCH
LDA (SRC),Y
STA TMP
BEQ ++
BIT ROMEN
- INY
LDA (SRC),Y
BIT $BF98
BMI +
JSR TOUPR
+ ORA #$80
JSR $FDED
CPY TMP
BNE -
BIT LCRDEN+LCBNK2
++ RTS
end
//
// READ STRING
@ -681,7 +686,7 @@ asm rdstr
STX ESP
BIT ROMEN
JSR $FD6A
BIT LCRDEN+LCBNK2
BIT LCRDEN+LCBNK2
STX $01FF
- LDA $01FF,X
AND #$7F
@ -699,7 +704,7 @@ end
// EXIT
//
asm exit
JSR $BF00
JSR $BF00
!BYTE $65
!WORD EXITTBL
EXITTBL:
@ -795,22 +800,22 @@ end
// return scanptr
//end
asm skipspace(scanptr)
LDA #$00
STA SRCL
LDA #$00
STA SRCL
LDA ESTKH,X
STA SRCH
LDY ESTKL,X
- LDA (SRC),Y
CMP #' '
BNE +
INY
BNE -
INC SRCH
BNE -
+ STY ESTKL,X
LDA SRCH
STA ESTKH,X
RTS
- LDA (SRC),Y
CMP #' '
BNE +
INY
BNE -
INC SRCH
BNE -
+ STY ESTKL,X
LDA SRCH
STA ESTKH,X
RTS
end
//def isalpha(c)
// if c >= 'A' and c <= 'Z'
@ -830,11 +835,11 @@ asm isalpha
CMP #'A'
BCC ISALRET
CMP #'Z'+1
BCC ISALTRU
BCC ISALTRU
CMP #'a'
BCC ISALRET
CMP #'z'+1
BCS ISALRET
BCS ISALRET
ISALTRU DEY
ISALRET STY ESTKL,X
STY ESTKH,X
@ -878,15 +883,15 @@ asm isalphanum
CMP #'0'
BCC ISANRET
CMP #'9'+1
BCC ISANTRU
BCC ISANTRU
CMP #'A'
BCC ISANRET
CMP #'Z'+1
BCC ISANTRU
BCC ISANTRU
CMP #'a'
BCC ISANRET
CMP #'z'+1
BCS ISANRET
BCS ISANRET
ISANTRU DEY
ISANRET STY ESTKL,X
STY ESTKH,X
@ -3162,7 +3167,7 @@ def parse_value(rvalue)
emit_val = TRUE
fin
else
if elem_offset <> 0
if elem_offset
emit_const(elem_offset)
emit_binaryop(ADD_TKN)
elem_offset = 0
@ -3210,9 +3215,12 @@ def parse_value(rvalue)
// Function call
//
if emit_val
if lookahead <> CLOSE_PAREN_TKN
emit_push
fin
if type & PTR_TYPE
emit_lw
fin
if lookahead <> CLOSE_PAREN_TKN
emit_push
fin
fin
cparams = 0
while parse_expr

View File

@ -79,7 +79,6 @@ byte hpmarkstr[] = "HEAPMARK"
byte hpalignstr[] = "HEAPALLOCALIGN"
byte hpallocstr[] = "HEAPALLOC"
byte hprelstr[] = "HEAPRELEASE"
byte hpavailstr[] = "HEAPAVAIL"
byte memsetstr[] = "MEMSET"
byte memcpystr[] = "MEMCPY"
byte uisgtstr[] = "ISUGT"
@ -183,21 +182,24 @@ end
// With optimizations from Peter Ferrie
//
asm memset
LDY #$00
LDA ESTKL+2,X
STA DSTL
LDA ESTKH+2,X
STA DSTH
INC ESTKL+1,X
LDY ESTKL+1,X
BEQ +
INC ESTKH+1,X
LDY #$00
+ LDA ESTKH+1,X
BEQ SETMEX
SETMLPL CLC
LDA ESTKL,X
SETMLPH DEC ESTKL+1,X
SETMLPH STA (DST),Y
DEC ESTKL+1,X
BNE +
DEC ESTKH+1,X
BEQ SETMEX
+ STA (DST),Y
INY
+ INY
BNE +
INC DSTH
+ BCS SETMLPL
@ -234,6 +236,8 @@ asm memcpy
STA SRCL
LDA ESTKH-1,X
STA SRCH
LDY ESTKL-2,X
BEQ FORCPYLP
INC ESTKH-2,X
LDY #$00
FORCPYLP LDA (SRC),Y
@ -268,7 +272,7 @@ REVCPY ;CLC
DEC SRCH
LDY #$FF
LDA ESTKL-2,X
BEQ REVCPYLP
BEQ REVCPYLP
INC ESTKH-2,X
REVCPYLP LDA (SRC),Y
STA (DST),Y
@ -961,21 +965,20 @@ end
def execmod(modfile)
byte moddci[17]
word saveheap, savesym, saveflags
perr = 1
if stodci(modfile, @moddci)
saveheap = heap
savesym = lastsym
saveflags = systemflags
^lastsym = 0
perr = loadmod(@moddci)
if perr >= modkeep
perr = perr & ~modkeep
else
if loadmod(@moddci) < modkeep
lastsym = savesym
heap = saveheap
fin
^lastsym = 0
systemflags = saveflags
fin
return perr
end
//
// Get heap start.

View File

@ -56,7 +56,6 @@ byte hpmarkstr = "HEAPMARK"
byte hpalignstr = "HEAPALLOCALIGN"
byte hpallocstr = "HEAPALLOC"
byte hprelstr = "HEAPRELEASE"
byte hpavailstr = "HEAPAVAIL"
byte memsetstr = "MEMSET"
byte memcpystr = "MEMCPY"
byte uisgtstr = "ISUGT"
@ -197,21 +196,24 @@ end
// With optimizations from Peter Ferrie
//
asm memset
LDY #$00
LDA ESTKL+2,X
STA DSTL
LDA ESTKH+2,X
STA DSTH
INC ESTKL+1,X
LDY ESTKL+1,X
BEQ +
INC ESTKH+1,X
LDY #$00
+ LDA ESTKH+1,X
BEQ SETMEX
SETMLPL CLC
LDA ESTKL,X
SETMLPH DEC ESTKL+1,X
SETMLPH STA (DST),Y
DEC ESTKL+1,X
BNE +
DEC ESTKH+1,X
BEQ SETMEX
+ STA (DST),Y
INY
+ INY
BNE +
INC DSTH
+ BCS SETMLPL
@ -248,6 +250,8 @@ asm memcpy
STA SRCL
LDA ESTKH-1,X
STA SRCH
LDY ESTKL-2,X
BEQ FORCPYLP
INC ESTKH-2,X
LDY #$00
FORCPYLP LDA (SRC),Y
@ -1128,9 +1132,9 @@ def catalog(optpath)
if read(refnum, databuff, 512) == 512
entry = databuff + 4
if firstblk
entrylen = databuff.$23
entriesblk = databuff.$24
filecnt = databuff:$25
entrylen = databuff->$23
entriesblk = databuff->$24
filecnt = databuff=>$25
entry = entry + entrylen
fin
for i = firstblk to entriesblk
@ -1246,22 +1250,21 @@ def execmod(modfile)
byte moddci[17]
word saveheap, savexheap, savesym, saveflags
perr = 1
if stodci(modfile, @moddci)
saveheap = heap
savexheap = xheap
savesym = lastsym
saveflags = systemflags
^lastsym = 0
perr = loadmod(@moddci)
if perr < modkeep
if loadmod(@moddci) < modkeep
lastsym = savesym
xheap = savexheap
heap = saveheap
else
perr = perr & ~modkeep
fin
^lastsym = 0
systemflags = saveflags
fin
return perr
end
//
// Get heap start.

View File

@ -80,7 +80,6 @@ byte hpmarkstr[] = "HEAPMARK"
byte hpalignstr[] = "HEAPALLOCALIGN"
byte hpallocstr[] = "HEAPALLOC"
byte hprelstr[] = "HEAPRELEASE"
byte hpavailstr[] = "HEAPAVAIL"
byte memsetstr[] = "MEMSET"
byte memcpystr[] = "MEMCPY"
byte uisgtstr[] = "ISUGT"
@ -184,21 +183,24 @@ end
// With optimizations from Peter Ferrie
//
asm memset
LDY #$00
LDA ESTKL+2,X
STA DSTL
LDA ESTKH+2,X
STA DSTH
INC ESTKL+1,X
LDY ESTKL+1,X
BEQ +
INC ESTKH+1,X
LDY #$00
+ LDA ESTKH+1,X
BEQ SETMEX
SETMLPL CLC
LDA ESTKL,X
SETMLPH DEC ESTKL+1,X
SETMLPH STA (DST),Y
DEC ESTKL+1,X
BNE +
DEC ESTKH+1,X
BEQ SETMEX
+ STA (DST),Y
INY
+ INY
BNE +
INC DSTH
+ BCS SETMLPL
@ -235,6 +237,8 @@ asm memcpy
STA SRCL
LDA ESTKH-1,X
STA SRCH
LDY ESTKL-2,X
BEQ FORCPYLP
INC ESTKH-2,X
LDY #$00
FORCPYLP LDA (SRC),Y
@ -269,7 +273,7 @@ REVCPY ;CLC
DEC SRCH
LDY #$FF
LDA ESTKL-2,X
BEQ REVCPYLP
BEQ REVCPYLP
INC ESTKH-2,X
REVCPYLP LDA (SRC),Y
STA (DST),Y
@ -1239,14 +1243,13 @@ end
def execmod(modfile)
byte moddci[17]
word saveheap, savesym, saveflags
perr = 1
if stodci(modfile, @moddci)
xpokeb(symtbl.0, lastsym, 0)
saveheap = heap
savesym = lastsym
saveflags = systemflags
perr = loadmod(@moddci)
if perr < modkeep
if loadmod(@moddci) < modkeep
lastsym = savesym
heap = saveheap
while modid
@ -1255,10 +1258,11 @@ def execmod(modfile)
loop
else
modid = 0
perr = perr & ~(modinitkeep | modkeep)
fin
xpokeb(symtbl.0, lastsym, 0)
systemflags = saveflags
fin
return perr
end
//
// Init console.