From 675f2cc4b9733d5bbe4491c41e1fdc06273cea45 Mon Sep 17 00:00:00 2001 From: jonnosan Date: Thu, 30 Jul 2009 10:43:37 +0000 Subject: [PATCH] git-svn-id: http://svn.code.sf.net/p/netboot65/code@167 93682198-c243-4bdb-bd91-e943c89aac3b --- client/cfg/a2bin.cfg | 2 + client/cfg/c64_16kcart.cfg | 2 +- client/drivers/Makefile | 6 +- client/drivers/a2charconv.s | 19 ++ client/drivers/a2input.s | 166 ++++++++++++- client/drivers/a2print.s | 2 +- client/drivers/c64charconv.s | 55 ++++ client/drivers/c64inputs.s | 6 +- client/inc/a2keycodes.i | 1 + client/inc/c64keycodes.i | 1 + client/inc/commonprint.i | 15 +- client/inc/gopher.i | 12 +- client/inc/telnet.i | 359 ++------------------------- client/ip65/Makefile | 4 +- client/ip65/dhcp.s | 12 +- client/ip65/telnet.s | 356 ++++++++++++++++++++++++++ client/nb65/nb65_c64.s | 13 +- client/test/Makefile | 20 +- client/test/a2_gopher.s | 47 ++++ client/test/a2_telnet.s | 78 ++++++ client/test/test_disk_io.s | 2 - client/test/test_tcp.s | 8 +- doc/nb65_api_technical_reference.doc | Bin 138752 -> 138752 bytes 23 files changed, 803 insertions(+), 383 deletions(-) create mode 100644 client/drivers/a2charconv.s create mode 100644 client/drivers/c64charconv.s create mode 100644 client/ip65/telnet.s create mode 100644 client/test/a2_gopher.s create mode 100644 client/test/a2_telnet.s diff --git a/client/cfg/a2bin.cfg b/client/cfg/a2bin.cfg index 8382ad8..d2d2176 100644 --- a/client/cfg/a2bin.cfg +++ b/client/cfg/a2bin.cfg @@ -13,6 +13,8 @@ SEGMENTS { IP65_DEFAULTS: load = RAM, run=RAM, type = ro , define = yes; DATA: load = RAM, run=RAM, type = rw , define = yes; BSS: load=RAM, type = bss, define = yes; + TCP_VARS: load = RAM, type = bss; + APP_SCRATCH: load = RAM, type = bss; ZEROPAGE: load = ZP, type = zp; IP65ZP: load = IP65ZP, type = zp; } diff --git a/client/cfg/c64_16kcart.cfg b/client/cfg/c64_16kcart.cfg index b6b0bd1..f3922d6 100644 --- a/client/cfg/c64_16kcart.cfg +++ b/client/cfg/c64_16kcart.cfg @@ -1,7 +1,7 @@ # CA65 config for a 16KB cart MEMORY { - IP65ZP: start = $A3, size = $11, type = rw, define = yes; + IP65ZP: start = $A3, size = $13, type = rw, define = yes; HEADER: start = $8000, size = $18, file = %O; DEFAULTS: start = $8018, size = $1E, file = %O; ROM: start = $8036, size = $3FC8, define = yes, file = %O; diff --git a/client/drivers/Makefile b/client/drivers/Makefile index 8ba13d6..f0e7544 100644 --- a/client/drivers/Makefile +++ b/client/drivers/Makefile @@ -18,13 +18,13 @@ DRIVERS=\ all: $(DRIVERS) -apple2prog.lib: a2print.o uthernet.o a2timer.o a2kernal.o a2input.o +apple2prog.lib: a2print.o uthernet.o a2timer.o a2kernal.o a2input.o a2charconv.o ar65 a $@ $^ -c64prog.lib: c64print.o rr-net.o c64timer.o c64kernal.o c64inputs.o c64_disk_access.o +c64prog.lib: c64print.o rr-net.o c64timer.o c64kernal.o c64inputs.o c64_disk_access.o c64charconv.o ar65 a $@ $^ -c64nb65.lib: c64print.o rr-net.o c64timer_nb65.o c64kernal.o c64inputs.o c64_disk_access.o +c64nb65.lib: c64print.o rr-net.o c64timer_nb65.o c64kernal.o c64inputs.o c64_disk_access.o c64charconv.o ar65 a $@ $^ clean: diff --git a/client/drivers/a2charconv.s b/client/drivers/a2charconv.s new file mode 100644 index 0000000..1bb366e --- /dev/null +++ b/client/drivers/a2charconv.s @@ -0,0 +1,19 @@ +;ASCII/PETSCII conversion tables +;cribbed from http://www.ffd2.com/fridge/misc/petcom.c + + +.export ascii_to_native +.export native_to_ascii + +;given an A2 Screen Code char in A, return equivalent ASCII +native_to_ascii: +;just strip high bit + and #$7f + rts + +;given an ASCII char in A, return equivalent A2 Screen Code +ascii_to_native: +;set high bit + ora #$80 + rts + diff --git a/client/drivers/a2input.s b/client/drivers/a2input.s index 030f1b1..bd0694c 100644 --- a/client/drivers/a2input.s +++ b/client/drivers/a2input.s @@ -1,12 +1,40 @@ .export get_key .export check_for_abort_key +.export get_filtered_input +.export filter_text +.export filter_ip +.export filter_dns +.export filter_number +.export get_key_ip65 +.export get_key_if_available + +.import ip65_process +.import print_a +.import print_hex + +.importzp copy_src + +.include "../inc/common.i" + +allowed_ptr=copy_src ;reuse zero page .code ;use Apple 2 monitor ROM function to read from keyboard ;inputs: none ;outputs: A contains ASCII code of key pressed get_key: + lda #$a0 jmp $fd1b - + +;inputs: none +;outputs: A contains ASCII value of key just pressed (0 if no key pressed) +get_key_if_available: + bit $c000 ;Key down? + bmi get_key + lda #0 + rts + + + ;check whether the escape key is being pressed ;inputs: none @@ -20,3 +48,139 @@ rts : clc rts + +;process inbound ip packets while waiting for a keypress +get_key_ip65: + jsr ip65_process + bit $c000 ;Key down? + bpl get_key_ip65 + jmp get_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. +;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. +;====================================================================== + + +; Main entry +get_filtered_input: + sty MAXCHARS + stax temp_allowed + + ;Zero characters received. + lda #$00 + sta INPUT_Y + +;Wait for a character. +@input_get: + jsr get_key_ip65 + ;convert to standard ASCII by turning off high bit + and #$7f + sta LASTCHAR + cmp #$08 ;Delete + beq @delete + + cmp #$0d ;Return + beq @input_done + + ;End reached? + lda INPUT_Y + cmp MAXCHARS + beq @input_get + + ;Check the allowed list of characters. + ldax temp_allowed + stax allowed_ptr ;since we are reusing this zero page, it may not stil be the same value since last time! + ldy #$00 + 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) + + cmp LASTCHAR + beq @input_ok ;Match found + + ;Not end or match, keep checking + iny + jmp @check_allowed + +@input_ok: + lda LASTCHAR ;Get the char back + ldy INPUT_Y + sta GOTINPUT,y ;Add it to string + + inc INPUT_Y ;Next character + jsr print_a + ;Not yet. + jmp @input_get + +@input_done: + ldy INPUT_Y + beq @no_input + lda #$00 + sta GOTINPUT,y ;Zero-terminate + clc + ldax #GOTINPUT + rts +@no_input: + sec + rts +; Delete last character. +@delete: + ;First, check if we're at the beginning. If so, just exit. + lda INPUT_Y + bne @delete_ok + jmp @input_get + + ;At least one character entered. +@delete_ok: + ;Move pointer back. + dec INPUT_Y + + ;Store a zero over top of last character, just in case no other characters are entered. + ldy INPUT_Y + lda #$00 + sta GOTINPUT,y + + ;Print the backspace char + lda #$88 + jsr print_a + + ;Print the a space + lda #$a0 + jsr print_a + + ;Print the backspace char + lda #$88 + jsr print_a + + ;Wait for next char + jmp @input_get + + +;================================================= +;Some example filters +;================================================= + +filter_text: + .byte ",+!#$%&'()* " +filter_dns: +.byte "-ABCDEFGHIJKLMNOPQRSTUVWXYZ" +filter_ip: +.byte "." +filter_number: +.byte "1234567890",0 + +;================================================= +.bss +temp_allowed: .res 2 +MAXCHARS: .res 1 +LASTCHAR: .res 1 +INPUT_Y: .res 1 +GOTINPUT: .res 40 diff --git a/client/drivers/a2print.s b/client/drivers/a2print.s index 7d748da..d0769cb 100644 --- a/client/drivers/a2print.s +++ b/client/drivers/a2print.s @@ -11,7 +11,7 @@ ;outputs: none print_a: ora #$80 ;turn ASCII into Apple 2 screen codes - jmp $fdf0 + jmp $fded ;use Apple 2 monitor ROM function to move to new line diff --git a/client/drivers/c64charconv.s b/client/drivers/c64charconv.s new file mode 100644 index 0000000..0486f37 --- /dev/null +++ b/client/drivers/c64charconv.s @@ -0,0 +1,55 @@ +;ASCII/PETSCII conversion tables +;cribbed from http://www.ffd2.com/fridge/misc/petcom.c + + +.export ascii_to_native +.export native_to_ascii + +;given a PETSCII char in A, return equivalent ASCII +native_to_ascii: + tax + lda petscii_to_ascii_table,x + rts + +;given an ASCII char in A, return equivalent PETSCII +ascii_to_native: + tax + lda ascii_to_petscii_table,x + rts + +.rodata +ascii_to_petscii_table: +.byte $00,$01,$02,$03,$04,$05,$06,$07,$14,$09,$0d,$11,$93,$0a,$0e,$0f +.byte $10,$0b,$12,$13,$08,$15,$16,$17,$18,$19,$1a,$1b,$1c,$1d,$1e,$1f +.byte $20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2a,$2b,$2c,$2d,$2e,$2f +.byte $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$3d,$3e,$3f +.byte $40,$c1,$c2,$c3,$c4,$c5,$c6,$c7,$c8,$c9,$ca,$cb,$cc,$cd,$ce,$cf +.byte $d0,$d1,$d2,$d3,$d4,$d5,$d6,$d7,$d8,$d9,$da,$5b,$5c,$5d,$5e,$5f +.byte $c0,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4a,$4b,$4c,$4d,$4e,$4f +.byte $50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$5a,$db,$dc,$dd,$de,$df +.byte $80,$81,$82,$83,$84,$85,$86,$87,$88,$89,$8a,$8b,$8c,$8d,$8e,$8f +.byte $90,$91,$92,$0c,$94,$95,$96,$97,$98,$99,$9a,$9b,$9c,$9d,$9e,$9f +.byte $a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7,$a8,$a9,$aa,$ab,$ac,$ad,$ae,$af +.byte $b0,$b1,$b2,$b3,$b4,$b5,$b6,$b7,$b8,$b9,$ba,$bb,$bc,$bd,$be,$bf +.byte $60,$61,$62,$63,$64,$65,$66,$67,$68,$69,$6a,$6b,$6c,$6d,$6e,$6f +.byte $70,$71,$72,$73,$74,$75,$76,$77,$78,$79,$7a,$7b,$7c,$7d,$7e,$7f +.byte $e0,$e1,$e2,$e3,$e4,$e5,$e6,$e7,$e8,$e9,$ea,$eb,$ec,$ed,$ee,$ef +.byte $f0,$f1,$f2,$f3,$f4,$f5,$f6,$f7,$f8,$f9,$fa,$fb,$fc,$fd,$fe,$ff + +petscii_to_ascii_table: +.byte $00,$01,$02,$03,$04,$05,$06,$07,$14,$09,$0d,$11,$93,$0a,$0e,$0f +.byte $10,$0b,$12,$13,$08,$15,$16,$17,$18,$19,$1a,$1b,$1c,$1d,$1e,$1f +.byte $20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2a,$2b,$2c,$2d,$2e,$2f +.byte $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$3d,$3e,$3f +.byte $40,$61,$62,$63,$64,$65,$66,$67,$68,$69,$6a,$6b,$6c,$6d,$6e,$6f +.byte $70,$71,$72,$73,$74,$75,$76,$77,$78,$79,$7a,$5b,$5c,$5d,$5e,$5f +.byte $c0,$c1,$c2,$c3,$c4,$c5,$c6,$c7,$c8,$c9,$ca,$cb,$cc,$cd,$ce,$cf +.byte $d0,$d1,$d2,$d3,$d4,$d5,$d6,$d7,$d8,$d9,$da,$db,$dc,$dd,$de,$df +.byte $80,$81,$82,$83,$84,$85,$86,$87,$88,$89,$8a,$8b,$8c,$8d,$8e,$8f +.byte $90,$91,$92,$0c,$94,$95,$96,$97,$98,$99,$9a,$9b,$9c,$9d,$9e,$9f +.byte $20,$a1,$a2,$a3,$a4,$a5,$a6,$a7,$a8,$a9,$aa,$ab,$ac,$ad,$ae,$af +.byte $b0,$b1,$b2,$b3,$b4,$b5,$b6,$b7,$b8,$b9,$ba,$bb,$bc,$bd,$be,$bf +.byte $60,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4a,$4b,$4c,$4d,$4e,$4f +.byte $50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$5a,$7b,$7c,$7d,$7e,$7f +.byte $a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7,$a8,$a9,$aa,$ab,$ac,$ad,$ae,$af +.byte $b0,$b1,$b2,$b3,$b4,$b5,$b6,$b7,$b8,$b9,$ba,$bb,$bc,$bd,$be,$bf diff --git a/client/drivers/c64inputs.s b/client/drivers/c64inputs.s index 2c6421d..2148935 100644 --- a/client/drivers/c64inputs.s +++ b/client/drivers/c64inputs.s @@ -71,7 +71,7 @@ check_for_abort_key: ; Main entry get_filtered_input: sty MAXCHARS - stax allowed_ptr + stax temp_allowed ;Zero characters received. lda #$00 @@ -94,6 +94,9 @@ get_filtered_input: beq @input_get ;Check the allowed list of characters. + ldax temp_allowed + stax allowed_ptr ;since we are reusing this zero page, it may not stil be the same value since last time! + ldy #$00 lda allowed_ptr+1 ;was the input filter point nul? beq @input_ok @@ -170,6 +173,7 @@ filter_number: ;================================================= .bss +temp_allowed: .res 2 MAXCHARS: .res 1 LASTCHAR: .res 1 INPUT_Y: .res 1 diff --git a/client/inc/a2keycodes.i b/client/inc/a2keycodes.i index 1613854..8a60f95 100644 --- a/client/inc/a2keycodes.i +++ b/client/inc/a2keycodes.i @@ -5,3 +5,4 @@ KEYCODE_LEFT=$88 KEYCODE_RIGHT=$95 KEYCODE_ABORT=$9B .define KEYNAME_ABORT "ESC" +.export KEYCODE_ABORT \ No newline at end of file diff --git a/client/inc/c64keycodes.i b/client/inc/c64keycodes.i index 9c706e2..b06abd8 100644 --- a/client/inc/c64keycodes.i +++ b/client/inc/c64keycodes.i @@ -13,3 +13,4 @@ KEYCODE_F7=$88 KEYCODE_F8=$8c KEYCODE_ABORT=$03 ;RUN/STOP .define KEYNAME_ABORT "RUN/STOP" +.export KEYCODE_ABORT \ No newline at end of file diff --git a/client/inc/commonprint.i b/client/inc/commonprint.i index 4b8ecd6..e5a003f 100644 --- a/client/inc/commonprint.i +++ b/client/inc/commonprint.i @@ -19,7 +19,9 @@ .export gateway_msg .export dns_server_msg .export tftp_server_msg - + .import ip65_error + .export print_errorcode + .import arp_cache .importzp ac_size @@ -321,6 +323,13 @@ print_hex: pla rts +print_errorcode: + ldax #error_code + jsr print + lda ip65_error + jsr print_hex + jmp print_cr + .rodata hexdigits: .byte "0123456789ABCDEF" @@ -366,3 +375,7 @@ ok_msg: dns_lookup_failed_msg: .byte "DNS LOOKUP FAILED", 0 + +error_code: + .asciiz "ERROR CODE: " + diff --git a/client/inc/gopher.i b/client/inc/gopher.i index 88e3d61..e20079f 100644 --- a/client/inc/gopher.i +++ b/client/inc/gopher.i @@ -18,7 +18,7 @@ .importzp copy_src .importzp copy_dest .import copymem - + .import ascii_to_native .import tcp_connect .import tcp_send .import tcp_send_data_len @@ -126,14 +126,14 @@ display_resource_in_buffer: ;if this is a text file, just convert ascii->petscii and print to screen @show_one_char: jsr get_next_byte - tax ;this both sets up X as index into ascii_to_petscii_table, and sets Z flag + tax ;this sets Z flag bne :+ lda #1 sta this_is_last_page jmp @get_keypress : - lda ascii_to_petscii_table,x + jsr ascii_to_native jsr print_a lda $d6 cmp #DISPLAY_LINES @@ -210,8 +210,7 @@ display_resource_in_buffer: jsr get_next_byte cmp #$09 beq @skip_to_end_of_line - tax - lda ascii_to_petscii_table,x + jsr ascii_to_native jsr print_a jmp @next_byte @@ -525,11 +524,12 @@ load_resource_into_buffer: stx dl_loop_counter stx dl_loop_counter+1 lda resource_selector_length + beq @empty_selector stax tcp_send_data_len ldax #resource_selector jsr tcp_send - +@empty_selector: ;send the tab and query string (if supplied) lda displayed_resource_type cmp #'7' ;is it a 'search' resource? diff --git a/client/inc/telnet.i b/client/inc/telnet.i index 0df6890..b170f6e 100644 --- a/client/inc/telnet.i +++ b/client/inc/telnet.i @@ -5,11 +5,16 @@ ; .include "../inc/common.i" ; .include "../inc/commonprint.i" ; .include "../inc/net.i" -; .include "../inc/char_conv.i" -; .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 buffer_ptr + +.import telnet_connect +.import telnet_local_echo +.import telnet_line_mode +.import telnet_use_native_charset +.import telnet_port +.import telnet_ip + + .code telnet_main_entry: ;prompt for a hostname, then resolve to an IP address @@ -75,26 +80,24 @@ telnet_main_entry: jmp @char_mode_input @ascii_mode: lda #0 - sta character_set - sta line_mode + sta telnet_use_native_charset + sta telnet_line_mode lda #1 - sta local_echo - lda #telnet_state_normal - sta telnet_state + sta telnet_local_echo jmp @after_mode_set @petscii_mode: lda #1 - sta character_set + sta telnet_use_native_charset lda #0 - sta local_echo - sta line_mode + sta telnet_local_echo + sta telnet_line_mode jmp @after_mode_set @line_mode: lda #0 - sta character_set + sta telnet_use_native_charset lda #1 - sta local_echo - sta line_mode + sta telnet_local_echo + sta telnet_line_mode @after_mode_set: @@ -103,12 +106,12 @@ telnet_main_entry: ldax #connecting_in jsr print - lda character_set + lda telnet_use_native_charset beq @a_mode ldax #petscii jmp @c_mode @a_mode: - lda line_mode + lda telnet_line_mode bne @l_mode ldax #ascii jmp @c_mode @@ -118,334 +121,16 @@ telnet_main_entry: jsr print ldax #mode jsr print - -telnet_connect: - ldax #telnet_callback - stax nb65_param_buffer+NB65_TCP_CALLBACK - ldx #3 -@copy_dest_ip: - lda telnet_ip,x - sta nb65_param_buffer+NB65_TCP_REMOTE_IP,x - dex - bpl @copy_dest_ip - ldax telnet_port - stax nb65_param_buffer+NB65_TCP_PORT - ldax #nb65_param_buffer - nb65call #NB65_TCP_CONNECT - - bcc @connect_ok - jsr print_cr - print_failed - jsr print_errorcode - jmp telnet_main_entry -@connect_ok: - print_ok - jsr print_cr - lda #0 - sta connection_closed -@main_polling_loop: - jsr NB65_PERIODIC_PROCESSING_VECTOR - lda connection_closed - beq @not_disconnected - ldax #disconnected - 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 - jsr print_cr - 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 - lda #0 - sta nb65_param_buffer+NB65_TCP_PAYLOAD_LENGTH - 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 - bne @not_runstop - lda #0 - sta $cb ;overwrite "current key pressed" else it's seen by the tcp stack and the close aborts - - ldax #closing_connection - jsr print - nb65call #NB65_TCP_CLOSE_CONNECTION - bcs @error_on_disconnect - ldax #disconnected - jsr print - jmp telnet_main_entry -@error_on_disconnect: - jsr print_errorcode - jsr print_cr - jmp telnet_main_entry -@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: - txa - ldy nb65_param_buffer+NB65_TCP_PAYLOAD_LENGTH - sta scratch_buffer,y - inc nb65_param_buffer+NB65_TCP_PAYLOAD_LENGTH - jmp @get_next_char -@no_more_input: - ldax #scratch_buffer - stax nb65_param_buffer+NB65_TCP_PAYLOAD_POINTER - ldax #nb65_param_buffer - nb65call #NB65_SEND_TCP_PACKET - bcs @error_on_send - jmp @main_polling_loop - -@error_on_send: - ldax #transmission_error - jsr print - jsr print_errorcode - jmp telnet_main_entry - -;tcp callback - will be executed whenever data arrives on the TCP connection -telnet_callback: - ldax #nb65_param_buffer - nb65call #NB65_GET_INPUT_PACKET_INFO - - lda nb65_param_buffer+NB65_PAYLOAD_LENGTH+1 - cmp #$ff - bne @not_eof - lda #1 - sta connection_closed - rts -@not_eof: - - ldax nb65_param_buffer+NB65_PAYLOAD_POINTER - stax buffer_ptr - lda nb65_param_buffer+NB65_PAYLOAD_LENGTH - sta buffer_length - lda nb65_param_buffer+NB65_PAYLOAD_LENGTH+1 - sta buffer_length+1 - - ;since we don't check the buffer length till the end of the loop, set 'buffer length' to be 1 less than the actual number of bytes - dec buffer_length - bpl :+ - dec buffer_length+1 -: - ldy #0 - sty iac_response_buffer_length -@next_byte: - lda (buffer_ptr),y - tax - lda character_set - beq :+ - jmp @no_conversion_req -: - - lda line_mode - beq :+ - jmp@convert_to_petscii -: -;if we get here, we are in ASCII 'char at a time' mode, so look for (and process) Telnet style IAC bytes - 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, ,