mirror of
https://github.com/bobbimanners/emailler.git
synced 2025-01-06 08:31:19 +00:00
git-svn-id: http://svn.code.sf.net/p/netboot65/code@263 93682198-c243-4bdb-bd91-e943c89aac3b
This commit is contained in:
parent
97df9d4199
commit
b63c85e95c
@ -17,13 +17,13 @@ IP65LIB=../ip65/ip65_tcp.lib
|
|||||||
|
|
||||||
C64PROGLIB=../drivers/c64prog.lib
|
C64PROGLIB=../drivers/c64prog.lib
|
||||||
|
|
||||||
all: gopherd.d64 kipperbas.d64
|
all: kipperbas.d64
|
||||||
|
|
||||||
%.o: %.s $(INCFILES)
|
%.o: %.s $(INCFILES)
|
||||||
$(AS) $(AFLAGS) $<
|
$(AS) $(AFLAGS) $<
|
||||||
|
|
||||||
%.prg: %.o $(IP65LIB) $(C64PROGLIB) $(INCFILES) ../cfg/c64_mlstub.cfg
|
%.prg: %.o $(IP65LIB) $(C64PROGLIB) $(INCFILES) ../cfg/kipperbas.cfg
|
||||||
$(LD) -m $*.map -vm -C ../cfg/c64_mlstub.cfg -o $*.prg $(AFLAGS) $< $(IP65LIB) $(C64PROGLIB)
|
$(LD) -m $*.map -vm -C ../cfg/kipperbas.cfg -o $*.prg $(AFLAGS) $< $(IP65LIB) $(C64PROGLIB)
|
||||||
|
|
||||||
|
|
||||||
kipperbas.d64: kipperbas.prg
|
kipperbas.d64: kipperbas.prg
|
||||||
@ -31,13 +31,6 @@ kipperbas.d64: kipperbas.prg
|
|||||||
ripxplore.rb -r -e kbapp $@ -o kbapp
|
ripxplore.rb -r -e kbapp $@ -o kbapp
|
||||||
ripxplore.rb $@ -a kipperbas.prg
|
ripxplore.rb $@ -a kipperbas.prg
|
||||||
|
|
||||||
|
|
||||||
gopherd.d64: mlstub.prg gophermap.txt addresses.txt
|
|
||||||
ripxplore.rb -r -e gopherd $@ -o gopherd.bas
|
|
||||||
ripxplore.rb $@ -a mlstub.prg
|
|
||||||
ripxplore.rb $@ -a gophermap.txt -t C64Seq
|
|
||||||
ripxplore.rb $@ -a addresses.txt -t C64Seq
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o *.bin *.map *.prg
|
rm -f *.o *.bin *.map *.prg
|
||||||
|
|
||||||
|
Binary file not shown.
Binary file not shown.
@ -1,11 +1,12 @@
|
|||||||
|
|
||||||
.include "../inc/common.i"
|
.include "../inc/common.i"
|
||||||
;.include "../inc/commonprint.i"
|
|
||||||
|
|
||||||
VARTAB = $2D ;BASIC variable table storage
|
VARTAB = $2D ;BASIC variable table storage
|
||||||
ARYTAB = $2F ;BASIC array table storage
|
ARYTAB = $2F ;BASIC array table storage
|
||||||
FREETOP = $33 ;bottom of string text storage area
|
FREETOP = $33 ;bottom of string text storage area
|
||||||
MEMSIZ = $37 ;highest address used by BASIC
|
MEMSIZ = $37 ;highest address used by BASIC
|
||||||
|
VARNAM = $45 ;current BASIC variable name
|
||||||
|
VARPNT = $47 ; pointer to current BASIC variable value
|
||||||
|
|
||||||
SETNAM = $FFBD
|
SETNAM = $FFBD
|
||||||
SETLFS = $FFBA
|
SETLFS = $FFBA
|
||||||
@ -30,22 +31,74 @@ CHKCOM = $AEFD
|
|||||||
NEW = $A642
|
NEW = $A642
|
||||||
CLR = $A65E
|
CLR = $A65E
|
||||||
NEWSTT = $A7AE
|
NEWSTT = $A7AE
|
||||||
|
GETVAR = $B0E7 ;find or create a variable
|
||||||
|
FRMEVL = $AD9E ;evaluate expression
|
||||||
|
FRESTR = $B6A3 ;free temporary string
|
||||||
|
|
||||||
|
VALTYP=$0D ;00=number, $FF=string
|
||||||
|
|
||||||
LINNUM = $14 ;Number returned by GETPAR
|
LINNUM = $14 ;Number returned by GETPAR
|
||||||
|
|
||||||
crunched_line = $0200 ;Input buffer
|
crunched_line = $0200 ;Input buffer
|
||||||
|
|
||||||
|
.import copymem
|
||||||
|
.importzp copy_dest
|
||||||
|
.import dhcp_init
|
||||||
|
.import ip65_init
|
||||||
|
.import cfg_get_configuration_ptr
|
||||||
|
.import tcp_listen
|
||||||
|
.import tcp_callback
|
||||||
|
.import tcp_connect_ip
|
||||||
|
.import tcp_send
|
||||||
|
.import tcp_connect
|
||||||
|
.import tcp_close
|
||||||
|
.import tcp_send_data_len
|
||||||
|
.import tcp_inbound_data_ptr
|
||||||
|
.import tcp_inbound_data_length
|
||||||
|
.import dns_set_hostname
|
||||||
|
.import dns_resolve
|
||||||
|
.import dns_ip
|
||||||
|
.import ip65_process
|
||||||
|
.import ip65_error
|
||||||
|
.import cfg_ip
|
||||||
|
.import cfg_dns
|
||||||
|
.import cfg_gateway
|
||||||
|
.import cfg_netmask
|
||||||
|
.import cfg_tftp_server
|
||||||
|
.import icmp_ping
|
||||||
|
.import icmp_echo_ip
|
||||||
|
.import print_a
|
||||||
|
.import print_cr
|
||||||
|
.import dhcp_server
|
||||||
|
.import cfg_mac
|
||||||
|
.import cs_driver_name
|
||||||
|
.importzp tftp_filename
|
||||||
|
.import tftp_ip
|
||||||
|
.import tftp_download
|
||||||
|
.import tftp_set_callback_vector
|
||||||
|
.import tftp_data_block_length
|
||||||
|
|
||||||
.zeropage
|
.zeropage
|
||||||
temp: .res 2
|
temp: .res 2
|
||||||
temp2: .res 2
|
temp2: .res 2
|
||||||
|
pptr=temp
|
||||||
.segment "STARTUP" ;this is what gets put at the start of the file on the C64
|
.segment "STARTUP" ;this is what gets put at the start of the file on the C64
|
||||||
.word jump_table ; load address
|
.word jump_table ; load address
|
||||||
jump_table:
|
jump_table:
|
||||||
jmp init ; $4000 (PTR 16384) - vars io$,io%,er% should be created (in that order!) before calling
|
jmp init ; $4000 (PTR 16384) - vars io$,io%,er% should be created (in that order!) before calling
|
||||||
|
|
||||||
|
|
||||||
|
safe_getvar: ;if GETVAR doesn't find the desired variable name in the VARTABLE, a routine at $B11D will create it
|
||||||
|
;however that routine checks if the low byte of the return address of the caller is $2A. if it is,
|
||||||
|
;it assumes the caller is the routine at $AF28 which just wants to get the variable value, and
|
||||||
|
;returns a pointer to a dummy 'zero' pointer.
|
||||||
|
;so if user code that is calling GETVAR happens to be compiled to an address $xx28, it will
|
||||||
|
;trigger this check, and not create a new variable, which (from painful experience) will create
|
||||||
|
;a really nasty condition to debug!
|
||||||
|
;so vector to GETVAR via here, so the return address seen by $B11D is here, and never $xx28
|
||||||
|
jsr GETVAR
|
||||||
|
rts
|
||||||
.code
|
.code
|
||||||
|
|
||||||
|
|
||||||
;
|
;
|
||||||
;BASIC extensions derived from BLARG - http://www.ffd2.com/fridge/programs/blarg/blarg.s
|
;BASIC extensions derived from BLARG - http://www.ffd2.com/fridge/programs/blarg/blarg.s
|
||||||
;
|
;
|
||||||
@ -65,9 +118,18 @@ install_new_vectors_loop:
|
|||||||
sta ICRUNCH,x
|
sta ICRUNCH,x
|
||||||
dex
|
dex
|
||||||
bpl install_new_vectors_loop
|
bpl install_new_vectors_loop
|
||||||
rts
|
|
||||||
|
|
||||||
;
|
|
||||||
|
;BASIC keywords installed, now bring up the ip65 stack
|
||||||
|
|
||||||
|
jsr ip65_init
|
||||||
|
bcs @init_failed
|
||||||
|
lda #0
|
||||||
|
sta ip65_error
|
||||||
|
|
||||||
|
@init_failed:
|
||||||
|
jmp set_error
|
||||||
|
|
||||||
; CRUNCH -- If this is one of our keywords, then tokenize it
|
; CRUNCH -- If this is one of our keywords, then tokenize it
|
||||||
;
|
;
|
||||||
crunch:
|
crunch:
|
||||||
@ -215,16 +277,19 @@ list:
|
|||||||
jmp $A700 ;Normal exit
|
jmp $A700 ;Normal exit
|
||||||
|
|
||||||
|
|
||||||
execute:
|
|
||||||
|
|
||||||
;
|
;
|
||||||
; EXECUTE -- if this is one of my
|
; EXECUTE -- if this is one of our new
|
||||||
; tokens, then execute it.
|
; tokens, then execute it.
|
||||||
;
|
execute:
|
||||||
; jmp (oldexec)
|
|
||||||
|
|
||||||
jsr CHRGET
|
jsr CHRGET
|
||||||
|
execute_a:
|
||||||
php
|
php
|
||||||
|
|
||||||
|
cmp #$8B ;is it 'IF'?
|
||||||
|
bne @not_if
|
||||||
|
lda #$E0 ;our dummy IF token
|
||||||
|
@not_if:
|
||||||
cmp #$E0
|
cmp #$E0
|
||||||
bcc @notmine
|
bcc @notmine
|
||||||
cmp #HITOKEN
|
cmp #HITOKEN
|
||||||
@ -243,21 +308,599 @@ execute:
|
|||||||
jmp CHRGET ;exit to routine (via RTS)
|
jmp CHRGET ;exit to routine (via RTS)
|
||||||
@notmine:
|
@notmine:
|
||||||
plp
|
plp
|
||||||
cmp #0
|
cmp #0 ;reset flags
|
||||||
jmp $A7E7
|
jmp $A7E7
|
||||||
|
|
||||||
goober:
|
;the standard BASIC IF routine calls the BASIC EXECUTE routine directly,
|
||||||
inc $d020
|
;without going through the vector. That means an extended keyword following THEN
|
||||||
|
;will lead to a syntax error. So we have to reimpliment IF here
|
||||||
|
;this is taken from TransBASIC - The Transactor, vol 5, Issue 04 (March 1985) page 34
|
||||||
|
if_keyword:
|
||||||
|
jsr FRMEVL ;evaluate expression
|
||||||
|
jsr CHRGOT
|
||||||
|
cmp #$89 ;is next token GOTO?
|
||||||
|
beq @ok
|
||||||
|
lda #$A7 ;is next token THEN
|
||||||
|
jsr $AEFF ;will generate SYNTAX ERROR if not
|
||||||
|
@ok:
|
||||||
|
jsr CHRGOT
|
||||||
|
ldx $61 ;result of expression : 0 means false
|
||||||
|
bne @expression_was_true
|
||||||
|
jmp $A93B ;go to REM implementation - skips rest of line
|
||||||
|
@expression_was_true:
|
||||||
|
bcs @not_numeric;CHRGOT clears carry flag if current char is a number
|
||||||
|
jmp $A8A0 ;do a GOTO
|
||||||
|
@not_numeric:
|
||||||
|
pla
|
||||||
|
pla ;pop the return address off the stack
|
||||||
|
jsr CHRGOT
|
||||||
|
jmp execute_a ;execute current token
|
||||||
|
|
||||||
|
set_result_code:
|
||||||
|
pha
|
||||||
|
txa
|
||||||
|
pha
|
||||||
|
lda #'R'+$80
|
||||||
|
sta VARNAM
|
||||||
|
lda #'C'+$80
|
||||||
|
sta VARNAM+1
|
||||||
|
jsr safe_getvar
|
||||||
|
ldy #0
|
||||||
|
pla
|
||||||
|
sta (VARPNT),y
|
||||||
|
iny
|
||||||
|
pla
|
||||||
|
sta (VARPNT),y
|
||||||
|
clear_error:
|
||||||
|
lda #0
|
||||||
|
sta ip65_error
|
||||||
|
set_error:
|
||||||
|
lda #'E'+$80
|
||||||
|
sta VARNAM
|
||||||
|
lda #'R'+$80
|
||||||
|
sta VARNAM+1
|
||||||
|
jsr safe_getvar
|
||||||
|
lda #0
|
||||||
|
tay
|
||||||
|
sta (VARPNT),y
|
||||||
|
iny
|
||||||
|
lda ip65_error
|
||||||
|
sta (VARPNT),y
|
||||||
|
|
||||||
rts
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
;emit the 4 bytes pointed at by AX as dotted decimals
|
||||||
|
emit_dotted_quad:
|
||||||
|
sta pptr
|
||||||
|
stx pptr + 1
|
||||||
|
ldy #0
|
||||||
|
lda (pptr),y
|
||||||
|
jsr emit_decimal
|
||||||
|
lda #'.'
|
||||||
|
jsr emit_a
|
||||||
|
|
||||||
|
ldy #1
|
||||||
|
lda (pptr),y
|
||||||
|
jsr emit_decimal
|
||||||
|
lda #'.'
|
||||||
|
jsr emit_a
|
||||||
|
|
||||||
|
ldy #2
|
||||||
|
lda (pptr),y
|
||||||
|
jsr emit_decimal
|
||||||
|
lda #'.'
|
||||||
|
jsr emit_a
|
||||||
|
|
||||||
|
ldy #3
|
||||||
|
lda (pptr),y
|
||||||
|
jsr emit_decimal
|
||||||
|
|
||||||
|
rts
|
||||||
|
|
||||||
|
emit_decimal: ;emit byte in A as a decimal number
|
||||||
|
pha
|
||||||
|
sta temp_bin ;save
|
||||||
|
sed ; Switch to decimal mode
|
||||||
|
lda #0 ; Ensure the result is clear
|
||||||
|
sta temp_bcd
|
||||||
|
sta temp_bcd+1
|
||||||
|
ldx #8 ; The number of source bits
|
||||||
|
:
|
||||||
|
asl temp_bin+0 ; Shift out one bit
|
||||||
|
lda temp_bcd+0 ; And add into result
|
||||||
|
adc temp_bcd+0
|
||||||
|
sta temp_bcd+0
|
||||||
|
lda temp_bcd+1 ; propagating any carry
|
||||||
|
adc temp_bcd+1
|
||||||
|
sta temp_bcd+1
|
||||||
|
dex ; And repeat for next bit
|
||||||
|
bne :-
|
||||||
|
|
||||||
|
cld ;back to binary
|
||||||
|
|
||||||
|
pla ;get back the original passed in number
|
||||||
|
bmi @emit_hundreds ; if N is set, the number is >=128 so emit all 3 digits
|
||||||
|
cmp #10
|
||||||
|
bmi @emit_units
|
||||||
|
cmp #100
|
||||||
|
bmi @emit_tens
|
||||||
|
@emit_hundreds:
|
||||||
|
lda temp_bcd+1 ;get the most significant digit
|
||||||
|
and #$0f
|
||||||
|
clc
|
||||||
|
adc #'0'
|
||||||
|
jsr emit_a
|
||||||
|
|
||||||
|
@emit_tens:
|
||||||
|
lda temp_bcd
|
||||||
|
lsr
|
||||||
|
lsr
|
||||||
|
lsr
|
||||||
|
lsr
|
||||||
|
clc
|
||||||
|
adc #'0'
|
||||||
|
jsr emit_a
|
||||||
|
@emit_units:
|
||||||
|
lda temp_bcd
|
||||||
|
and #$0f
|
||||||
|
clc
|
||||||
|
adc #'0'
|
||||||
|
jsr emit_a
|
||||||
|
|
||||||
|
rts
|
||||||
|
|
||||||
|
print:
|
||||||
|
sta pptr
|
||||||
|
stx pptr + 1
|
||||||
|
|
||||||
|
@print_loop:
|
||||||
|
ldy #0
|
||||||
|
lda (pptr),y
|
||||||
|
beq @done_print
|
||||||
|
jsr print_a
|
||||||
|
inc pptr
|
||||||
|
bne @print_loop
|
||||||
|
inc pptr+1
|
||||||
|
bne @print_loop ;if we ever get to $ffff, we've probably gone far enough ;-)
|
||||||
|
@done_print:
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
extract_string:
|
||||||
|
jsr FRMEVL
|
||||||
|
jsr $AD8F ;check result is a string, if not create type mismatch error
|
||||||
|
ldy $19 ;temp string created by FRMEVL
|
||||||
|
sty param_length
|
||||||
|
lda #0
|
||||||
|
sta transfer_buffer,y
|
||||||
|
dey
|
||||||
|
@loop:
|
||||||
|
lda ($1a),y
|
||||||
|
sta transfer_buffer,y
|
||||||
|
dey
|
||||||
|
bpl @loop
|
||||||
|
jmp FRESTR ;free up the temp string created by FRMEVL
|
||||||
|
|
||||||
|
;get a string value from BASIC command, turn into a 32 bit IP address,save it in the 4 bytes pointed at by AX
|
||||||
|
get_ip_parameter:
|
||||||
|
stax temp2
|
||||||
|
jsr extract_string
|
||||||
|
ldax #transfer_buffer
|
||||||
|
jsr dns_set_hostname
|
||||||
|
|
||||||
|
bcs @error
|
||||||
|
jsr dns_resolve
|
||||||
|
bcc @ok
|
||||||
|
@error:
|
||||||
|
ldax #dns_error
|
||||||
|
jsr print
|
||||||
|
sec
|
||||||
|
rts
|
||||||
|
@ok:
|
||||||
|
ldax #dns_ip
|
||||||
|
ldx #4
|
||||||
|
@copy_dns_ip:
|
||||||
|
lda dns_ip,y
|
||||||
|
sta (temp2),y
|
||||||
|
iny
|
||||||
|
dex
|
||||||
|
bne @copy_dns_ip
|
||||||
|
rts
|
||||||
|
|
||||||
|
print_dotted_quad:
|
||||||
|
ldy #<string_buffer
|
||||||
|
sty current_output_ptr
|
||||||
|
ldy #>string_buffer
|
||||||
|
sty current_output_ptr+1
|
||||||
|
jsr emit_dotted_quad
|
||||||
|
make_null_terminated_and_print:
|
||||||
|
lda #0
|
||||||
|
jsr emit_a
|
||||||
|
ldax #string_buffer
|
||||||
|
jmp print
|
||||||
|
|
||||||
|
print_mac:
|
||||||
|
ldy #<string_buffer
|
||||||
|
sty current_output_ptr
|
||||||
|
ldy #>string_buffer
|
||||||
|
sty current_output_ptr+1
|
||||||
|
jsr emit_mac
|
||||||
|
jmp make_null_terminated_and_print
|
||||||
|
|
||||||
|
;print 6 bytes printed at by AX as a MAC address
|
||||||
|
emit_mac:
|
||||||
|
stax pptr
|
||||||
|
ldy #0
|
||||||
|
@one_mac_digit:
|
||||||
|
tya ;just to set the Z flag
|
||||||
|
pha
|
||||||
|
beq @dont_print_colon
|
||||||
|
lda #':'
|
||||||
|
jsr emit_a
|
||||||
|
@dont_print_colon:
|
||||||
|
pla
|
||||||
|
tay
|
||||||
|
lda (pptr),y
|
||||||
|
jsr emit_hex
|
||||||
|
iny
|
||||||
|
cpy #06
|
||||||
|
bne @one_mac_digit
|
||||||
|
rts
|
||||||
|
|
||||||
|
emit_hex:
|
||||||
|
pha
|
||||||
|
pha
|
||||||
|
lsr
|
||||||
|
lsr
|
||||||
|
lsr
|
||||||
|
lsr
|
||||||
|
tax
|
||||||
|
lda hexdigits,x
|
||||||
|
jsr emit_a
|
||||||
|
pla
|
||||||
|
and #$0F
|
||||||
|
tax
|
||||||
|
lda hexdigits,x
|
||||||
|
jsr emit_a
|
||||||
|
pla
|
||||||
|
rts
|
||||||
|
|
||||||
|
get_optional_byte:
|
||||||
|
jsr CHRGOT
|
||||||
|
beq @no_param ;leave X as it was
|
||||||
|
jsr CHKCOM ;make sure next char is a comma (and skip it)
|
||||||
|
jsr CHRGOT
|
||||||
|
beq @eol
|
||||||
|
jsr GETBYT
|
||||||
|
@no_param:
|
||||||
|
rts
|
||||||
|
@eol:
|
||||||
|
jmp $AF08 ;SYNTAX ERROR
|
||||||
|
ipcfg_keyword:
|
||||||
|
|
||||||
|
ldax #interface_type
|
||||||
|
jsr print
|
||||||
|
|
||||||
|
ldax #cs_driver_name
|
||||||
|
jsr print
|
||||||
|
jsr print_cr
|
||||||
|
|
||||||
|
ldax #mac_address_msg
|
||||||
|
jsr print
|
||||||
|
ldax #cfg_mac
|
||||||
|
jsr print_mac
|
||||||
|
jsr print_cr
|
||||||
|
|
||||||
|
ldax #ip_address_msg
|
||||||
|
jsr print
|
||||||
|
ldax #cfg_ip
|
||||||
|
jsr print_dotted_quad
|
||||||
|
jsr print_cr
|
||||||
|
|
||||||
|
ldax #netmask_msg
|
||||||
|
jsr print
|
||||||
|
ldax #cfg_netmask
|
||||||
|
jsr print_dotted_quad
|
||||||
|
jsr print_cr
|
||||||
|
|
||||||
|
ldax #gateway_msg
|
||||||
|
jsr print
|
||||||
|
ldax #cfg_gateway
|
||||||
|
jsr print_dotted_quad
|
||||||
|
jsr print_cr
|
||||||
|
|
||||||
|
ldax #dns_server_msg
|
||||||
|
jsr print
|
||||||
|
ldax #cfg_dns
|
||||||
|
jsr print_dotted_quad
|
||||||
|
jsr print_cr
|
||||||
|
|
||||||
|
|
||||||
|
ldax #dhcp_server_msg
|
||||||
|
jsr print
|
||||||
|
ldax #dhcp_server
|
||||||
|
jsr print_dotted_quad
|
||||||
|
jsr print_cr
|
||||||
|
|
||||||
|
ldax #tftp_server_msg
|
||||||
|
jsr print
|
||||||
|
ldax #cfg_tftp_server
|
||||||
|
jsr print_dotted_quad
|
||||||
|
jsr print_cr
|
||||||
|
|
||||||
|
jmp clear_error
|
||||||
|
|
||||||
|
dhcp_keyword:
|
||||||
|
jsr dhcp_init
|
||||||
|
bcc @init_ok
|
||||||
|
jsr ip65_init ;if DHCP failed, then reinit the IP stack (which will reset IP address etc that DHCP messed with to default values)
|
||||||
|
|
||||||
|
@init_failed:
|
||||||
|
jsr set_error
|
||||||
|
ldax #dhcp_error
|
||||||
|
jmp print
|
||||||
|
@init_ok:
|
||||||
|
jmp clear_error
|
||||||
|
rts
|
||||||
|
|
||||||
|
ping_keyword:
|
||||||
|
ldax #icmp_echo_ip
|
||||||
|
jsr get_ip_parameter
|
||||||
|
bcc @no_error
|
||||||
|
rts
|
||||||
|
@no_error:
|
||||||
|
|
||||||
|
;is there an optional parameter?
|
||||||
|
ldx #3
|
||||||
|
jsr get_optional_byte
|
||||||
|
stx ping_counter
|
||||||
|
|
||||||
|
ldax #pinging
|
||||||
|
jsr print
|
||||||
|
ldax #dns_ip
|
||||||
|
jsr print_dotted_quad
|
||||||
|
jsr print_cr
|
||||||
|
|
||||||
|
@ping_loop:
|
||||||
|
jsr icmp_ping
|
||||||
|
bcs @error
|
||||||
|
jsr set_result_code
|
||||||
|
lda #'.'
|
||||||
|
@print_and_loop:
|
||||||
|
jsr print_a
|
||||||
|
dec ping_counter
|
||||||
|
bne @ping_loop
|
||||||
|
jsr print_cr
|
||||||
|
jmp set_error
|
||||||
|
@error:
|
||||||
|
lda #'!'
|
||||||
|
jmp @print_and_loop
|
||||||
|
|
||||||
|
|
||||||
|
myip_keyword:
|
||||||
|
ldax #cfg_ip
|
||||||
|
jmp get_ip_parameter
|
||||||
|
|
||||||
|
dns_keyword:
|
||||||
|
ldax #cfg_dns
|
||||||
|
jmp get_ip_parameter
|
||||||
|
|
||||||
|
gateway_keyword:
|
||||||
|
ldax #cfg_gateway
|
||||||
|
jmp get_ip_parameter
|
||||||
|
|
||||||
|
netmask_keyword:
|
||||||
|
ldax #cfg_netmask
|
||||||
|
jmp get_ip_parameter
|
||||||
|
|
||||||
|
tftp_keyword:
|
||||||
|
ldax #cfg_tftp_server
|
||||||
|
jmp get_ip_parameter
|
||||||
|
|
||||||
|
tfget_keyword:
|
||||||
|
jsr extract_string
|
||||||
|
ldax #get_msg
|
||||||
|
jsr print
|
||||||
|
ldax #transfer_buffer
|
||||||
|
stax tftp_filename
|
||||||
|
jsr print
|
||||||
|
ldax #from_msg
|
||||||
|
jsr print
|
||||||
|
ldax #cfg_tftp_server
|
||||||
|
jsr print_dotted_quad
|
||||||
|
jsr print_cr
|
||||||
|
|
||||||
|
ldx #$03
|
||||||
|
:
|
||||||
|
lda cfg_tftp_server,x
|
||||||
|
sta tftp_ip,x
|
||||||
|
dex
|
||||||
|
bpl :-
|
||||||
|
ldax #tftp_download_callback
|
||||||
|
jsr tftp_set_callback_vector
|
||||||
|
lda #0
|
||||||
|
sta file_opened
|
||||||
|
;make file output name
|
||||||
|
lda #'@'
|
||||||
|
sta string_buffer
|
||||||
|
lda #':'
|
||||||
|
sta string_buffer+1
|
||||||
|
ldy #$FF
|
||||||
|
@loop:
|
||||||
|
iny
|
||||||
|
lda transfer_buffer,y
|
||||||
|
sta string_buffer+2,y
|
||||||
|
bne @loop
|
||||||
|
iny
|
||||||
|
iny
|
||||||
|
lda #','
|
||||||
|
sta string_buffer,y
|
||||||
|
iny
|
||||||
|
lda #'P'
|
||||||
|
sta string_buffer,y
|
||||||
|
iny
|
||||||
|
lda #','
|
||||||
|
sta string_buffer,y
|
||||||
|
iny
|
||||||
|
lda #'W'
|
||||||
|
sta string_buffer,y
|
||||||
|
iny
|
||||||
|
sta string_length
|
||||||
|
|
||||||
|
jsr tftp_download
|
||||||
|
bcs @error
|
||||||
|
jsr close_file
|
||||||
|
rts
|
||||||
|
@error:
|
||||||
|
ldax #tftp_error
|
||||||
|
@error_set:
|
||||||
|
jsr print
|
||||||
|
jsr close_file
|
||||||
|
jmp set_error
|
||||||
|
|
||||||
|
close_file:
|
||||||
|
lda #$02 ; filenumber 2
|
||||||
|
jsr $FFC3 ; call CLOSE
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
tftp_download_callback:
|
||||||
|
|
||||||
|
;buffer pointed at by AX now contains "tftp_data_block_length" bytes
|
||||||
|
stax temp
|
||||||
|
|
||||||
|
lda #'.'
|
||||||
|
jsr print_a
|
||||||
|
lda file_opened
|
||||||
|
bne @already_opened
|
||||||
|
lda string_length
|
||||||
|
ldx #<string_buffer
|
||||||
|
ldy #>string_buffer
|
||||||
|
|
||||||
|
;A,X,Y set up ready for a call to SETNAM for file #2
|
||||||
|
jsr $FFBD ; call SETNAM
|
||||||
|
lda #$02 ; file number 2
|
||||||
|
ldx $BA ; last used drive
|
||||||
|
|
||||||
|
ldy #$02 ; secondary address 2
|
||||||
|
jsr $FFBA ; call SETLFS
|
||||||
|
|
||||||
|
jsr $FFC0 ; call OPEN
|
||||||
|
|
||||||
|
@already_opened:
|
||||||
|
|
||||||
|
ldx #$02 ; filenumber 2 = output file
|
||||||
|
jsr $FFC9 ; call CHKOUT
|
||||||
|
|
||||||
|
@copy_one_byte:
|
||||||
|
lda tftp_data_block_length
|
||||||
|
bne @not_done
|
||||||
|
lda tftp_data_block_length+1
|
||||||
|
beq @done
|
||||||
|
|
||||||
|
@not_done:
|
||||||
|
ldy #2 ;we want to skip the first 2 bytes in the buffer
|
||||||
|
lda (temp),y
|
||||||
|
jsr $ffd2 ;write byte
|
||||||
|
inc temp
|
||||||
|
bne :+
|
||||||
|
inc temp+1
|
||||||
|
:
|
||||||
|
lda tftp_data_block_length
|
||||||
|
dec tftp_data_block_length
|
||||||
|
cmp #0
|
||||||
|
bne @copy_one_byte
|
||||||
|
dec tftp_data_block_length+1
|
||||||
|
jmp @copy_one_byte
|
||||||
|
@done:
|
||||||
|
|
||||||
|
ldx #$00 ; filenumber 0 = console
|
||||||
|
jsr $FFC9 ; call CHKOUT
|
||||||
|
|
||||||
|
rts
|
||||||
|
|
||||||
.rodata
|
.rodata
|
||||||
vectors:
|
vectors:
|
||||||
.word crunch
|
.word crunch
|
||||||
.word list
|
.word list
|
||||||
.word execute
|
.word execute
|
||||||
|
|
||||||
.data
|
; Keyword list
|
||||||
|
; Keywords are stored as normal text,
|
||||||
|
; followed by the token number.
|
||||||
|
; All tokens are >$80,
|
||||||
|
; so they easily mark the end of the keyword
|
||||||
|
hexdigits:
|
||||||
|
.byte "0123456789ABCDEF"
|
||||||
|
|
||||||
|
pinging:
|
||||||
|
.byte"PINGING ",0
|
||||||
|
interface_type:
|
||||||
|
.byte "INTERFACE : ",0
|
||||||
|
|
||||||
|
mac_address_msg:
|
||||||
|
.byte "MAC ADDRESS : ", 0
|
||||||
|
|
||||||
|
ip_address_msg:
|
||||||
|
.byte "IP ADDRESS : ", 0
|
||||||
|
|
||||||
|
netmask_msg:
|
||||||
|
.byte "NETMASK : ", 0
|
||||||
|
|
||||||
|
gateway_msg:
|
||||||
|
.byte "GATEWAY : ", 0
|
||||||
|
|
||||||
|
dns_server_msg:
|
||||||
|
.byte "DNS SERVER : ", 0
|
||||||
|
|
||||||
|
dhcp_server_msg:
|
||||||
|
.byte "DHCP SERVER : ", 0
|
||||||
|
|
||||||
|
tftp_server_msg:
|
||||||
|
.byte "TFTP SERVER : ", 0
|
||||||
|
|
||||||
|
dns_error:
|
||||||
|
.byte "ADDRESS RESOLUTION ERROR",0
|
||||||
|
get_msg:
|
||||||
|
.byte "GETTING ",0
|
||||||
|
from_msg:
|
||||||
|
.byte " FROM ",0
|
||||||
|
tftp_error:
|
||||||
|
.byte "TFTP ERROR",0
|
||||||
|
dhcp_error:
|
||||||
|
.byte "DHCP INITIALIZATION ERROR",13,0
|
||||||
|
keywords:
|
||||||
|
.byte "IF",$E0 ;our dummy 'IF' entry takes $E0
|
||||||
|
.byte "IPCFG",$E1
|
||||||
|
.byte "DHCP",$E2
|
||||||
|
.byte "PING",$E3
|
||||||
|
.byte "MYIP",$E4
|
||||||
|
.byte "NETMASK",$E5
|
||||||
|
.byte "GATEWAY",$E6
|
||||||
|
.byte "DNS",$E7
|
||||||
|
.byte "TFTP",$E8
|
||||||
|
.byte "TFGET",$E9
|
||||||
|
.byte "TF",$A1,$E9 ;since BASIC will replace GET with A1
|
||||||
|
|
||||||
|
.byte $00 ;end of list
|
||||||
|
HITOKEN=$EA
|
||||||
|
|
||||||
|
;
|
||||||
|
; Table of token locations-1
|
||||||
|
;
|
||||||
|
token_routines:
|
||||||
|
E0: .word if_keyword-1
|
||||||
|
E1: .word ipcfg_keyword-1
|
||||||
|
E2: .word dhcp_keyword-1
|
||||||
|
E3: .word ping_keyword-1
|
||||||
|
E4: .word myip_keyword-1
|
||||||
|
E5: .word netmask_keyword-1
|
||||||
|
E6: .word gateway_keyword-1
|
||||||
|
E7: .word dns_keyword-1
|
||||||
|
E8: .word tftp_keyword-1
|
||||||
|
E9: .word tfget_keyword-1
|
||||||
|
.segment "SELF_MODIFIED_CODE"
|
||||||
|
|
||||||
|
|
||||||
jmp_crunch: .byte $4C ;JMP
|
jmp_crunch: .byte $4C ;JMP
|
||||||
@ -265,22 +908,29 @@ oldcrunch: .res 2 ;Old CRUNCH vector
|
|||||||
oldlist: .res 2
|
oldlist: .res 2
|
||||||
oldexec: .res 2
|
oldexec: .res 2
|
||||||
|
|
||||||
|
emit_a:
|
||||||
|
current_output_ptr=emit_a+1
|
||||||
|
sta $ffff
|
||||||
|
inc string_length
|
||||||
|
inc current_output_ptr
|
||||||
|
bne :+
|
||||||
|
inc current_output_ptr+1
|
||||||
|
:
|
||||||
|
rts
|
||||||
|
|
||||||
; Keyword list
|
|
||||||
; Keywords are stored as normal text,
|
|
||||||
; followed by the token number.
|
|
||||||
; All tokens are >$80,
|
|
||||||
; so they easily mark the end of the keyword
|
|
||||||
|
|
||||||
keywords:
|
|
||||||
.byte "FIZZ",$E0
|
|
||||||
.byte $00 ;end of list
|
|
||||||
HITOKEN=$E1
|
|
||||||
|
|
||||||
;
|
.bss
|
||||||
; Table of token locations-1
|
string_length: .res 1
|
||||||
; Subtract $E0 first
|
param_length: .res 1
|
||||||
; Then check to make sure number isn't greater than NUMWORDS
|
ip_string: .res 15
|
||||||
;
|
netmask_string: .res 15
|
||||||
token_routines:
|
dns_string: .res 15
|
||||||
E0: .word goober-1
|
gateway_string: .res 15
|
||||||
|
temp_bin: .res 1
|
||||||
|
temp_bcd: .res 2
|
||||||
|
ping_counter: .res 1
|
||||||
|
string_buffer: .res 128
|
||||||
|
transfer_buffer: .res 256
|
||||||
|
file_opened: .res 1
|
||||||
|
|
@ -33,6 +33,7 @@ CLOSE=$FFC3
|
|||||||
.import dns_resolve
|
.import dns_resolve
|
||||||
.import dns_ip
|
.import dns_ip
|
||||||
.import ip65_process
|
.import ip65_process
|
||||||
|
.import icmp_echo_ip
|
||||||
|
|
||||||
.zeropage
|
.zeropage
|
||||||
temp_buff: .res 2
|
temp_buff: .res 2
|
||||||
|
25
client/cfg/kipperbas.cfg
Normal file
25
client/cfg/kipperbas.cfg
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# CA65 config for a M/L stub that will use memory from $6000..$A000 and $c010..$cfff
|
||||||
|
|
||||||
|
MEMORY {
|
||||||
|
IP65ZP: start = $A3, size = $12, type = rw;
|
||||||
|
MAINRAM: start = $3ffe, size = $3FC9, define = yes, file = %O;
|
||||||
|
HIRAM: start = $C010, size = $0fE0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SEGMENTS {
|
||||||
|
STARTUP: load = MAINRAM, type = ro;
|
||||||
|
IP65_DEFAULTS: load = MAINRAM, type = ro;
|
||||||
|
CODE: load = MAINRAM, type = ro;
|
||||||
|
SELF_MODIFIED_CODE: load = MAINRAM, type = rw;
|
||||||
|
RODATA: load = MAINRAM, type = ro;
|
||||||
|
DATA: load = MAINRAM, type = rw, define = yes;
|
||||||
|
BSS: load = MAINRAM, type = bss;
|
||||||
|
|
||||||
|
IP65ZP: load = IP65ZP, type = zp;
|
||||||
|
|
||||||
|
ZEROPAGE: load = IP65ZP, type = zp;
|
||||||
|
|
||||||
|
TCP_VARS: load = HIRAM, type = bss;
|
||||||
|
}
|
@ -18,7 +18,6 @@
|
|||||||
.export tftp_upload
|
.export tftp_upload
|
||||||
.export tftp_data_block_length
|
.export tftp_data_block_length
|
||||||
.export tftp_set_callback_vector
|
.export tftp_set_callback_vector
|
||||||
.export tftp_data_block_length
|
|
||||||
.export tftp_clear_callbacks
|
.export tftp_clear_callbacks
|
||||||
.export tftp_filesize
|
.export tftp_filesize
|
||||||
.export tftp_upload_from_memory
|
.export tftp_upload_from_memory
|
||||||
@ -105,12 +104,7 @@ tftp_bytes_remaining: .res 2
|
|||||||
; outputs: carry flag is set if there was an error
|
; outputs: carry flag is set if there was an error
|
||||||
; if a callback vector has been set with tftp_set_callback_vector
|
; if a callback vector has been set with tftp_set_callback_vector
|
||||||
; then the specified routine will be called once for each 512 byte packet
|
; then the specified routine will be called once for each 512 byte packet
|
||||||
; sent from the tftp server (each time AX will point at data block just arrived,
|
; to be sent to the tftp server
|
||||||
; and tftp_data_block_length will contain number of bytes in that data block)
|
|
||||||
; otherwise, the buffer at tftp_load_address will be filled
|
|
||||||
; with file downloaded.
|
|
||||||
; tftp_load_address: will be set to the actual address loaded into (NB - this field is
|
|
||||||
; ignored if a callback vector has been set with tftp_set_callback_vector)
|
|
||||||
tftp_upload_from_memory:
|
tftp_upload_from_memory:
|
||||||
ldax #copy_ram_to_tftp_block
|
ldax #copy_ram_to_tftp_block
|
||||||
jsr tftp_set_callback_vector
|
jsr tftp_set_callback_vector
|
||||||
@ -559,6 +553,7 @@ copy_ram_to_tftp_block:
|
|||||||
; outputs: none
|
; outputs: none
|
||||||
tftp_set_callback_vector:
|
tftp_set_callback_vector:
|
||||||
stax tftp_callback_vector+1
|
stax tftp_callback_vector+1
|
||||||
|
inc tftp_callback_address_set
|
||||||
rts
|
rts
|
||||||
|
|
||||||
;clear callback vectors, i.e. all future transfers read from/write to RAM
|
;clear callback vectors, i.e. all future transfers read from/write to RAM
|
||||||
|
Loading…
Reference in New Issue
Block a user