git-svn-id: http://svn.code.sf.net/p/netboot65/code@274 93682198-c243-4bdb-bd91-e943c89aac3b

This commit is contained in:
jonnosan 2010-09-05 03:12:33 +00:00
parent 3246d36576
commit 71b42eb29d
14 changed files with 581 additions and 742 deletions

View File

@ -17,10 +17,8 @@ IP65LIB=../ip65/ip65_tcp.lib
C64PROGLIB=../drivers/c64prog.lib
all: kipperbas.d64 bails.prg
all: kipperbas.d64 bails.d64
bails.o: bails.s $(INCFILES) httpd.inc
$(AS) $(AFLAGS) $<
%.o: %.s $(INCFILES)
$(AS) $(AFLAGS) $<
@ -29,12 +27,18 @@ bails.o: bails.s $(INCFILES) httpd.inc
$(LD) -m $*.map -vm -C ../cfg/kipperbas.cfg -o $*.prg $(AFLAGS) $< $(IP65LIB) $(C64PROGLIB)
bails.d64: bails.prg
# ripxplore.rb -r -e kbload $@ -o kbload
# ripxplore.rb -r -e kbapp $@ -o kbapp
# ripxplore.rb $@ -I CbmDos -a kipperbas.prg
ripxplore.rb $@ -a bails.prg
kipperbas.d64: kipperbas.prg
# ripxplore.rb -r -e kbload $@ -o kbload
# ripxplore.rb -r -e kbapp $@ -o kbapp
# ripxplore.rb $@ -I CbmDos -a kipperbas.prg
ripxplore.rb $@ -a kipperbas.prg
clean:
rm -f *.o *.bin *.map *.prg

View File

@ -1,9 +1,14 @@
.include "../inc/common.i"
.ifndef KPR_API_VERSION_NUMBER
.define EQU =
.include "../inc/kipper_constants.i"
.endif
;.ifndef KPR_API_VERSION_NUMBER
; .define EQU =
; .include "../inc/kipper_constants.i"
;.endif
HTTPD_TIMEOUT_SECONDS=5 ;what's the maximum time we let 1 connection be open for?
;DEBUG=1
VARTAB = $2D ;BASIC variable table storage
ARYTAB = $2F ;BASIC array table storage
@ -14,6 +19,7 @@ VARPNT = $47 ; pointer to current BASIC variable value
SETNAM = $FFBD
SETLFS = $FFBA
LOAD = $FFD5
OPEN = $FFC0
CHKIN = $FFC6
READST = $FFB7 ; read status byte
@ -80,6 +86,18 @@ crunched_line = $0200 ;Input buffer
.import http_get_value
.import http_variables_buffer
.import tcp_inbound_data_ptr
.import tcp_inbound_data_length
.import tcp_send_data_len
.import tcp_send
.import check_for_abort_key
.import tcp_connect_remote_port
.import tcp_remote_ip
.import tcp_listen
.import tcp_callback
.import tcp_close
temp_ptr =copy_src
.zeropage
@ -151,13 +169,20 @@ install_new_vectors_loop:
sta ICRUNCH,x
dex
bpl install_new_vectors_loop
;copy error handlers:
ldax IERROR
stax olderror
ldax #error_handler
stax IERROR
;BASIC keywords installed, now bring up the ip65 stack
jsr ip65_init
@init_failed:
jsr $A644 ;do a "NEW"
jmp $A474 ;"READY" prompt
welcome_banner:
@ -818,7 +843,10 @@ hook_keyword:
goto:
sta $14
sta $39
stx $15
stx $3a
jmp $a8a3 ;GOTO keyword
@ -873,16 +901,26 @@ calc_hash:
yield_keyword:
rts
jsr flush_keyword
jsr tcp_close
.ifdef DEBUG
dec $d020
.endif
jmp httpd_start
gosub:
bang_keyword:
jsr extract_string
lda sent_header
bne :+
jsr send_header
:
ldy #0
sty string_ptr
@loop:
lda transfer_buffer,y
jsr putchar
jsr xmit_a
inc string_ptr
ldy string_ptr
cpy param_length
@ -890,20 +928,16 @@ bang_keyword:
rts
putchar:
jmp $ffd2
grok_keyword:
ldax #http_buffer
stax http_variables_buffer
jsr extract_string
ldax #transfer_buffer
got_http_request:
got_http_request:
jsr http_parse_request
ldax #path
jsr print
lda #$02
jsr http_get_value
stax copy_src
jsr print
jsr print_cr
ldy #0
@copy_path:
lda (copy_src),y
@ -974,11 +1008,15 @@ got_http_request:
jmp goto
httpd_keyword:
jsr get_integer
stax httpd_port_number
jsr skip_comma_get_integer
stax default_line_number
;start a HTTP server
;this routine will stay in an endless loop that is broken only if user press the ABORT key (runstop on a c64)
;inputs:
; none
;outputs:
; none
httpd_start:
ldx top_of_stack
txs
ldax #listening
jsr print
ldax #cfg_ip
@ -988,22 +1026,415 @@ httpd_keyword:
ldax httpd_port_number
jsr print_integer
jsr print_cr
jmp httpd_start
lda #0
sta $dc08 ;make sure TOD clock is started
@listen:
jsr tcp_close
ldax httpd_io_buffer
stax tcp_buffer_ptr
ldax #http_callback
stax tcp_callback
ldax httpd_port_number
jsr tcp_listen
bcs @abort_key_pressed
@connect_ok:
.ifdef DEBUG
inc $d020
.endif
ldax #connection_from
jsr print
ldax #tcp_remote_ip
jsr print_dotted_quad
lda #':'
jsr print_a
ldax tcp_connect_remote_port
jsr print_integer
jsr print_cr
lda #0
sta connection_closed
sta found_eol
clc
lda $dc09 ;time of day clock: seconds (in BCD)
sed
adc #HTTPD_TIMEOUT_SECONDS
cmp #$60
bcc @timeout_set
sec
sbc #$60
@timeout_set:
cld
sta connection_timeout_seconds
@main_polling_loop:
jsr ip65_process
jsr check_for_abort_key
bcc @no_abort
@abort_key_pressed:
lda #0
sta error_handling_mode
ldx #$1E ;break
jmp $e38b ;print error message, warm start BASIC
@no_abort:
lda found_eol
bne @got_eol
lda $dc09 ;time of day clock: seconds
cmp connection_timeout_seconds
beq @connection_timed_out
lda connection_closed
beq @main_polling_loop
@connection_timed_out:
.ifdef DEBUG
dec $d020
.endif
jmp @listen
@got_eol:
jsr reset_output_buffer
ldy #$FF
:
iny
lda status_ok,y
sta status_code_buffer,y
bne :-
ldy #$FF
:
iny
lda text_html,y
sta content_type_buffer,y
bne :-
sta sent_header
ldax httpd_io_buffer
jmp got_http_request
http_callback:
lda tcp_inbound_data_length+1
cmp #$ff
bne @not_eof
inc connection_closed
@done:
rts
@not_eof:
lda found_eol
bne @done
;copy this chunk to our input buffer
ldax tcp_buffer_ptr
stax copy_dest
ldax tcp_inbound_data_ptr
stax copy_src
ldax tcp_inbound_data_length
jsr copymem
;increment the pointer into the input buffer
clc
lda tcp_buffer_ptr
adc tcp_inbound_data_length
sta tcp_buffer_ptr
sta temp_ptr
lda tcp_buffer_ptr+1
adc tcp_inbound_data_length+1
sta tcp_buffer_ptr+1
sta temp_ptr+1
;put a null byte at the end (assumes we have set temp_ptr already)
lda #0
tay
sta (temp_ptr),y
;look for CR or LF in input
sta found_eol
ldax httpd_io_buffer
stax get_next_byte+1
@look_for_eol:
jsr get_next_byte
cmp #$0a
beq @found_eol
cmp #$0d
bne @not_eol
@found_eol:
inc found_eol
rts
@not_eol:
cmp #0
bne @look_for_eol
rts
reset_output_buffer:
ldax httpd_io_buffer
sta xmit_a_ptr+1
stx xmit_a_ptr+2
lda #0
sta output_buffer_length
sta output_buffer_length+1
rts
send_buffer:
ldax output_buffer_length
stax tcp_send_data_len
ldax httpd_io_buffer
jsr tcp_send
jmp reset_output_buffer
emit_string:
stax temp_ptr
ldy #0
@next_byte:
lda (temp_ptr),y
beq @done
jsr xmit_a
iny
bne @next_byte
@done:
rts
httpd_keyword:
jsr get_integer
stax httpd_port_number
jsr skip_comma_get_integer
stax default_line_number
inc error_handling_mode
tsx
stx top_of_stack
jmp httpd_start
status_keyword:
jsr extract_string
ldy #$FF
@loop:
iny
lda transfer_buffer,y
sta status_code_buffer,y
bne @loop
rts
type_keyword:
jsr extract_string
ldy #$FF
@loop:
iny
lda transfer_buffer,y
sta content_type_buffer,y
bne @loop
rts
send_header:
inc sent_header
ldax #http_version
jsr emit_string
ldax #status_code_buffer
jsr emit_string
ldax #crlf
jsr emit_string
ldax #content_type
jsr emit_string
ldax #content_type_buffer
jsr emit_string
ldax #end_of_header
jmp emit_string
flush_keyword:
lda output_buffer_length
bne :+
ldx output_buffer_length+1
bne :+
rts
:
jmp send_buffer
xsend_keyword:
jsr extract_string
ldx #<transfer_buffer
ldy #>transfer_buffer
lda param_length
jsr SETNAM
lda #$02 ; file number 2
ldx $BA ; last used device number
bne @skip
ldx #$08 ; default to device 8
@skip:
ldy #$02 ; secondary address 2
jsr SETLFS
jsr OPEN
bcs @error ; if carry set, the file could not be opened
ldx #$02 ; filenumber 2
jsr CHKIN
@loop:
jsr CHRIN
sta tmp_a
jsr READST
bne @eof ; either EOF or read error
lda sent_header
bne :+
jsr send_header
:
lda tmp_a
jsr xmit_a
jmp @loop
@eof:
and #$40 ; end of file?
beq @error
lda tmp_a
jsr xmit_a
@close_handles:
lda #$02 ; filenumber 2
jsr CLOSE
ldx #$00 ; filenumber 0 = keyboard
jsr CHKIN ;keyboard now input device again
rts
@error:
lda #$00 ; no filename
tax
tay
jsr SETNAM
lda #$0f ;file number 15
ldx $ba ;drive number
ldy #$0f ; secondary address 15 (error channel)
jsr SETLFS
jsr OPEN
LDX #$0F ; filenumber 15
JSR CHKIN ;(file 15 now used as input)
LDY #$00
@error_loop:
JSR READST ;(read status byte)
BNE @error_eof ; either EOF or read error
JSR CHRIN ;(get a byte from file)
sta error_buffer,y
iny
JMP @error_loop ; next byte
@error_eof:
lda #0
sta error_buffer,y
LDX #$00 ; filenumber 0 = keyboard
JSR CHKIN ;(keyboard now input device again)
jsr @close_handles
jmp create_error
create_error:
lda sent_header
bne @header_sent
ldy #$FF
:
iny
lda status_error,y
sta status_code_buffer,y
bne :-
jsr send_header
@header_sent:
ldax #error_start
jsr emit_string
ldax #system_error
jsr print
lda $3a ;current line number
ldx $39
sta $62
stx $63
ldx #$90 ;exponent to 16
sec
jsr $bc49 ;pad out flp acc
jsr $bddf ;convert to string
jsr $b487 ;move string descriptor into flp acc
jsr $b6a6 ;get text pointer into $22/$23
tay
lda #0
sta ($22),y
lda $22
ldx $23
jsr emit_string
jsr emit_br
ldax #line_number
jsr print
lda $22
ldx $23
jsr print
jsr print_cr
ldax #error_buffer
jsr emit_string
ldax #error_buffer
jsr print
jmp yield_keyword
emit_br:
ldax #br
jmp emit_string
error_handler:
ldy error_handling_mode
bne @send_error_to_browser
jmp (olderror)
@send_error_to_browser:
txa
asl a
tax
lda $a326,x ; fetch address from table of error messages
sta $22
lda $a327,x ; fetch address from table of error messages
sta $23
ldy #0
@one_char:
lda ($22),y
pha
and #$7f
sta error_buffer,y
iny
pla
bpl @one_char
lda #0
sta error_buffer,y
jmp create_error
.rodata
vectors:
.word crunch
.word list
.word execute
; 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"
CR=$0D
LF=$0A
error_start:
.byte "<h1>SYSTEM ERROR</h1><br>"
line_number:
.byte " LINE NUMBER: ",0
br:
.byte "<br>",CR,LF,0
listening:
.byte"LISTENING ON ",0
@ -1050,6 +1481,43 @@ disconnected:
connected_msg:
.byte "CONNECTED",13,0
loaded:
.byte " LOADED",13,0
skipped:
.byte " SKIPPED",13,0
path:
.byte "PATH: ",0
http_version:
.byte "HTTP/1.0 ",0
status_ok:
.byte "200 OK",0
status_error:
.byte "500 "
system_error:
.byte "SYSTEM ERROR",0
content_type:
.byte "Content-Type: ",0
text_html:
.byte "text/html",0
end_of_header:
.byte CR,LF
.byte "Connection: Close",CR,LF
.byte "Server: BoB_httpd/0.c64",CR,LF
crlf:
.byte CR,LF,0
connection_from: .byte "CONNECTION FROM ",0
; 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 "IF",$E0 ;our dummy 'IF' entry takes $E0
.byte "IPCFG",$E1
@ -1061,11 +1529,14 @@ keywords:
.byte "DNS",$E7
.byte "HOOK",$E8
.byte "YIELD",$E9
.byte "GROK",$EA
.byte "XS",$80,$EA ;BASIC will replace 'END' with $80
.byte "!",$EB
.byte "HTTPD",$EC
.byte "TYPE",$ED
.byte "STATUS",$EE
.byte "FLUSH",$EF
.byte $00 ;end of list
HITOKEN=$ED
HITOKEN=$F0
;
; Table of token locations-1
@ -1081,9 +1552,12 @@ E6: .word gateway_keyword-1
E7: .word dns_keyword-1
E8: .word hook_keyword-1
E9: .word yield_keyword-1
EA: .word grok_keyword-1
EA: .word xsend_keyword-1
EB: .word bang_keyword-1
EC: .word httpd_keyword-1
ED: .word type_keyword-1
EE: .word status_keyword-1
EF: .word flush_keyword-1
.segment "SELF_MODIFIED_CODE"
@ -1092,6 +1566,7 @@ jmp_crunch: .byte $4C ;JMP
oldcrunch: .res 2 ;Old CRUNCH vector
oldlist: .res 2
oldexec: .res 2
olderror: .res 2
emit_a:
current_output_ptr=emit_a+1
@ -1114,6 +1589,7 @@ hook_table:
; $04/$05 line number that hook handler starts at
hooks: .byte 0
error_handling_mode: .byte 0
.bss
string_length: .res 1
@ -1124,14 +1600,64 @@ temp_bcd: .res 2
ping_counter: .res 1
http_buffer: .res 256
string_buffer: .res 128
content_type_buffer: .res 128
status_code_buffer: .res 128
transfer_buffer: .res 256
handler_address: .res 2
hash: .res 1
string_ptr: .res 1
default_line_number: .res 2
found_eol: .byte 0
connection_closed: .byte 0
output_buffer_length: .res 2
connection_timeout_seconds: .byte 0
tcp_buffer_ptr: .res 2
buffer_size: .res 1
temp_x: .res 1
sent_header: .res 1
tmp_a: .res 1
error_buffer: .res 80
top_of_stack: .res 1
.segment "TCP_VARS"
__httpd_io_buffer: .res 1024 ;temp buffer for storing inbound requests.
.segment "HTTP_VARS"
httpd_io_buffer: .word __httpd_io_buffer
httpd_port_number: .word 80
get_next_byte:
lda $ffff
inc get_next_byte+1
bne @skip
inc get_next_byte+2
@skip:
rts
xmit_a:
xmit_a_ptr:
sta $ffff
inc xmit_a_ptr+1
bne :+
inc xmit_a_ptr+2
:
inc output_buffer_length
bne :+
inc output_buffer_length+1
lda output_buffer_length+1
cmp #2
bne :+
stx temp_x
jsr send_buffer
ldx temp_x
:
rts
.include "httpd.inc"
;-- LICENSE FOR bails.s --
; The contents of this file are subject to the Mozilla Public License
; Version 1.1 (the "License"); you may not use this file except in

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,379 +0,0 @@
;a simple HTTP server (ip65 httpd customised for use with BASIC on bails)
;.include "../inc/common.i"
;
;.ifndef KPR_API_VERSION_NUMBER
; .define EQU =
; .include "../inc/kipper_constants.i"
;.endif
HTTPD_TIMEOUT_SECONDS=5 ;what's the maximum time we let 1 connection be open for?
DEBUG=1
.import http_parse_request
.import http_get_value
.import tcp_listen
.import tcp_callback
.import ip65_process
.import check_for_abort_key
.import ip65_error
.import parse_hex_digits
.import copymem
.importzp copy_src
.importzp copy_dest
.import tcp_inbound_data_ptr
.import tcp_inbound_data_length
.import tcp_send_data_len
.import tcp_send
.import tcp_close
.import io_read_catalogue
.import native_to_ascii
.import io_read_file_with_callback
.import io_filename
.import io_callback
.import tcp_connect_remote_port
.import tcp_remote_ip
temp_ptr =copy_src
.bss
found_eol: .byte 0
connection_closed: .byte 0
output_buffer_length: .res 2
sent_header: .res 1
connection_timeout_seconds: .byte 0
tcp_buffer_ptr: .res 2
buffer_size: .res 1
temp_x: .res 1
.segment "TCP_VARS"
__httpd_io_buffer: .res 1024 ;temp buffer for storing inbound requests.
.segment "HTTP_VARS"
httpd_io_buffer: .word __httpd_io_buffer
httpd_port_number: .word 80
get_next_byte:
lda $ffff
inc get_next_byte+1
bne @skip
inc get_next_byte+2
@skip:
rts
xmit_a:
xmit_a_ptr:
sta $ffff
inc xmit_a_ptr+1
bne :+
inc xmit_a_ptr+2
:
inc output_buffer_length
bne :+
inc output_buffer_length+1
lda output_buffer_length+1
cmp #2
bne :+
stx temp_x
jsr send_buffer
ldx temp_x
:
rts
.code
;start a HTTP server
;this routine will stay in an endless loop that is broken only if user press the ABORT key (runstop on a c64)
;inputs:
; none
;outputs:
; none
httpd_start:
lda #0
sta $dc08 ;make sure TOD clock is started
@listen:
jsr tcp_close
ldax httpd_io_buffer
stax tcp_buffer_ptr
ldax #http_callback
stax tcp_callback
ldax httpd_port_number
jsr tcp_listen
bcc @connect_ok
rts
@connect_ok:
.ifdef DEBUG
inc $d020
.endif
ldax #connection_from
jsr print
ldax #tcp_remote_ip
jsr print_dotted_quad
lda #':'
jsr print_a
ldax tcp_connect_remote_port
jsr print_integer
jsr print_cr
lda #0
sta connection_closed
sta found_eol
clc
lda $dc09 ;time of day clock: seconds (in BCD)
sed
adc #HTTPD_TIMEOUT_SECONDS
cmp #$60
bcc @timeout_set
sec
sbc #$60
@timeout_set:
cld
sta connection_timeout_seconds
@main_polling_loop:
jsr ip65_process
jsr check_for_abort_key
bcc @no_abort
lda #KPR_ERROR_ABORTED_BY_USER
sta ip65_error
rts
@no_abort:
lda found_eol
bne @got_eol
lda $dc09 ;time of day clock: seconds
cmp connection_timeout_seconds
beq @connection_timed_out
lda connection_closed
beq @main_polling_loop
@connection_timed_out:
.ifdef DEBUG
dec $d020
.endif
jmp @listen
@got_eol:
ldax httpd_io_buffer
jmp got_http_request
http_callback:
lda tcp_inbound_data_length+1
cmp #$ff
bne @not_eof
inc connection_closed
@done:
rts
@not_eof:
lda found_eol
bne @done
;copy this chunk to our input buffer
ldax tcp_buffer_ptr
stax copy_dest
ldax tcp_inbound_data_ptr
stax copy_src
ldax tcp_inbound_data_length
jsr copymem
;increment the pointer into the input buffer
clc
lda tcp_buffer_ptr
adc tcp_inbound_data_length
sta tcp_buffer_ptr
sta temp_ptr
lda tcp_buffer_ptr+1
adc tcp_inbound_data_length+1
sta tcp_buffer_ptr+1
sta temp_ptr+1
;put a null byte at the end (assumes we have set temp_ptr already)
lda #0
tay
sta (temp_ptr),y
;look for CR or LF in input
sta found_eol
ldax httpd_io_buffer
stax get_next_byte+1
@look_for_eol:
jsr get_next_byte
cmp #$0a
beq @found_eol
cmp #$0d
bne @not_eol
@found_eol:
inc found_eol
rts
@not_eol:
cmp #0
bne @look_for_eol
rts
reset_output_buffer:
ldax httpd_io_buffer
sta xmit_a_ptr+1
stx xmit_a_ptr+2
lda #0
sta output_buffer_length
sta output_buffer_length+1
rts
send_buffer:
ldax output_buffer_length
stax tcp_send_data_len
ldax httpd_io_buffer
jsr tcp_send
jmp reset_output_buffer
send_header:
;inputs: Y = header type
;$00 = no header (assume header sent already)
;$01 = 200 OK, 'text/text'
;$02 = 200 OK, 'text/html'
;$03 = 200 OK, 'application/octet-stream'
;$04 = 404 Not Found
;$05..$FF = 500 System Error
cpy #00
bne :+
rts
:
cpy #1
bne @not_text
jsr emit_ok_status_line_and_content_type
ldax #text_text
jsr emit_string
jmp @done
@not_text:
cpy #2
bne @not_html
jsr emit_ok_status_line_and_content_type
ldax #text_html
jsr emit_string
jmp @done
@not_html:
cpy #3
bne @not_binary
jsr emit_ok_status_line_and_content_type
ldax #application_octet_stream
jsr emit_string
jmp @done
@not_binary:
cpy #4
bne @not_404
ldax #http_version
jsr emit_string
ldax #status_not_found
jsr emit_string
jsr @done
ldax #status_not_found
jmp emit_string
@not_404:
ldax #http_version
jsr emit_string
ldax #status_system_error
jsr emit_string
jsr @done
ldax #status_system_error
jmp emit_string
@done:
ldax #end_of_header
jmp emit_string
emit_ok_status_line_and_content_type:
ldax #http_version
jsr emit_string
ldax #status_ok
jsr emit_string
ldax #content_type
jmp emit_string
emit_string:
stax temp_ptr
ldy #0
@next_byte:
lda (temp_ptr),y
beq @done
jsr xmit_a
iny
bne @next_byte
@done:
rts
.rodata
CR=$0D
LF=$0A
http_version:
.byte "HTTP/1.0 ",0
status_ok:
.byte "200 OK",CR,LF,0
status_not_found:
.byte "404 Not Found",CR,LF,0
status_system_error:
.byte "500 System Error",CR,LF,0
content_type:
.byte "Content-Type: ",0
text_text:
.byte "text/text",CR,LF,0
text_html:
.byte "text/html",CR,LF,0
application_octet_stream:
.byte "application/octet-stream",CR,LF,0
end_of_header:
.byte "Connection: Close",CR,LF
.byte "Server: BoB_httpd/0.c64",CR,LF
.byte CR,LF,0
connection_from: .byte "CONNECTION FROM ",0
;-- LICENSE FOR httpd.inc --
; The contents of this file are subject to the Mozilla Public License
; Version 1.1 (the "License"); you may not use this file except in
; compliance with the License. You may obtain a copy of the License at
; http://www.mozilla.org/MPL/
;
; Software distributed under the License is distributed on an "AS IS"
; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
; License for the specific language governing rights and limitations
; under the License.
;
; The Original Code is netboot65.
;
; The Initial Developer of the Original Code is Jonno Downes,
; jonno@jamtronix.com.
; Portions created by the Initial Developer are Copyright (C) 2009,2010
; Jonno Downes. All Rights Reserved.
; -- LICENSE END --

View File

@ -0,0 +1,15 @@
10 dhcp
20 hook"/hello",1000
30 httpd80,100
100 !"<h1>hello</h1>"
110 !"<form action=/hello>"
120 !"what's your name?"
130 !"<input type=text name=n>"
140 !"</form>"
200 yield
100 !"<h1>hello</h1>"
1000!"<br>hello "+n$+", i'm a c64 running basic on bails."
1010 yield

View File

Binary file not shown.

Binary file not shown.

View File

@ -19,7 +19,7 @@ CHKIN = $FFC6
READST = $FFB7 ; read status byte
CHRIN = $FFCF ; get a byte from file
CLOSE = $FFC3
MEMTOP = $FE25
MEMTOP = $FE25
TXTPTR = $7A ;BASIC text pointer
IERROR = $0300
ICRUNCH = $0304 ;Crunch ASCII into token

View File

@ -1,327 +0,0 @@
.include "../inc/common.i"
.include "../inc/commonprint.i"
VARTAB=$2D ;BASIC variable table storage
ARYTAB=$2F ;BASIC array table storage
FREETOP=$33 ;bottom of string text storage area
MEMSIZ=$37 ;highest address used by BASIC
CLEAR=$A65E ;clears BASIC variables
SETNAM=$FFBD
SETLFS=$FFBA
OPEN=$FFC0
CHKIN=$FFC6
READST=$FFB7 ; read status byte
CHRIN=$FFCF ; get a byte from file
CLOSE=$FFC3
.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 icmp_echo_ip
.zeropage
temp_buff: .res 2
.segment "STARTUP" ;this is what gets put at the start of the file on the C64
.word jump_table ; load address
jump_table:
jmp init ; $4000 (PTR) - vars io$,io%,er% should be created (in that order!) before calling
jmp listen_on_port ; $4003 (PTR+3) - io% is port to listen on
jmp send_data ; $4006 (PTR+6) - io$ is string to send
jmp check_for_data ; $4009 (PTR+9) - after return, io% 0 means no new data, 1 means io$ set to new data
jmp connect_to_server ; $400c (PTR+12) - io$ is remote server name or ip, io% is remote port
jmp send_file ; $400f (PTR+15) - io$ is name of file (on last accessed drive) to send over current channel
jmp close_connection ; $4002 (ptr+18) - no inputs needed
.code
init:
;IO$,IO% and ER% should be first three variables created!
lda #14
jsr print_a ;switch to lower case
ldax #init_msg+1
jsr print_ascii_as_native
jsr ip65_init
bcs @init_failed
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 cartridge default values)
bcc @init_ok
@init_failed:
print_failed
jsr print_errorcode
jmp set_error_var
@init_ok:
jsr print_ip_config
exit_to_basic:
rts
setup_for_tcp:
ldax #tcp_data_arrived
stax tcp_callback
lda #0
sta ip65_error
rts
listen_on_port:
jsr setup_for_tcp
jsr get_io_var
jsr tcp_listen
bcs @error
ldax #connected
jsr print_ascii_as_native
ldax #tcp_connect_ip
jsr print_dotted_quad
jsr print_cr
lda #0
sta ip65_error
@error:
jmp set_error_var
send_data:
jsr get_io_string_ptr
sty tcp_send_data_len
ldy #0
sty tcp_send_data_len+1
jsr tcp_send
bcs @error
lda #0
sta ip65_error
@error:
jmp set_error_var
set_error_var:
ldy #16 ;we want to set 3rd & 4th byte of 3rd entry in variable table entry
ldx #0
lda ip65_error
jmp set_var
set_io_var:
ldy #9 ;we want to set 3rd & 4th byte of 2nd entry in variable table entry
set_var:
pha
txa
sta (VARTAB),y ; set high byte
iny
pla
sta (VARTAB),y ; set low byte
rts
get_io_var:
ldy #9 ;we want to read 3rd & 4th byte of 2nd entry in variable table entry
lda (VARTAB),y ; set high byte
tax
iny
lda (VARTAB),y ; set low byte
rts
get_io_string_ptr:
ldy #4 ;we want to read 1st entry in variable table entry
lda (VARTAB),y ; ptr high byte
tax
dey
lda (VARTAB),y ; ptr low byte
pha
dey
lda (VARTAB),y ; length
tay
pla
rts
get_io_string: ;we want to turn from a string prefixed by length to nul terminated
jsr get_io_string_ptr
stax copy_src
ldax #transfer_buffer
stax copy_dest
lda #0
sta (copy_dest),y ;null terminate the string
tax
tya
jmp copymem
set_io_string:
stax copy_src
ldax #transfer_buffer
stax copy_dest
ldy #0
@loop:
lda (copy_src),y
beq @done
sta (copy_dest),y
iny
bne @loop
@done:
set_io_string_ptr:
tya ;length of string copied
ldy #2 ;length is 2nd byte of variable table entry
sta (VARTAB),y
iny
lda #<transfer_buffer
sta (VARTAB),y
iny
lda #>transfer_buffer
sta (VARTAB),y
rts
check_for_data:
lda #0
sta ip65_error
jsr set_error_var
sta data_arrived_flag
jsr ip65_process
bcc @no_error
jsr set_error_var
@no_error:
lda data_arrived_flag
ldx #0
jmp set_io_var
tcp_data_arrived:
inc data_arrived_flag
ldax #transfer_buffer
stax copy_dest
ldax tcp_inbound_data_ptr
stax copy_src
lda tcp_inbound_data_length
ldx tcp_inbound_data_length+1
beq @short_packet
cpx #$ff
bne @not_end_packet
inc data_arrived_flag
rts
@not_end_packet:
lda #$ff
@short_packet:
tay
pha
jsr set_io_string_ptr
pla
ldx #0
jmp copymem
rts
connect_to_server:
jsr get_io_string
ldax #transfer_buffer
jsr dns_set_hostname
bcs @error
jsr dns_resolve
bcs @error
ldx #4
@copy_dns_ip:
lda dns_ip,y
sta tcp_connect_ip,y
iny
dex
bne @copy_dns_ip
jsr setup_for_tcp
jsr get_io_var
jsr tcp_connect
@error:
jmp set_error_var
send_file:
jsr get_io_string_ptr ;AX ptr, Y is length
stax copy_src
tya
ldx copy_src
ldy copy_src+1
jsr SETNAM
lda #$02 ; file number 2
ldx $BA ; last used device number
bne @skip
ldx #$08 ; default to device 8
@skip:
ldy #$02 ; secondary address 2
jsr SETLFS
jsr OPEN
bcs @error ; if carry set, the file could not be opened
ldx #$02 ; filenumber 2
jsr CHKIN
ldy #$00
@loop:
jsr READST
bne @eof ; either EOF or read error
jsr CHRIN
sta transfer_buffer,y
iny
bne @loop
ldax #$100
stax tcp_send_data_len
ldax #transfer_buffer
jsr tcp_send
bcs @error_stored
ldy #0
jmp @loop
@eof:
and #$40 ; end of file?
beq @readerror
lda #$00
sty tcp_send_data_len
sta tcp_send_data_len+1
ldax #transfer_buffer
jsr tcp_send
bcs @error_stored
@close:
lda #0
@store_error:
sta ip65_error
@error_stored:
jsr set_error_var
lda #$02 ; filenumber 2
jsr CLOSE
ldx #$00 ; filenumber 0 = keyboard
jsr CHKIN ;keyboard now input device again
rts
@error:
lda #KPR_ERROR_DEVICE_FAILURE
jmp @store_error
@readerror:
lda #KPR_ERROR_FILE_ACCESS_FAILURE
jmp @store_error
close_connection:
jsr tcp_close
bcs @error
lda #0
sta ip65_error
@error:
jmp set_error_var
.data
data_arrived_flag: .byte 0
connected:
.byte "connected - ",0
.bss
transfer_buffer: .res $100