diff --git a/client/drivers/c64inputs.s b/client/drivers/c64inputs.s index 469ee14..2c6421d 100644 --- a/client/drivers/c64inputs.s +++ b/client/drivers/c64inputs.s @@ -6,8 +6,11 @@ .export filter_number .export check_for_abort_key .export get_key_if_available +.export get_key_ip65 .importzp copy_src +.import ip65_process + .include "../inc/common.i" .code @@ -25,7 +28,17 @@ get_key: ;inputs: none ;outputs: A contains ASCII value of key just pressed (0 if no key pressed) get_key_if_available=$ffe4 - + + +;process inbound ip packets while waiting for a keypress +get_key_ip65: + jsr ip65_process + jsr $ffe4 + beq get_key_ip65 + rts + + + ;check whether the RUN/STOP key is being pressed ;inputs: none @@ -49,7 +62,8 @@ check_for_abort_key: ;cribbed from http://codebase64.org/doku.php?id=base:robust_string_input ;====================================================================== ;Input a string and store it in GOTINPUT, terminated with a null byte. -;x:a is a pointer to the allowed list of characters, null-terminated. +;AX is a pointer to the allowed list of characters, null-terminated. +;set AX to $0000 for no filter on input ;max # of chars in y returns num of chars entered in y. ;====================================================================== @@ -64,35 +78,37 @@ get_filtered_input: sta INPUT_Y ;Wait for a character. -INPUT_GET: - jsr get_key +@input_get: + jsr get_key_ip65 sta LASTCHAR cmp #$14 ;Delete - beq DELETE + beq @delete cmp #$0d ;Return - beq INPUT_DONE + beq @input_done ;End reached? lda INPUT_Y cmp MAXCHARS - beq INPUT_GET + beq @input_get ;Check the allowed list of characters. ldy #$00 -CHECKALLOWED: + lda allowed_ptr+1 ;was the input filter point nul? + beq @input_ok +@check_allowed: lda (allowed_ptr),y ;Overwritten - beq INPUT_GET ;Reached end of list (0) + beq @input_get ;Reached end of list (0) cmp LASTCHAR - beq INPUTOK ;Match found + beq @input_ok ;Match found ;Not end or match, keep checking iny - jmp CHECKALLOWED + jmp @check_allowed -INPUTOK: +@input_ok: lda LASTCHAR ;Get the char back ldy INPUT_Y sta GOTINPUT,y ;Add it to string @@ -100,30 +116,29 @@ INPUTOK: inc INPUT_Y ;Next character - ;Not yet. - jmp INPUT_GET + jmp @input_get -INPUT_DONE: +@input_done: ldy INPUT_Y - beq no_input + beq @no_input lda #$00 sta GOTINPUT,y ;Zero-terminate clc ldax #GOTINPUT rts -no_input: +@no_input: sec rts ; Delete last character. -DELETE: +@delete: ;First, check if we're at the beginning. If so, just exit. lda INPUT_Y - bne DELETE_OK - jmp INPUT_GET + bne @delete_ok + jmp @input_get ;At least one character entered. -DELETE_OK: +@delete_ok: ;Move pointer back. dec INPUT_Y @@ -137,7 +152,7 @@ DELETE_OK: jsr $ffd2 ;Wait for next char - jmp INPUT_GET + jmp @input_get ;================================================= @@ -159,4 +174,3 @@ MAXCHARS: .res 1 LASTCHAR: .res 1 INPUT_Y: .res 1 GOTINPUT: .res 40 - diff --git a/client/examples/httpd.asm b/client/examples/httpd.asm index b398d1e..ceece71 100644 --- a/client/examples/httpd.asm +++ b/client/examples/httpd.asm @@ -121,16 +121,9 @@ listen_on_port_80 nb65call #NB65_PRINT_HEX lda #"!" jsr print_a - ldaxi #4 + ldaxi #html_length stax nb65_param_buffer+NB65_TCP_PAYLOAD_LENGTH - ldaxi #press_a_key_to_continue - stax nb65_param_buffer+NB65_TCP_PAYLOAD_POINTER - ldaxi #nb65_param_buffer - nb65call #NB65_SEND_TCP_PACKET - - ldaxi #4 - stax nb65_param_buffer+NB65_TCP_PAYLOAD_LENGTH - ldaxi #nb65_signature + ldaxi #html stax nb65_param_buffer+NB65_TCP_PAYLOAD_POINTER ldaxi #nb65_param_buffer nb65call #NB65_SEND_TCP_PACKET @@ -276,6 +269,10 @@ failed dc.b "FAILED ", 0 ok dc.b "OK ", 0 transmission_error dc.b "ERROR WHILE SENDING ",0 +html dc.b "

c64 test page

foo:
bar:
" +html_end +html_length equ html_end-html + ;self modifying code get_next_byte lda $ffff diff --git a/client/inc/nb65_constants.i b/client/inc/nb65_constants.i index 3b3b7ee..55cec2e 100644 --- a/client/inc/nb65_constants.i +++ b/client/inc/nb65_constants.i @@ -53,8 +53,9 @@ NB65_PRINT_DOTTED_QUAD EQU $82 ;inputs: AX=pointer to 4 bytes that will NB65_PRINT_IP_CONFIG EQU $83 ;no inputs, no outputs, prints to screen current IP configuration -NB65_INPUT_HOSTNAME EQU $90 ;no inputs, outputs: AX = pointer to hostname (which may be IP address). -NB65_INPUT_PORT_NUMBER EQU $91 ;no inputs, outputs: AX = port number entered ($0000..$FFFF) +NB65_INPUT_STRING EQU $90 ;no inputs, outputs: AX = pointer to null terminated string +NB65_INPUT_HOSTNAME EQU $91 ;no inputs, outputs: AX = pointer to hostname (which may be IP address). +NB65_INPUT_PORT_NUMBER EQU $92 ;no inputs, outputs: AX = port number entered ($0000..$FFFF) NB65_BLOCK_COPY EQU $A0 ;inputs: AX points to a block copy structure, outputs: none diff --git a/client/inc/telnet.i b/client/inc/telnet.i index 124e766..5a87d6e 100644 --- a/client/inc/telnet.i +++ b/client/inc/telnet.i @@ -9,7 +9,7 @@ ; .include "../inc/c64keycodes.i" ; 3) define a routine called 'exit_telnet' ; 4) define a buffer called 'scratch_buffer' -; 5) define a zero page var called temp_ptr +; 5) define a zero page var called buffer_ptr .code telnet_main_entry: ;prompt for a hostname, then resolve to an IP address @@ -68,22 +68,30 @@ telnet_main_entry: beq @petscii_mode jmp @char_mode_input @ascii_mode: -; lda #14 -; jsr print_a ;switch to lower case lda #0 - jmp @character_mode_set -@petscii_mode: -; lda #142 -; jsr print_a ;switch to upper case + sta character_set + sta line_mode lda #1 -@character_mode_set: - sta character_mode + sta local_echo + lda #telnet_state_normal + sta telnet_state + jmp @after_mode_set +@petscii_mode: + lda #1 + sta character_set + lda #0 + sta local_echo + sta line_mode + + +@after_mode_set: + lda #147 ; 'CLR/HOME' jsr print_a ldax #connecting_in jsr print - lda character_mode + lda character_set beq @a_mode ldax #petscii jsr print @@ -127,6 +135,35 @@ telnet_connect: jsr print jmp telnet_main_entry @not_disconnected: + lda line_mode + beq @not_line_mode + + nb65call #NB65_INPUT_STRING + stax buffer_ptr + ldy #0 +@copy_one_char: + lda (buffer_ptr),y + tax + lda petscii_to_ascii_table,x + beq @end_of_input_string + sta scratch_buffer,y + iny + bne @copy_one_char +@end_of_input_string: + lda #$0d + sta scratch_buffer,y + iny + lda #$0a + sta scratch_buffer,y + iny + sty nb65_param_buffer+NB65_TCP_PAYLOAD_LENGTH + lda #0 + sta nb65_param_buffer+NB65_TCP_PAYLOAD_LENGTH+1 + + jmp @no_more_input + +@not_line_mode: + ;is there anything in the input buffer? lda $c6 ;NDX - chars in keyboard buffer beq @main_polling_loop @@ -135,6 +172,9 @@ telnet_connect: sta nb65_param_buffer+NB65_TCP_PAYLOAD_LENGTH+1 @get_next_char: jsr $ffe4 ;getkey - 0 means no input +; pha +; jsr print_hex +; pla tax beq @no_more_input cmp #$03 ;RUN/STOP @@ -153,9 +193,20 @@ telnet_connect: jsr print_errorcode jsr print_cr jmp telnet_main_entry -@not_runstop: - lda character_mode +@not_runstop: + lda character_set bne @no_conversion_required + txa + cmp #$0d + bne @not_cr + + ;if we get a CR in ascii mode, send CR/LF + ldy nb65_param_buffer+NB65_TCP_PAYLOAD_LENGTH + sta scratch_buffer,y + inc nb65_param_buffer+NB65_TCP_PAYLOAD_LENGTH + ldx #$0a + jmp @no_conversion_required +@not_cr: lda petscii_to_ascii_table,x tax @no_conversion_required: @@ -202,11 +253,104 @@ telnet_callback: dec buffer_length+1 : ldy #0 + sty iac_response_buffer_length @next_byte: lda (buffer_ptr),y tax - lda character_mode - bne @no_conversion_req + lda character_set + beq :+ + jmp @no_conversion_req +: + + lda telnet_state + cmp #telnet_state_got_command + beq @waiting_for_option + cmp #telnet_state_got_iac + beq @waiting_for_command +; we must be in 'normal' mode + txa + cmp #255 + beq :+ + jmp @not_iac +: + lda #telnet_state_got_iac + sta telnet_state + jmp @byte_processed +@waiting_for_command: + txa + sta telnet_command + cmp #$fb ;WILL + beq @option + cmp #$fc ;WONT + beq @option + cmp #$fd ; DO + beq @option + cmp #$fe ;DONT + beq @option +;we got a command we don't understand - just ignore it + lda #telnet_state_normal + sta telnet_state + jmp @byte_processed +@option: + lda #telnet_state_got_command + sta telnet_state + jmp @byte_processed + +@waiting_for_option: +;we have now got IAC, ,