diff --git a/apps/Makefile b/apps/Makefile new file mode 100644 index 0000000..a8869c6 --- /dev/null +++ b/apps/Makefile @@ -0,0 +1,109 @@ +# Build for Cirrus Logic CS8900A based devices: +# make eth=cl + +# Build for Standard Microsystems LAN91C96 based devices: +# make eth=sm + +# Build for WIZnet W5100 based devices: +# make eth=wn + +ifeq ($(eth),cl) + C64DRIVERLIB = ../drivers/c64rrnet.lib + A2DRIVERLIB = ../drivers/a2uther.lib +else ifeq ($(eth),sm) + C64DRIVERLIB = ../drivers/c64eth64.lib + A2DRIVERLIB = ../drivers/a2lancegs.lib +else ifeq ($(eth),wn) + C64DRIVERLIB = ../drivers/c64wiz811.lib + A2DRIVERLIB = ../drivers/a2uther2.lib +else + C64DRIVERLIB = ../drivers/c64combo.lib + A2DRIVERLIB = ../drivers/a2combo.lib +endif +ATRDRIVERLIB = ../drivers/atrdragon.lib +VICDRIVERLIB = ../drivers/vic20rrnet.lib + +UDP =\ + +TCP =\ + telnet65 + +all: $(UDP) $(TCP) +.PHONY: $(UDP) $(TCP) + +$(addsuffix .prg,$(UDP)): IP65LIB = ../ip65/ip65.lib +$(addsuffix .prg,$(TCP)): IP65LIB = ../ip65/ip65_tcp.lib + +$(addsuffix .bin,$(UDP)): IP65LIB = ../ip65/ip65.lib +$(addsuffix .bin,$(TCP)): IP65LIB = ../ip65/ip65_tcp.lib + +$(addsuffix .com,$(UDP)): IP65LIB = ../ip65/ip65.lib +$(addsuffix .com,$(TCP)): IP65LIB = ../ip65/ip65_tcp.lib + +$(addsuffix .vicprg,$(UDP)): IP65LIB = ../ip65/ip65.lib +$(addsuffix .vicprg,$(TCP)): IP65LIB = ../ip65/ip65_tcp.lib + +$(foreach pgm,$(UDP) $(TCP),$(eval $(pgm): $(pgm).prg $(pgm).bin $(pgm).com $(pgm).vicprg)) + +INCFILES =\ + ../inc/common.i \ + ../inc/commonprint.i \ + ../inc/net.i + +prg: $(addsuffix .prg,$(UDP) $(TCP)) + +bin: $(addsuffix .bin,$(UDP) $(TCP)) + +com: $(addsuffix .com,$(UDP) $(TCP)) + +vicprg: $(addsuffix .vicprg,$(UDP) $(TCP)) + +d64: ip65.d64 + +dsk: ip65.dsk + +atr: ip65.atr + +ip65: + make -C ../ip65 + +drivers: + make -C ../drivers + +%.o: %.s + ca65 $< + +%.prg: %.o ip65 drivers $(INCFILES) + ld65 -o $*.prg -C c64.cfg -m $*.c64.map -vm $< $(IP65LIB) $(C64DRIVERLIB) c64.lib + +%.bin: %.o ip65 drivers $(INCFILES) + ld65 -o $*.bin -C apple2.cfg -m $*.a2.map -vm $< $(IP65LIB) $(A2DRIVERLIB) apple2.lib + +%.com: %.o ip65 drivers $(INCFILES) + ld65 -o $*.com -C atari.cfg -m $*.atr.map -vm $< $(IP65LIB) $(ATRDRIVERLIB) atari.lib + +%.vicprg: %.o ip65 drivers $(INCFILES) + ld65 -o $*.vicprg -C vic20-32k.cfg -m $*.vic.map -vm $< $(IP65LIB) $(VICDRIVERLIB) vic20.lib + +ip65.d64: prg + $(C1541) -format ip65,00 d64 $@ + $(C1541) -attach $@ -write telnet65.prg telnet65,p + +ip65.dsk: bin + cp prodos.dsk $@ + java -jar $(AC) -cc65 $@ telnet65 bin < telnet65.bin + +ip65.atr: com + mkdir atr + cp dos.sys atr/dos.sys + cp dup.sys atr/dup.sys + cp telnet65.com atr/telnet65.com + $(DIR2ATR) -b Dos25 1040 $@ atr + rm -r atr + +clean: + make -C ../ip65 clean + make -C ../drivers clean + -rm -f ../supplement/*.o + -rm -f *.o *.prg *.bin *.com *.vicprg *.map + -rm -f ip65.d64 ip65.dsk ip65.atr diff --git a/ip65/telnet.s b/apps/telnet65.s similarity index 55% rename from ip65/telnet.s rename to apps/telnet65.s index f46616d..c551263 100644 --- a/ip65/telnet.s +++ b/apps/telnet65.s @@ -1,188 +1,298 @@ ; minimal telnet implementation (dumb terminal emulation only) -; to use: -; set the following variables - telnet_use_native_charset,telnet_port,telnet_ip -; then call telnet_connect -; you must also define (and export) these function -; telnet_menu - called whenever the F1 key is pressed. -; telnet_on_connection - called after succesful connection -.include "zeropage.inc" .include "../inc/common.i" +.include "../inc/commonprint.i" +.include "../inc/net.i" -.import tcp_connect +.export start + +.import get_filtered_input +.import get_key +.import get_key_if_available +.import exit_to_basic +.import filter_dns +.import filter_number +.import dns_hostname_is_dotted_quad +.import dns_ip +.import dns_resolve +.import dns_set_hostname +.import ip65_process +.import native_to_ascii +.import parse_integer +.import print_cr .import tcp_callback +.import tcp_close +.import tcp_connect .import tcp_connect_ip -.import tcp_listen -.importzp KEYCODE_F1 .import tcp_inbound_data_ptr .import tcp_inbound_data_length .import tcp_send .import tcp_send_data_len -.import tcp_close -.import print_a -.import print_cr -.import vt100_init_terminal -.import vt100_process_inbound_char -.import vt100_transform_outbound_char .import tcp_send_keep_alive .import timer_read +.import vt100_init_terminal +.import vt100_exit_terminal +.import vt100_process_inbound_char +.import vt100_process_outbound_char +.importzp vt100_screen_cols +.importzp vt100_screen_rows -.import ip65_process -.import get_key_if_available -.import get_filtered_input -.import check_for_abort_key -.import ok_msg -.import failed_msg -.import print -.import print_errorcode +.export telnet_close +.export telnet_send_char +.export telnet_send_string -.export telnet_connect -.export telnet_use_native_charset -.export telnet_port -.export telnet_ip - -.import telnet_menu -.import telnet_on_connection - -buffer_ptr = ptr4 +buffer_ptr = sreg -.code +; keep LD65 happy +.segment "INIT" +.segment "ONCE" -; connect to a remote telnet server -; inputs: -; telnet_use_native_charset: set to 0 if remote server uses standard ASCII, 1 if remote server uses the 'native' charset (i.e. PETSCII) -; telnet_port: port number to connect to -; telnet_ip: ip address of remote server -telnet_connect: - lda telnet_use_native_charset - bne :+ + +.segment "STARTUP" + +start: jsr vt100_init_terminal -: ldax #telnet_callback + +; initialize stack + ldax #initializing + jsr print_ascii_as_native + jsr ip65_init + bcc :+ + ldax #device_not_found + jsr print_ascii_as_native + jmp error_exit +: ldax #eth_driver_name + jsr print_ascii_as_native + ldax #io_base_prefix + jsr print_ascii_as_native + lda eth_driver_io_base+1 + jsr print_hex + lda eth_driver_io_base + jsr print_hex + ldax #io_base_postfix + jsr print_ascii_as_native + +; get IP addr + ldax #obtaining + jsr print_ascii_as_native + jsr dhcp_init + bcc :+ + jsr print_error + jmp error_exit +: ldax #cfg_ip + jsr print_dotted_quad + jsr print_cr + +telnet_main_entry: +; enter host name + ldax #remote_host + jsr print_ascii_as_native + ldy #40 ; max chars + ldax #filter_dns + jsr get_filtered_input + bcc :+ + jmp exit + +; set host name +: stax buffer_ptr + ldy #$ff +: iny + lda (buffer_ptr),y + jsr native_to_ascii + cmp #'a' + bcs :+ + cmp #'A' + bcc :+ + clc + adc #'a'-'A' +: sta (buffer_ptr),y + tax ; set Z flag + bne :-- + ldax buffer_ptr + jsr dns_set_hostname + bcc :+ + jsr print_error + jmp telnet_main_entry + +; resolve host name +: lda dns_hostname_is_dotted_quad + bne :++ + ldax #resolving + jsr print_ascii_as_native + jsr dns_resolve + bcc :+ + jsr print_error + jmp telnet_main_entry +: ldax #dns_ip + jsr print_dotted_quad + +; enter port +: ldax #remote_port + jsr print_ascii_as_native + ldy #5 ; max chars + ldax #filter_number + jsr get_filtered_input + bcs :+ ; empty -> default + jsr parse_integer + bcc :++ + jmp telnet_main_entry +: ldax #23 ; default +: stax telnet_port + +; connect + ldax #connecting + jsr print_ascii_as_native + ldax #dns_ip + jsr print_dotted_quad + ldax #blank + jsr print_ascii_as_native + ldax #telnet_callback stax tcp_callback ldx #3 -@copy_dest_ip: - lda telnet_ip,x +: lda dns_ip,x sta tcp_connect_ip,x dex - bpl @copy_dest_ip - + bpl :- ldax telnet_port jsr tcp_connect + bcc :+ + jsr print_error + jmp telnet_main_entry - bcc @connect_ok - jsr print_cr - ldax #failed_msg - jsr print - jsr print_cr - jsr print_errorcode - rts -@connect_ok: - jsr telnet_on_connection - - ldax #ok_msg - jsr print - jsr print_cr +; connected +: ldax #ok + jsr print_ascii_as_native lda #0 + sta connection_close_requested sta connection_closed sta iac_response_buffer_length + ldax #cursor_on + jsr print_vt100 @main_polling_loop: - jsr check_for_abort_key - bcc @no_abort - jsr tcp_close - jmp @disconnected - -@no_abort: jsr timer_read txa - adc #$20 ; 32 x 1/4 = ~ 8seconds + adc #$20 ; 32 x 1/4 = ~ 8 seconds sta telnet_timeout @wait_for_keypress: jsr timer_read cpx telnet_timeout - bne @no_timeout + bne :+ jsr tcp_send_keep_alive jmp @main_polling_loop -@no_timeout: - jsr ip65_process - lda connection_closed - beq @not_disconnected -@disconnected: +: jsr ip65_process + lda connection_close_requested + beq :+ + jsr tcp_close + jmp :++ +: lda connection_closed + beq :++ +: ldax #cursor_off + jsr print_vt100 ldax #disconnected - jsr print - rts -@not_disconnected: - lda iac_response_buffer_length - beq @no_iac_response + jsr print_ascii_as_native + jmp telnet_main_entry +: lda iac_response_buffer_length + beq :+ ldx #0 stax tcp_send_data_len stx iac_response_buffer_length ldax #iac_response_buffer jsr tcp_send -@no_iac_response: - jsr get_key_if_available +: jsr get_key_if_available beq @wait_for_keypress - - cmp #KEYCODE_F1 - bne @not_telnet_menu - jsr telnet_menu - jmp @main_polling_loop -@not_telnet_menu: ldx #0 stx tcp_send_data_len stx tcp_send_data_len+1 + tay + jsr vt100_process_outbound_char + jmp @main_polling_loop - ldx telnet_use_native_charset - bne @no_conversion_required - - jsr vt100_transform_outbound_char - - sta temp_a - tya - bne :+ - jmp @main_polling_loop ; Y = 0 means nothing to send -: cmp #2 - beq :+ - lda temp_a - jmp @no_conversion_required -: lda temp_a +print_vt100: stax buffer_ptr + lda #0 + sta buffer_offset +: ldy buffer_offset + lda (buffer_ptr),y + bne :+ + rts +: tay + jsr vt100_process_inbound_char + inc buffer_offset + jmp :-- + +print_error: + lda ip65_error + cmp #KPR_ERROR_ABORTED_BY_USER + bne :+ + ldax #abort + jmp print_ascii_as_native +: cmp #KPR_ERROR_TIMEOUT_ON_RECEIVE + bne :+ + ldax #timeout + jmp print_ascii_as_native +: ldax #error_prefix + jsr print_ascii_as_native + lda ip65_error + jsr print_hex + jmp print_cr + +error_exit: + ldax #press_a_key_to_continue + jsr print_ascii_as_native + jsr get_key +exit: + jsr vt100_exit_terminal + jmp exit_to_basic + + +; vt100 callback - will be executed when the user requests to close the connection +telnet_close: + lda #1 + sta connection_close_requested + rts + + +; vt100 callback - will be executed when sending a char string +telnet_send_string: + stx buffer_ptr + sty buffer_ptr+1 ldy #0 : lda (buffer_ptr),y - beq @send_char + beq send_char sta scratch_buffer,y inc tcp_send_data_len iny bne :- - jmp @send_char + jmp send_char -@no_conversion_required: + +; vt100 callback - will be executed when sending a single char +telnet_send_char: ldy tcp_send_data_len sta scratch_buffer,y inc tcp_send_data_len -@send_char: +send_char: ldax #scratch_buffer jsr tcp_send - bcs @error_on_send - jmp @main_polling_loop + bcs :+ + rts +: ldax #send_error + jsr print_ascii_as_native + jmp print_error -@error_on_send: - ldax #transmission_error - jsr print - jmp print_errorcode ; tcp callback - will be executed whenever data arrives on the TCP connection telnet_callback: lda tcp_inbound_data_length+1 cmp #$ff - bne @not_eof + bne :+ lda #1 sta connection_closed rts -@not_eof: - ldax tcp_inbound_data_ptr +: ldax tcp_inbound_data_ptr stax buffer_ptr lda tcp_inbound_data_length sta buffer_length @@ -193,11 +303,9 @@ telnet_callback: ldy #0 lda (buffer_ptr),y tax - lda telnet_use_native_charset - beq :+ - jmp @no_conversion_req - ; 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 + ; 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 bne :+ jmp @waiting_for_option @@ -216,7 +324,6 @@ telnet_callback: @waiting_for_suboption_end: txa - ldx iac_suboption_buffer_length sta iac_suboption_buffer,x inc iac_suboption_buffer_length @@ -259,6 +366,7 @@ telnet_callback: lda #telnet_state_normal sta telnet_state jmp @byte_processed + @suboption: lda #telnet_state_got_suboption sta telnet_state @@ -276,17 +384,14 @@ telnet_callback: txa sta telnet_option lda telnet_command - cmp #$fb beq @iac_will cmp #$fc beq @iac_wont cmp #$fe beq @iac_dont - ; if we get here, then it's a "do" lda telnet_option - cmp #$18 ; terminal type beq @do_terminaltype cmp #$1f @@ -298,11 +403,10 @@ telnet_callback: @add_iac_response: ldx iac_response_buffer_length sta iac_response_buffer+1,x - lda #255 + lda #$ff sta iac_response_buffer,x lda telnet_option sta iac_response_buffer+2,x - inc iac_response_buffer_length inc iac_response_buffer_length inc iac_response_buffer_length @@ -312,19 +416,16 @@ telnet_callback: jmp @byte_processed @iac_will: lda telnet_option - cmp #$01 ; ECHO + cmp #$01 ; ECHO beq @will_echo cmp #$03 ; DO SUPPRESS GA beq @will_suppress_ga - @iac_wont: lda #$fe ; DONT jmp @add_iac_response - @will_echo: lda #$fd ; DO jmp @add_iac_response - @will_suppress_ga: lda #$fd ; DO jmp @add_iac_response @@ -339,46 +440,56 @@ telnet_callback: txa cmp #naws_response_length bne :- - jmp @after_set_iac_response - @do_terminaltype: lda #$fb ; WILL jmp @add_iac_response @not_iac: -@convert_to_native: txa + tay jsr vt100_process_inbound_char - jmp @byte_processed -@no_conversion_req: - txa - jsr print_a + @byte_processed: inc buffer_ptr bne :+ inc buffer_ptr+1 : lda buffer_length+1 - beq @last_page + beq :++ lda buffer_length - bne @not_end_of_page + bne :+ dec buffer_length+1 -@not_end_of_page: - dec buffer_length +: dec buffer_length jmp @next_byte -@last_page: - dec buffer_length - beq @finished - +: dec buffer_length + beq :+ jmp @next_byte +: rts -@finished: - rts -; constants -closing_connection: .byte "CLOSING CONNECTION",13,0 -disconnected: .byte 13,"CONNECTION CLOSED",13,0 -transmission_error: .byte "ERROR WHILE SENDING ",0 +.rodata + +blank: .byte " ",0 +initializing: .byte 10," Telnet65 v1.0 based on:",10,10 + .byte "- IP65 (oliverschmidt.github.io/ip65)",10 + .byte "- CaTer (www.opppf.de/Cater)",10,10 + .byte "Initializing ",0 +obtaining: .byte "Obtaining IP address ",0 +resolving: .byte 10,"Resolving to address ",0 +connecting: .byte 10,"Connecting to ",0 +io_base_prefix: .byte " ($",0 +io_base_postfix: .byte ")",10,0 +ok: .byte "Ok",10,10,0 +device_not_found: .byte "- Device not found",10,0 +abort: .byte "- User abort",10,0 +timeout: .byte "- Timeout",10,0 +error_prefix: .byte "- Error $",0 +remote_host: .byte 10,"Hostname (leave blank to quit)",10,"? ",0 +remote_port: .byte 10,10,"Port Num (leave blank for default)",10,"? ",0 +disconnected: .byte 10,"Disconnected",10,0 +send_error: .byte "Sending ",0 +cursor_on: .byte 27,"[?25h",0 +cursor_off: .byte 27,"[?25l",0 ; initial_telnet_options: ; .byte $ff,$fb,$1F ; IAC WILL NAWS @@ -387,36 +498,35 @@ transmission_error: .byte "ERROR WHILE SENDING ",0 terminal_type_response: .byte $ff ; IAC - .byte $fa; SB - .byte $18 ; TERMINAL TYPE - .byte $0 ; IS + .byte $fa ; SB + .byte $18 ; TERMINAL TYPE + .byte $0 ; IS .byte "vt100" ; what we pretend to be .byte $ff ; IAC .byte $f0 ; SE terminal_type_response_length = *-terminal_type_response naws_response: - .byte $ff,$fb,$1F ; IAC WILL NAWS + .byte $ff,$fb,$1f ; IAC WILL NAWS .byte $ff ; IAC .byte $fa ; SB - .byte $1F ; NAWS + .byte $1f ; NAWS .byte $00 ; width (high byte) - .byte 40 ; width (low byte) + .byte vt100_screen_cols ; width (low byte) .byte $00 ; height (high byte) - .byte 25 ; height (low byte) + .byte vt100_screen_rows ; height (low byte) .byte $ff ; IAC .byte $f0 ; SE naws_response_length = *-naws_response -.segment "APP_SCRATCH" +.bss ; variables -telnet_ip: .res 4 ; ip address of remote server telnet_port: .res 2 ; port number to connect to telnet_timeout: .res 1 +connection_close_requested: .res 1 connection_closed: .res 1 -telnet_use_native_charset: .res 1 ; 0 means all data is translated to/from NVT ASCII buffer_offset: .res 1 telnet_command: .res 1 telnet_option: .res 1 @@ -429,12 +539,11 @@ telnet_state_got_suboption = 3 buffer_length: .res 2 telnet_state: .res 1 -temp_a: .res 1 iac_response_buffer: .res 64 iac_response_buffer_length: .res 1 scratch_buffer : .res 40 iac_suboption_buffer: .res 64 -iac_suboption_buffer_length: .res 1 +iac_suboption_buffer_length: .res 1 diff --git a/drivers/Makefile b/drivers/Makefile index f8d1853..b8425a9 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -32,6 +32,7 @@ C64OBJS=\ c64kernal.o \ c64input.o \ c64filteredinput.o \ + c64vt100.o \ cbmcharconv.o A2OBJS=\ @@ -40,6 +41,7 @@ A2OBJS=\ a2kernal.o \ a2input.o \ a2filteredinput.o \ + a2vt100.o \ a2charconv.o ATROBJS=\ @@ -48,6 +50,7 @@ ATROBJS=\ atrkernal.o \ atrinput.o \ atrfilteredinput.o \ + atrvt100.o \ atrcharconv.o VIC20OBJS=\ @@ -56,6 +59,7 @@ VIC20OBJS=\ vic20kernal.o \ vic20input.o \ vic20filteredinput.o \ + vic20vt100.o \ cbmcharconv.o c64rrnet.lib: rr-net.o cs8900a.o cs8900adriver.o ethernet.o $(C64OBJS) diff --git a/drivers/a2vt100.s b/drivers/a2vt100.s new file mode 100644 index 0000000..332d284 --- /dev/null +++ b/drivers/a2vt100.s @@ -0,0 +1,1529 @@ +.feature labels_without_colons +.feature leading_dot_in_identifiers +.feature loose_char_term +.define .asc .byt + +.export vt100_init_terminal = InitTerminal +.export vt100_exit_terminal = ExitTerminal +.export vt100_process_inbound_char = ProcIn +.export vt100_process_outbound_char = ProcOut +.exportzp vt100_screen_cols = 80 +.exportzp vt100_screen_rows = 24 + +.import beep +.import telnet_close +.import telnet_send_char +.import telnet_send_string + +putRS = telnet_send_char +SendStr = telnet_send_string + +; ************************************* +; * * +; * C a T e r * +; * * +; * Copyright by * +; * Lars Stollenwerk * +; * * +; * 2001 - 2003 * +; * * +; * This file is part of CaTer. * +; * * +; * CaTer is provided under the terms * +; * of GNU General Public License. * +; * * +; * For more information see the * +; * README file. * +; * * +; ************************************* + +; ************************************* +; * +; * Constant declaration +; * +; ************************************* + +.include "apple2.inc" + +ControlFlags = $1000 + +; ************************************* +; * +; * Zeropage +; * +; ************************************* + +.include "zeropage.inc" + +; --- Vector --- +; four vectors in zeropage for +; temporary use. +zVector = ptr1 +xVector = ptr2 + +; --- vector for PrnScr --- +vVector = ptr3 + +; ************************************* +; * +; * Variables +; * +; ************************************* + +.bss + +; --- esc mode --- +; $00 = normal +; $0f = esc mode +; $ff = esc [ mode +; $f0 = ignore one char +EMode .res 1 + +; --- esc buffer --- +EBuf .res $100 + +; --- esc buffer length --- +; points on first free position +EBufL .res 1 + +; --- esc parameter --- +; numeric parameter in esc sequence +EPar .res 1 + +; --- scroll region --- +SRS .res 1 ; first line number +SRE .res 1 ; last line number + +; --- ANSI font attributes --- +; contains three bits +; bit 0 = reverse +; bit 1 = bold +; bit 2 = underline +Font: .res 1 + +; --- crsr save area --- +; here is crsr info saved with ESC 7 +; and restored from with ESC 8 +SaveF .res 1 ; font +SaveR .res 1 ; reverse mode +SaveRow .res 1 ; row +SaveCol .res 1 ; column + +; --- Linebreak pending --- +; 0 = not pending, ff = pending +lbPending .res 1 + +; --- crsr invisible --- +; 0 = visible, !0 = invisible +civis .res 1 + +; --- char under crsr --- +sCrsrChar .res 1 + +; --- buffer for addDecDig --- +mul10buf .res 1 + +; ************************************* +; * +; * Code +; * +; ************************************* + +.code + +; ------------------------------------- +; init terminal +; +; ------------------------------------- + +InitTerminal + jsr InitVar ; memory variables + jsr InitChar; init font + jsr InitScr ; init screen + rts + +; ------------------------------------- +; exit terminal +; +; ------------------------------------- + +ExitTerminal + jsr ExitChar; exit font + jsr ExitScr ; exit screen + rts + +; ************************************* +; * +; * imcoming data +; * +; ************************************* + +; ------------------------------------- +; process incoming data +; +; char in Y +; ------------------------------------- + +ProcIn lda EMode ; handle esc mode + bne PIEsc + cpy #$20 ; control? + bcc Special + tya + jsr CPrnChr ; print to screen + rts + +; to far for branch +PIEsc jmp Esc + +; ------------------------------------- +; special incoming char +; +; ------------------------------------- + +Special tya ; restore char +; --- CR --- + cmp #$0d ; CR? + bne D1 +CR jsr clPending + ldx CV ; get row + ldy #$00 ; set col=0 + jsr CPlot ; set crsr + rts +; --- BS --- +D1 cmp #$08 ; BS? + bne D2 +BS jsr clPending + ldy CH ; get col + beq D1rts ; stop @ left margin + dey ; dec column + ldx CV ; get row + jsr CPlot ; set crsr +D1rts rts +; --- ESC --- +D2 cmp #$1b ; esc? + bne D3 + lda #$0f ; set esc mode + sta EMode + rts +; --- BEL --- +D3 cmp #$07 ; BEL? + bne D4 + jsr beep + rts +; --- LF --- +D4 cmp #$0a ; LF? + bne D5 +LF jsr clPending + ldx CV ; crsr line + cpx SRE ; end scroll region? + bne D4a ; no -> branch + jsr CUScrl ; yes -> scroll up + rts +D4a cpx #$17 ; end of screen? + bne D4b ; no -> branch + rts ; yes -> do nothing +D4b inx ; next line + ldy CH ; get col + jsr CPlot ; set crsr + rts +; --- TAB --- +D5 cmp #$09 ; TAB? + bne D6 + ; don't clear pending + ; don't set pending + lda CH ; crsr col + and #$f8 ; (col DIV 8) * 8 + clc ; col + 8 + adc #$08 + cmp #$50 ; col=80? + bne D5a ; no -> skip + lda #$4f ; yes -> col=79 +D5a tay ; col to y + ldx CV ; line to x + jsr CPlot ; set crsr + rts + +D6 rts + +; ------------------------------------- +; esc mode +; +; char in Y +; EMode != $00 in A +; ------------------------------------- + +Esc tax ; save EMode + and #$0f ; EMode = $0f? + bne E1 + +; --- throw mode --- EMode = $f0 +; throw away char + lda #$00 ; reset EMode + sta EMode + rts + +E1 txa ; restore EMode + and #$f0 ; EMode = $ff? + beq SEsc ; no -> short Emode + jmp LEsc ; yes -> long Emode + +; ------------------------------------- +; short esc mode +; +; EMode = $0f +; process first char +; ------------------------------------- + +SEsc tya ; restore char + ; --- [ --- + cmp #$5b ; [ ? + bne E2 + lda #$ff ; set esc [ mode + sta EMode + rts + ; --- ( --- +E2 cmp #$28 ; ( ? + bne E3 + jmp sThrow + ; --- ) --- +E3 cmp #$29 ; ) ? + bne E4 + jmp sThrow + ; --- # --- +E4 cmp #$23 ; # ? + bne E5 + jmp sThrow + ; --- D --- index +E5 cmp #$44 ; D ? + bne E6 + jsr LF ; same as LF + jmp Eend + ; --- M --- reverse index +E6 cmp #$4d ; M ? + bne E7 + jsr clPending + ldx CV ; get crsr row + cpx SRS ; top os scroll reg? + bne E6a + jsr CDScrl ; yes -> scroll down + jmp Eend +E6a cpx #$00 ; top of screen? + bne E6b + jmp Eend ; yes -> do nothing +E6b dex ; one line up + ldy CH ; get crsr col + jsr CPlot ; set crsr + jmp Eend + ; --- E --- next line +E7 cmp #$45 ; E ? + bne E8 + jsr CR + jsr LF + jmp Eend + ; --- 7 --- save crsr +E8 cmp #$37 ; 7 ? + bne E9 + lda Font ; save font + sta SaveF + lda INVFLG ; save reverse mode + sta SaveR + ldx CV ; save position + ldy CH + stx SaveRow + sty SaveCol + jmp Eend + ; --- 8 --- restore crsr +E9 cmp #$38 ; 8 ? + bne E10 + jsr clPending + ldx SaveRow ; restore pos + ldy SaveCol + jsr CPlot + lda SaveR ; restore .. + sta INVFLG ; .. reverse mode + ldx SaveF ; restore font + stx Font + jmp Eend + + ; --- unknown --- +E10 + + ; --- reset ESC mode --- +Eend lda #$00 ; reset EMode + sta EMode + rts + + ; --- set Throw mode --- +sThrow lda #$f0 ; set esc mode $f0 + sta EMode + rts + +; ------------------------------------- +; [ esc mode +; +; EMode = $ff +; ------------------------------------- + +LEsc tya ; restore char + + ldy EBufL + sta EBuf,y ; store char + iny + sty EBufL ; inc esc buffer + + jsr TestL ; test letter + bcs LE1 ; process command + rts + +; --- process esc command --- +; A = last char +; Y = EBufL +; X conunts processed command chars +LE1 ldx #$00 ; first char + +; --- A --- crsr up + cmp #$41 ; A ? + bne LE2 + jsr clPending + jsr GetNum ; get argument + lda EPar ; EPar = 0... + bne LE1c + inc EPar ; .. means 1 +LE1c lda CV ; get crsr row + sec + sbc EPar ; row = row - up + cmp SRS ; stop at top of .. + bpl LE1a ; ..scroll region + lda SRS +LE1a tax ; x is row + ldy CH ; y is col + jsr CPlot ; set crsr + jmp LEend + +; --- B --- crsr down +LE2 cmp #$42 ; B ? + bne LE3 + jsr clPending + jsr GetNum ; get argument + lda EPar ; EPar = 0... + bne LE2c + inc EPar ; .. means 1 +LE2c lda CV ; get crsr row + clc + adc EPar ; row = row + down + cmp SRE ; outside scrregion? + bcs LE2d ; yes -> branch + tax ; x is row + jmp LE2a +LE2d ldx SRE ; x = row = SRE +LE2a ldy CH ; y is col + jsr CPlot ; set crsr + jmp LEend + +; --- C --- crsr right +LE3 cmp #$43 ; C ? + bne LE4 + jsr clPending + jsr GetNum ; get argument + lda EPar ; EPar = 0... + bne LE3c + inc EPar ; .. means 1 +LE3c lda CH ; get crsr col + clc + adc EPar ; col = col + right + cmp #$4f ; outside screen? + bcs LE3d ; yes -> branch + tay + jmp LE3a +LE3d ldy #$4f ; y=col=left margin +LE3a ldx CV ; x is row + jsr CPlot ; set crsr + jmp LEend + +; --- D --- crsr left +LE4 cmp #$44 ; D ? + bne LE5 + jsr clPending + jsr GetNum ; get argument + lda EPar ; EPar = 0... + bne LE4c + inc EPar ; .. means 1 +LE4c lda CH ; get crsr col + sec + sbc EPar ; col = col - left + bpl LE4a ; stop at left.. + lda #$00 ; ..margin +LE4a tay ; y is col + ldx CV ; x is row + jsr CPlot ; set crsr + jmp LEend + +; --- m --- font attributes +LE5 cmp #$6d ; m ? + beq LE5a + jmp LE6 ; too far to branch +LE5a jsr GetNum + pha ; save nondigit char + lda Font ; font to A + ldy EPar ; parameter to Y + ; -- 0 -- + bne LE5b ; 0 ? + tya ; set font = vanilla + jmp LE5nx + ; -- 1 -- bold +LE5b cpy #$01 + bne LE5c + ora #$02 ; bit 1 = bold + jmp LE5nx + ; -- 4 -- underline +LE5c cpy #$04 + bne LE5d + ora #$04 ; bit 2 = underline + jmp LE5nx + ; -- 7 -- reverse +LE5d cpy #$07 + bne LE5nx + ora #$01 ; bit 0 = reverse +LE5nx ; -- next char -- + sta Font + pla ; get nondigit char + cmp #$3b ; is semicolon? + beq LE5a ; then next param + ; set ANSI font attributes + lda Font + ldx #$ff ; reverse off + lsr ; reverse? + bcc LE5k + ldx #$3f ; reverse on +LE5k stx INVFLG ; set reverse mode + jmp LEend + +; --- K --- erase line +LE6 cmp #$4b ; K ? + bne LE7 + jsr GetNum ; get parameter + lda EPar ; in A + ; -- 0 -- crsr to end of line + bne LE6b + jsr ErEnLn ; erase end line + jmp LEend + ; -- 1 -- begin to crsr +LE6b cmp #$01 + bne LE6d + jsr ErBeLn ; erase beg line + jmp LEend + ; -- 2 -- whole line +LE6d cmp #$02 + bne LE6e ; par undefined + ldx CV ; line in X + jsr ErLn ; erase line + sta sCrsrChar ; del char .. + ; ..under crsr +LE6e jmp LEend + + +; --- f --- same as H +LE7 cmp #$66 + bne LE8 + jmp LE7a ; same as H + +; --- H --- cursor position +LE8 cmp #$48 + bne LE9 +LE7a jsr clPending + cpy #$01 ; no par means home + bne LE8a + ; -- home -- + ldx #$00 + ldy #$00 + jsr CPlot ; set crsr + jmp LEend + ; -- row, col -- +LE8a jsr GetNum + cmp #$3b ; is ;? + bne LE8d ; no -> error + ; -- prepare row -- + ldy EPar ; get row + bne LE8b ; 0 means 1 + iny +LE8b dey ; line 1 -> line 0 + cpy #$18 ; >= 24?.. + bcs LE8d ; ..error! + sty xVector ; save row + ; -- prepare col + jsr GetNum + ldy EPar ; get col + bne LE8c ; 0 means 1 + iny +LE8c dey ; col 1 -> col 0 + cpy #$50 ; >= 80?.. + bcs LE8d ; ..error! + ldx xVector ; restore row to X + jsr CPlot ; set crsr +LE8d jmp LEend + +; --- J --- erase screen +LE9 cmp #$4a ; J ? + bne LE10 + jsr GetNum ; get parameter + lda EPar ; in A + ; -- 0 -- crsr to end + bne LE9a + jsr ErEnLn ; del rest of line + ldx CV ; get crsr line +LE9b inx ; next line + cpx #$18 ; line 24? + bcs LE9f ; then end + txa + pha ; save X + jsr ErLn ; erase line + pla + tax ; restore X + jmp LE9b ; next line + ; -- 1 -- beg of screen to crsr +LE9a cmp #$01 + bne LE9e + jsr ErBeLn ; del start of ln + ldx CV ; get crsr line +LE9c dex ; previous line + bmi LE9f ; neg line -> end + txa + pha ; save X + jsr ErLn ; erase line + pla + tax ; restore X + jmp LE9c + ; -- 2 -- del screen +LE9e cmp #$02 ; unknown? + bne LE9f ; then ingnore + ldx #$17 ; start at ln 23 +LE9d txa + pha ; save X + jsr ErLn ; erase line + pla + tax ; restore X + dex ; previous line + bpl LE9d +LE9f jmp LEend + +; --- r --- set scroll region +LE10 cmp #$72 ; r ? + bne LE11 + ; -- prepare top -- + jsr GetNum + cmp #$3b ; is ;? + bne LE10e ; no -> error + ldy EPar ; get top + dey ; line 1 -> line 0 + cpy #$18 ; >=24?.. + bcs LE10e ; ..error! + sty xVector ; save top + ; -- prepare bottom -- + jsr GetNum + ldy EPar ; get bottom + dey ; line 1 -> line 0 + cpy #$18 ; >=24?.. + bcs LE10e ; ..error! + sty zVector ; save bottom + ; -- validate lines -- + lda xVector ; restore top + cmp zVector ; >= bottom?.. + bcs LE10e ; ..error! + sta SRS ; top -> SRStart + sty SRE ; bottom -> SREnd + ; -- home crsr + jsr clPending + ldx #$00 + ldy #$00 + jsr CPlot +LE10e jmp LEend + +; --- l --- set crsr invisible +LE11 cmp #$6c ; l ? + bne LE12 + lda EBuf ; first char .. + cmp #$3f ; .. is '?' ? + bne LE11a + inx ; at second char .. + jsr GetNum + lda EPar + cmp #25 ; .. 25 ? + bne LE11a + jsr COff ; switch crsr off + sta civis ; mark invisible +LE11a jmp LEend + +; --- h --- set crsr visible +LE12 cmp #$68 ; h ? + bne LE13 + lda EBuf ; first char .. + cmp #$3f ; ... is '?' ? + bne LE12a + inx ; at second char .. + jsr GetNum + lda EPar + cmp #25 ; .. 25 ? + bne LE12a + lda #$00 + sta civis ; mark visible + jsr COn ; switch crsr off +LE12a jmp LEend + +LE13 +; --- unknown esc seqence --- +LEend lda #$00 + sta EBufL ; reset esc buffer + sta EMode ; reset esc mode + rts + +; ------------------------------------- +; GetNum - get decimal number from +; esc sequence +; +; params: esc sequence in EBuf +; first index to process in X +; affects: A, X, Y +; return: number in EPar +; first non digit char in A +; next index to process in X +; ------------------------------------- + +GetNum lda #$00 ; init value + sta EPar +GN2 lda EBuf,x ; get next char + inx + jsr TestD ; digit? + bcc GN1 ; no -> return + tay ; digit to Y + lda EPar + jsr addDecDig + sta EPar + jmp GN2 ; next char + +GN1 rts + +; ------------------------------------- +; TestL - Test letter +; +; params: char in A +; affects: none +; return: c = 1 for letter +; c = 0 for no letter +; ------------------------------------- + +TestL cmp #$41 ; smaller then A? + bcs TL1 ; no -> go on + rts ; return no letter + +TL1 cmp #$5b ; smaller then Z+1? + bcs TL2 ; no -> go on + sec ; return letter + rts + +TL2 cmp #$61 ; smaller then a? + bcs TL3 ; no -> go on + rts ; return no letter + +TL3 cmp #$7b ; smaller then z+1? + bcs TL4 ; no -> go on + sec ; return letter + rts + +TL4 clc ; return no letter + rts + +; ------------------------------------- +; TestD - test digit +; +; params: char in A +; affects: none +; return: c = 1 for digit +; c = 0 for no digit +; ------------------------------------- + +TestD cmp #$30 ; smaller then 0? + bcs TD1 ; no -> go on + rts ; return no digit + +TD1 cmp #$3a ; smaller then 9+1? + bcs TD2 ; no -> go on + sec ; return digit + rts + +TD2 clc ; return no digit + rts + +; ------------------------------------- +; addDecDig - add decimal digit +; +; multiply A * 10, add Y +; +; param: present number in A +; new digit in Y (may be ASCII digit) +; affects: A +; return: 10 times the number in A + Y +; c = 1 overflow occured, +; number invalid +; c = 0 no overflow +; ------------------------------------- + +addDecDig + ; --- inc value --- + ; old value * 10 + ; 10a = ( 4a + a ) * 2 + sta mul10buf + clc + asl ; ( 4a + bcs aDDigE + asl + bcs aDDigE + adc mul10buf ; + a ) + bcs aDDigE + asl ; *2 + bcs aDDigE + sta mul10buf + ; --- add Y --- + tya + and #$0f ; digit to val + adc mul10buf + +aDDigE rts + +; ************************************* +; * +; * outgoing data +; * +; ************************************* + +; ------------------------------------- +; process outgoing key +; +; params: key in Y +; ------------------------------------- + +ProcOut + lda kta,y ; keyboard to ASCII + beq POrts ; ignore key + cmp #$fe + beq CmdKey ; command key + jsr putRS +POrts rts + +; ------------------------------------- +; outgoing command key +; +; ------------------------------------- + +ScrsrU .byt $1b, $5b, $41, $00 ; esc [ A +ScrsrD .byt $1b, $5b, $42, $00 ; esc [ B +ScrsrR .byt $1b, $5b, $43, $00 ; esc [ C +ScrsrL .byt $1b, $5b, $44, $00 ; esc [ D + +CmdKey tya ; restore character + +; --- crsr L --- +; --- ^H --- +; both events send char $08 + cmp #$08 + bne C0 + bit BUTN0 ; Open-Apple key + bpl crsrL ; not pressed + jsr putRS ; send ^H + rts + + ; crsr L +crsrL ldx #ScrsrL + jsr SendStr + rts + +; --- crsr D --- +; --- ^J --- +; both events send char $0a +C0 cmp #$0a + bne C1 + bit BUTN0 ; Open-Apple key + bpl crsrD ; not pressed + jsr putRS ; send ^J + rts + + ; crsr down is pressed +crsrD ldx #ScrsrD + jsr SendStr + rts + +; --- crsr U --- +; --- ^K --- +; both events send char $0b +C1 cmp #$0b + bne C2 + bit BUTN0 ; Open-Apple key + bpl crsrU ; not pressed + jsr putRS ; send ^K + rts + + ; crsr up is pressed +crsrU ldx #ScrsrU + jsr SendStr + rts + +; --- crsr R --- +; --- ^U --- +; both events send char $15 +C2 cmp #$15 + bne C3 + bit BUTN0 ; Open-Apple key + bpl crsrR ; not pressed + jsr putRS ; send ^U + rts + + ; crsr R +crsrR ldx #ScrsrR + jsr SendStr + rts + +; --- Open-Apple q --- +; quit CaTer +C3 cmp #$71 ; q + bne C4 + bit BUTN0 ; Open-Apple key + bmi Cquit ; pressed + jsr putRS ; send q + rts + + ; quit CaTer +Cquit jsr telnet_close + rts + +; --- unknown character --- +C4 rts + +; ************************************* +; * +; * screen handling +; * +; ************************************* + +; ------------------------------------- +; COff - switch cursor off +; +; affects: none +; +; Switch cursor off and restore char. +; This has to be done before every crsr +; movement. +; After movement COn has to be called. +; ------------------------------------- + +COff pha ; save registers + tya + pha + + lda civis ; invisible? + bne CO2 ; -> do nothing + lda CH ; get column + lsr ; column DIV 2 + tay + lda sCrsrChar ; restore char + bcs CO1 ; odd column? + bit $c055 +CO1 sta (BASL),y + bit $c054 +CO2 pla ; restore registers + tay + pla + rts + +; ------------------------------------- +; COn - switch crsr on +; +; affects: none +; +; opposite of COff +; ------------------------------------- + +COn pha + tya + pha + + lda civis ; invisible? + bne COn4 ; -> do nothing + lda CH ; get column + lsr ; column DIV 2 + tay + bcs COn1 ; odd column? + bit $c055 +COn1 lda (BASL),y ; save chr + sta sCrsrChar + and #$20 ; capital letter? + beq COn2 ; yes + lda sCrsrChar + eor #$80 ; reverse char + jmp COn3 +COn2 lda sCrsrChar + eor #$c0 ; reverse capital letter +COn3 sta (BASL),y + bit $c054 + +COn4 pla + tay + pla + rts + +; ------------------------------------- +; CPlot - move cursor +; +; params: coumn in Y +; line in X +; affects: A, X, Y +; +; The crsr ist turned off during +; operation (COff - COn) +; ------------------------------------- + +CPlot jsr COff + jsr Plot + jsr COn + rts + +; ------------------------------------- +; Plot - move cursor +; +; params: coumn in Y +; line in X +; affects: A, X, Y +; ------------------------------------- + +Plot stx CV ; set row + sty CH ; set col + jsr SLV + ldx xVector ; set screen line + ldy xVector+1 + stx BASL + sty BASH + rts + +; ------------------------------------- +; CPrnChr - print char to screen +; +; params: chr in A, $ff means no output +; affects: A +; uses: xVector +; +; The crsr ist turned off during +; operation (COff - COn) +; ------------------------------------- + +CPrnChr jsr COff + jsr PrnChr + jsr COn + rts + +; ------------------------------------- +; PrnChr - print char to screen +; +; params: chr in A, $80 means no output +; affects: A +; uses: xVector +; ------------------------------------- + +PrnChr sta xVector ; save char + txa ; save registers + pha + tya + pha + lda xVector ; restore char + + ; -- $80-$ff -- non-ASCII + bpl PC1 + jmp PCend + ; -- $20-$7f -- printable +PC1 cmp #$20 + bcc PC2 + jmp PCrvs + ; -- $00-$1f -- control +PC2 jmp PCend ; no output + + ; -- handle reverse mode -- +PCrvs ora #$80 ; turn on high bit + ldy INVFLG + cpy #$FF ; normal character display mode? + beq PCput + cmp #$E0 ; lowercase? + bcc mask + and #$7F ; inverse lowercase + jmp PCput +mask and INVFLG ; apply normal, inverse, flash + +PCput ldx lbPending ; need new line? + beq PC6 ; no -> skip + ldx #$00 ; clear pending + stx lbPending + jsr NewLn +PC6 tax ; save char + lda CH ; get crsr col + lsr ; col DIV 2 + tay + txa ; restore char + bcs PC7 ; odd col? + bit $c055 +PC7 sta (BASL),y ; char to screen + bit $c054 + ldy CH ; get crsr col + + ; -- move on crsr -- + cpy #$4f ; col = 79? + bne PC8 ; no -> skip + lda #$ff ; yes -> set.. + sta lbPending ; ..pending + jmp PCend +PC8 iny ; move on crsr + sty CH + +PCend pla ; restore registers + tay + pla + tax + rts + +; ------------------------------------- +; NewLn - move crsr to next line +; +; affects: X, Y +; +; --- INTERNAL --- +; subtask of PrnChr +; ------------------------------------- + +NewLn pha ; save char + ldx CV ; get crsr row + cpx SRE ; end of scroll reg? + beq NL1 ; yes -> branche + cpx #$17 ; line 23? + beq NLend ; yes -> crsr stays + ; --- normal wrap --- + inx ; increase line + ldy #$00 ; begin of line + jsr Plot + jmp NLend + ; --- scroll up --- +NL1 jsr UScrl + ldy #$00 ; begin of line + sty CH +NLend pla ; restore char + rts + +; ------------------------------------- +; DEL - move crsr to the left and +; delete char +; +; Can move through left margin. +; +; affects: A, X, Y +; ------------------------------------- + +DEL jsr COff + ldy CH + lda lbPending + beq DEL1 + ; pending + jsr clPending + jmp DELe + +DEL1 dey + bmi DEL2 + ; middle of line + sty CH + jmp DELe + +DEL2 ; first col + ldx CV + beq DELee ; odd: top left corner + dex + ldy #79 + jsr Plot + ldy CH + +DELe tya + lsr ; col DIV 2 + tay + lda #" "|$80 ; clear char + bcs DEL3 ; odd col? + bit $c055 +DEL3 sta (BASL),y + bit $c054 +DELee jsr COn + rts + +; ------------------------------------- +; clPending - clear pending flag +; +; affects: none +; +; Must be called in all crsr movement +; commands. +; ------------------------------------- + +clPending + pha + lda #$00 + sta lbPending + pla + rts + +; ------------------------------------- +; CUScrl - scroll up scrollregion +; +; affects: A, X, Y +; +; The crsr ist turned off during +; operation (COff - COn) +; ------------------------------------- + +CUScrl jsr COff + jsr UScrl + jsr COn + rts + +; ------------------------------------- +; UScrl - scroll up scrollregion +; +; affects: A, X, Y +; uses: xVector, zVector +; ------------------------------------- + +UScrl ldx SRS ; get first line + ; --- scroll one line --- +US1 ; -- new line: -- + ; -- zVector -- + jsr SLV + lda xVector ; screen line + ldy xVector+1 + sta zVector + sty zVector+1 + ; -- old line: -- + ; -- xVector -- + inx ; old line + jsr SLV + ; -- copy even col chars -- + bit $c055 + ldy #$27 ; even col 39 +US2 lda (xVector),y ; copy char + sta (zVector),y + dey + bpl US2 + ; -- copy odd col chars -- + bit $c054 + ldy #$27 ; odd col 39 +US3 lda (xVector),y ; copy char + sta (zVector),y + dey + bpl US3 + cpx SRE ; last line? + bne US1 ; no -> go on + jsr ErLn_ ; del last line + + rts + +; ------------------------------------- +; CDScrl - scroll down scrollregion +; +; affects: A, X, Y +; +; The crsr ist turned off during +; operation (COff - COn) +; ------------------------------------- + +CDScrl jsr COff + jsr DScrl + jsr COn + rts + +; ------------------------------------- +; DScrl - scroll down scrollregion +; +; affects: A, X, Y +; uses: xVector, zVector +; ------------------------------------- + +DScrl ldx SRE ; get last line + ; --- scroll one line --- +DS1 ; -- new line: -- + ; -- zVector -- + jsr SLV + lda xVector ; screen line + ldy xVector+1 + sta zVector + sty zVector+1 + ; -- old line: -- + ; -- xVector -- + dex ; old line + jsr SLV + ; -- copy even col chars -- + bit $c055 + ldy #$27 ; even col 39 +DS2 lda (xVector),y ; copy char + sta (zVector),y + dey + bpl DS2 + ; -- copy odd col chars -- + bit $c054 + ldy #$27 ; odd col 39 +DS3 lda (xVector),y ; copy char + sta (zVector),y + dey + bpl DS3 + cpx SRS ; first line? + bne DS1 ; no -> go on + jsr ErLn_ ; del first line + + rts + +; ------------------------------------- +; ErLn - erase screen line +; +; params: line number in X +; affects: A, X, Y +; return: $20 (space) in A +; +; For internal use: +; ErLn_ needs line ptr in xVector +; ------------------------------------- + +ErLn jsr SLV ; line start in xVector + + ; -- erase even col chars -- +ErLn_ bit $c055 + ldy #$27 ; even col 39 + lda #$20|$80 ; load space +EL1 sta (xVector),y ; clear char + dey + bpl EL1 + + ; -- erase odd col chars -- + bit $c054 + ldy #$27 ; odd col 39 +EL2 sta (xVector),y ; clear char + dey + bpl EL2 + + rts + +; ------------------------------------- +; ErEnLn - erase to end of line +; +; affects: A, X, Y +; +; erase screen line from crsr to end of line +; ------------------------------------- + +ErEnLn + ; -- erase even col chars -- + bit $c055 + lda CH ; get crsr col + lsr ; col DIV 2 + tay + sty tmp1 ; save start + lda #$20|$80 ; load space + bcs EEL2 ; odd crsr col +EEL1 sta (BASL),y ; clear char +EEL2 iny + cpy #$28 ; even pos 40? + bne EEL1 ; next char + + ; -- erase odd col chars -- + bit $c054 + ldy tmp1 ; restore start +EEL3 sta (BASL),y ; clear char + iny + cpy #$28 ; odd pos 40? + bne EEL3 ; next char + + sta sCrsrChar ; del char .. + ; ..under crsr + rts + +; ------------------------------------- +; ErBeLn - erase from begin of line +; +; affects: A, X, Y +; +; erase screen line up to crsr +; ------------------------------------- + +ErBeLn + ; -- erase even col chars -- + bit $c055 + lda CH ; get crsr col + lsr ; col DIV 2 + tay + sty tmp1 ; save start + lda #$20|$80 ; load space +EBL1 sta (BASL),y ; clear char + dey + bpl EBL1 ; pos>=0 -> next + + ; -- erase odd col chars -- + bit $c054 + ldy tmp1 ; restore start + bcc EBL3 ; even crsr col +EBL2 sta (BASL),y ; clear char +EBL3 dey + bpl EBL2 ; pos>=0 -> next + + sta sCrsrChar ; del char .. + ; ..under crsr + rts + +; ------------------------------------- +; SLV - set line vector +; --- INTERNAL --- +; +; params: line no in X +; affects: A, Y +; return: screen line ptr in xVector +; ------------------------------------- + +SLV lda LineVecLo,x + ldy LineVecHi,x + sta xVector + sty xVector+1 + rts + +LineVecLo +.byt $00, $80, $00, $80, $00, $80, $00, $80 +.byt $28, $A8, $28, $A8, $28, $A8, $28, $A8 +.byt $50, $D0, $50, $D0, $50, $D0, $50, $D0 +LineVecHi +.byt $04, $04, $05, $05, $06, $06, $07, $07 +.byt $04, $04, $05, $05, $06, $06, $07, $07 +.byt $04, $04, $05, $05, $06, $06, $07, $07 + +; ************************************* +; * +; * Init routines +; * +; ************************************* + +; ------------------------------------- +; init memory +; +; ------------------------------------- + +InitVar lda #$00 + sta EMode + sta EBufL + sta SRS + sta Font + sta SaveF + sta SaveR + sta SaveRow + sta SaveCol + sta lbPending + sta civis + + lda #$17 ; last line + sta SRE ; = 23 + + rts + +; ------------------------------------- +; Init char +; +; ------------------------------------- + +InitChar + rts + +; ------------------------------------- +; Exit char +; +; ------------------------------------- + +ExitChar + rts + +; ------------------------------------- +; Init Screen +; +; ------------------------------------- + +InitScr + ; --- turn on 80 col --- + jsr $c300 + ; --- limit SET80COL-HISCR to text --- + bit LORES + ; --- erase screen --- + ldx #$16 ; start at ln 22 +IS1 txa + pha ; save X + jsr ErLn ; erase line + pla + tax ; restore X + dex ; previous line + bpl IS1 + ; --- put crsr --- + ldx #$00 + ldy #$00 + jsr Plot + + rts + +; ------------------------------------- +; Exit Screen +; +; ------------------------------------- + +ExitScr + ; --- erase screen --- + jsr $fc58 ; clear current text screen + rts + +; ************************************* +; * +; * ASCII tables +; * +; ************************************* + +; ------------------------------------- +; table keyboard to ASCII +; +; This table is used to prepare keyboard +; input for sending over the serial +; line. +; +; ascii = $00 means ignore key +; ascii = $fe means do something +; complicated (command key) +; ------------------------------------- + +kta ;_0 _1 _2 _3 _4 _5 _6 _7 _8 _9 _a _b _c _d _e _f + +; --- Control chars ------------------------------------------------ +; {←} {↓} {↑} +; ^A ^B ^C ^D ^E ^F ^G ^H ^I ^J ^K ^L ^M ^N ^O +.byt $00,$01,$02,$03,$04,$05,$06,$07,$fe,$09,$fe,$fe,$0c,$0d,$0e,$0f ; 0_ +; {→} +; ^P ^Q ^R ^S ^T ^U ^V ^W ^X ^Y ^Z ^[ ^\ ^] ^^ ^_ +.byt $10,$11,$12,$13,$14,$fe,$16,$17,$18,$19,$1a,$1b,$1c,$1d,$1e,$1f ; 1_ + +; --- special chars ------------------------------------------------ +; ' ' ! " # $ % & ' ( ) * + , - . / +.byt $20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2a,$2b,$2c,$2d,$2e,$2f ; 2_ +; 0 1 2 3 4 5 6 7 8 9 : ; < = > ? +.byt $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$3d,$3e,$3f ; 3_ + +; --- capital letters ---------------------------------------------- +; @ A B C D E F G H I J K L M N O +.byt $40,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4a,$4b,$4c,$4d,$4e,$4f ; 4_ +; P Q R S T U V W X Y Z [ \ ] ^ _ +.byt $50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$5a,$5b,$5c,$5d,$5e,$5f ; 5_ + +; --- lower case letters ------------------------------------------- +; ` a b c d e f g h i j k l m n o +.byt $60,$61,$62,$63,$64,$65,$66,$67,$68,$69,$6a,$6b,$6c,$6d,$6e,$6f ; 6_ +; p q r s t u v w x y z { | } ~ DEL +.byt $70,$fe,$72,$73,$74,$75,$76,$77,$78,$79,$7a,$7b,$7c,$7d,$7e,$7f ; 7_ diff --git a/drivers/atrvt100.s b/drivers/atrvt100.s new file mode 100644 index 0000000..45b857d --- /dev/null +++ b/drivers/atrvt100.s @@ -0,0 +1,6 @@ +.export vt100_init_terminal = $1000 +.export vt100_exit_terminal = $1000 +.export vt100_process_inbound_char = $1000 +.export vt100_process_outbound_char = $1000 +.exportzp vt100_screen_cols = 40 +.exportzp vt100_screen_rows = 24 diff --git a/drivers/c64vt100.s b/drivers/c64vt100.s new file mode 100644 index 0000000..9532169 --- /dev/null +++ b/drivers/c64vt100.s @@ -0,0 +1,1937 @@ +.feature labels_without_colons +.feature leading_dot_in_identifiers +.feature loose_char_term +.define .asc .byt + +.export vt100_init_terminal = InitTerminal +.export vt100_exit_terminal = ExitTerminal +.export vt100_process_inbound_char = ProcIn +.export vt100_process_outbound_char = ProcOut +.exportzp vt100_screen_cols = 40 +.exportzp vt100_screen_rows = 25 + +.import beep +.import telnet_close +.import telnet_send_char +.import telnet_send_string + +putRS = telnet_send_char +SendStr = telnet_send_string + +; ************************************* +; * * +; * C a T e r * +; * * +; * Copyright by * +; * Lars Stollenwerk * +; * * +; * 2001 - 2003 * +; * * +; * This file is part of CaTer. * +; * * +; * CaTer is provided under the terms * +; * of GNU General Public License. * +; * * +; * For more information see the * +; * README file. * +; * * +; ************************************* + +; ************************************* +; * +; * Constant declaration +; * +; ************************************* + +; --- video RAM --- +Video = $84 ; $8400 - $87E7 + +; --- char ROM --- +Char = $8800 ; $8800 - $8fff + +; --- colour values --- +; 0 black 8 orange +; 1 white 9 brown +; 2 red a light red +; 3 cyan b gray 1 +; 4 purple c gray 2 +; 5 green d light green +; 6 blue e light blue +; 7 yellow f gray 3 + +; --- font type --- +; vanilla f bold 1 +; underline e 3 +fVa = $0f +fBo = $01 +fUl = $0e +fUlBo = $03 + +; text background +bgcolour = $0b ; gray1 + +; border colour +bgocolour = $0c ; gray2 + +; ------------------------------------- +; Zeropage Kernal +; +; Zeropage from $90 to $ff is used +; by kernal. +; Following are the variables accessed +; by CaTer. +; ------------------------------------- + +; --- reverse mode --- +; 0 = normal, !0 = revers +Rvs = $c7 + +; --- crsr flag, 0 = on --- +sCrsrOn = $cc + +; --- crsr blink counter --- +sCrsrCnt = $cd + +; --- char under crsr --- +sCrsrChar = $ce + +; --- crsr blink phase --- +; $00 = normal, $01 = revers +sCrsrPhase = $cf + +; --- ptr to start of screen line --- +sLinePtr = $d1 + +; --- crsr column --- +sCol = $d3 + +; --- crsr row --- +sRow = $d6 + +; --- ptr to start of colour line --- +sLineColPtr = $f3 + +; ------------------------------------- +; page $02, $03: BASIC and KERNAL +; +; Following are the variables accessed +; by CaTer. +; ------------------------------------- + +; --- colour for writing --- +sColor = $0286 + +; --- colour under crsr --- +sCrsrCol = $0287 + +; --- video addr hibyte --- +VideoAddr = $0288 + +; --- CTRL, SHIFT, C= --- +; flags indicating pressed +; contol keys +; 1 SHIFT, 2 C=, 4 CTRL +ControlFlags = $028d + +; --- flag for SHIFT + C= --- +; $80 = lock, no charset switch +; $00 = free +ShiftCFlag = $0291 + +; ************************************* +; * +; * Zeropage +; * +; ************************************* + +.include "zeropage.inc" + +; --- Vector --- +; four vectors in zeropage for +; temporary use. +zVector = ptr1 +yVector = ptr2 +xVector = ptr3 +wVector = ptr4 + +; --- vector for PrnScr --- +; tmp1, tmp2 +vVector = tmp1 + +; ************************************* +; * +; * Variables +; * +; ************************************* + +.bss + +; --- esc mode --- +; $00 = normal +; $0f = esc mode +; $ff = esc [ mode +; $f0 = ignore one char +EMode .res 1 + +; --- esc buffer --- +EBuf .res $100 + +; --- esc buffer length --- +; points on first free position +EBufL .res 1 + +; --- esc parameter --- +; numeric parameter in esc sequence +EPar .res 1 + +; --- scroll region --- +SRS .res 1 ; first line number +SRE .res 1 ; last line number + +; --- ANSI font attributes --- +; contains three bits +; bit 0 = reverse +; bit 1 = bold +; bit 2 = underline +; bit 6 = background set +; bit 7 = foreground set +Font .res 1 +; foreground +AFore .res 1 +; background +ABack .res 1 + +; --- crsr save area --- +; here is crsr info saved with ESC 7 +; and restored from with ESC 8 +SaveF .res 1 ; font +SaveR .res 1 ; reverse mode +SaveRow .res 1 ; row +SaveCol .res 1 ; column + +; --- Linebreak pending --- +; 0 = not pending, ff = pending +lbPending .res 1 + +; --- crsr invisible --- +; 0 = visible, !0 = invisible +civis .res 1 + +; --- buffer for addDecDig --- +mul10buf .res 1 + +; ************************************* +; * +; * Code +; * +; ************************************* + +.code + +; ------------------------------------- +; init terminal +; +; ------------------------------------- + +InitTerminal + jsr InitVar ; memory variables + jsr InitChar; init font + jsr InitScr ; init screen + rts + +; ------------------------------------- +; exit terminal +; +; ------------------------------------- + +ExitTerminal + jsr ExitChar; exit font + jsr ExitScr ; exit screen + rts + +; ************************************* +; * +; * imcoming data +; * +; ************************************* + +; ------------------------------------- +; process incoming data +; +; char in Y +; ------------------------------------- + +ProcIn lda EMode ; handle esc mode + bne PIEsc + lda atp,y ; ASCII to PETSCII + beq PIrts ; ignore $00 + cmp #$01 ; something special? + beq Special + jsr CPrnChr ; print to screen +PIrts rts + +; to far for branch +PIEsc jmp Esc + +; ------------------------------------- +; special incoming char +; +; ------------------------------------- + +Special tya ; restore char +; --- CR --- + cmp #$0d ; CR? + bne D1 +CR jsr clPending + ldx sRow ; get row + ldy #$00 ; set col=0 + jsr CPlot ; set crsr + rts +; --- BS --- +D1 cmp #$08 ; BS? + bne D2 +BS jsr clPending + ldy sCol ; get col + beq D1rts ; stop @ left margin + dey ; dec column + ldx sRow ; get row + jsr CPlot ; set crsr +D1rts rts +; --- ESC --- +D2 cmp #$1b ; esc? + bne D3 + lda #$0f ; set esc mode + sta EMode + rts +; --- BEL --- +D3 cmp #$07 ; BEL? + bne D4 + jsr beep + rts +; --- LF --- +D4 cmp #$0a ; LF? + bne D5 +LF jsr clPending + ldx sRow ; crsr line + cpx SRE ; end scroll region? + bne D4a ; no -> branch + jsr CUScrl ; yes -> scroll up + rts +D4a cpx #$18 ; end of screen? + bne D4b ; no -> branch + rts ; yes -> do nothing +D4b inx ; next line + ldy sCol ; get col + jsr CPlot ; set crsr + rts +; --- TAB --- +D5 cmp #$09 ; TAB? + bne D6 + ; don't clear pending + ; don't set pending + lda sCol ; crsr col + and #$f8 ; (col DIV 8) * 8 + clc ; col + 8 + adc #$08 + cmp #$28 ; col=40? + bne D5a ; no -> skip + lda #$27 ; yes -> col=39 +D5a tay ; col to y + ldx sRow ; line to x + jsr CPlot ; set crsr + rts + +D6 rts + +; ------------------------------------- +; esc mode +; +; char in Y +; EMode != $00 in A +; ------------------------------------- + +Esc tax ; save EMode + and #$0f ; EMode = $0f? + bne E1 + +; --- throw mode --- EMode = $f0 +; throw away char + lda #$00 ; reset EMode + sta EMode + rts + +E1 txa ; restore EMode + and #$f0 ; EMode = $ff? + beq SEsc ; no -> short Emode + jmp LEsc ; yes -> long Emode + +; ------------------------------------- +; short esc mode +; +; EMode = $0f +; process first char +; ------------------------------------- + +SEsc tya ; restore char + ; --- [ --- + cmp #$5b ; [ ? + bne E2 + lda #$ff ; set esc [ mode + sta EMode + rts + ; --- ( --- +E2 cmp #$28 ; ( ? + bne E3 + jmp sThrow + ; --- ) --- +E3 cmp #$29 ; ) ? + bne E4 + jmp sThrow + ; --- # --- +E4 cmp #$23 ; # ? + bne E5 + jmp sThrow + ; --- D --- index +E5 cmp #$44 ; D ? + bne E6 + jsr LF ; same as LF + jmp Eend + ; --- M --- reverse index +E6 cmp #$4d ; M ? + bne E7 + jsr clPending + ldx sRow ; get crsr row + cpx SRS ; top os scroll reg? + bne E6a + jsr CDScrl ; yes -> scroll down + jmp Eend +E6a cpx #$00 ; top of screen? + bne E6b + jmp Eend ; yes -> do nothing +E6b dex ; one line up + ldy sCol ; get crsr col + jsr CPlot ; set crsr + jmp Eend + ; --- E --- next line +E7 cmp #$45 ; E ? + bne E8 + jsr CR + jsr LF + jmp Eend + ; --- 7 --- save crsr +E8 cmp #$37 ; 7 ? + bne E9 + lda Font ; save font + sta SaveF + lda Rvs ; save reverse mode + sta SaveR + ldx sRow ; save position + ldy sCol + stx SaveRow + sty SaveCol + jmp Eend + ; --- 8 --- restore crsr +E9 cmp #$38 ; 8 ? + bne E10 + jsr clPending + ldx SaveRow ; restore pos + ldy SaveCol + jsr CPlot + lda SaveR ; restore .. + sta Rvs ; .. reverse mode + ldx SaveF ; restore font + stx Font + lda FontTable,x + sta sColor ; set colour + jmp Eend + + ; --- unknown --- +E10 + + ; --- reset ESC mode --- +Eend lda #$00 ; reset EMode + sta EMode + rts + + ; --- set Throw mode --- +sThrow lda #$f0 ; set esc mode $f0 + sta EMode + rts + +; ------------------------------------- +; [ esc mode +; +; EMode = $ff +; ------------------------------------- + +LEsc tya ; restore char + + ldy EBufL + sta EBuf,y ; store char + iny + sty EBufL ; inc esc buffer + + jsr TestL ; test letter + bcs LE1 ; process command + rts + +; --- process esc command --- +; A = last char +; Y = EBufL +; X conunts processed command chars +LE1 ldx #$00 ; first char + +; --- A --- crsr up + cmp #$41 ; A ? + bne LE2 + jsr clPending + jsr GetNum ; get argument + lda EPar ; EPar = 0... + bne LE1c + inc EPar ; .. means 1 +LE1c lda sRow ; get crsr row + sec + sbc EPar ; row = row - up + cmp SRS ; stop at top of .. + bpl LE1a ; ..scroll region + lda SRS +LE1a tax ; x is row + ldy sCol ; y is col + jsr CPlot ; set crsr + jmp LEend + +; --- B --- crsr down +LE2 cmp #$42 ; B ? + bne LE3 + jsr clPending + jsr GetNum ; get argument + lda EPar ; EPar = 0... + bne LE2c + inc EPar ; .. means 1 +LE2c lda sRow ; get crsr row + clc + adc EPar ; row = row + down + cmp SRE ; outside scrregion? + bcs LE2d ; yes -> branch + tax ; x is row + jmp LE2a +LE2d ldx SRE ; x = row = SRE +LE2a ldy sCol ; y is col + jsr CPlot ; set crsr + jmp LEend + +; --- C --- crsr right +LE3 cmp #$43 ; C ? + bne LE4 + jsr clPending + jsr GetNum ; get argument + lda EPar ; EPar = 0... + bne LE3c + inc EPar ; .. means 1 +LE3c lda sCol ; get crsr col + clc + adc EPar ; col = col + right + cmp #$27 ; outside screen? + bcs LE3d ; yes -> branch + tay + jmp LE3a +LE3d ldy #$27 ; y=col=left margin +LE3a ldx sRow ; x is row + jsr CPlot ; set crsr + jmp LEend + +; --- D --- crsr left +LE4 cmp #$44 ; D ? + bne LE5 + jsr clPending + jsr GetNum ; get argument + lda EPar ; EPar = 0... + bne LE4c + inc EPar ; .. means 1 +LE4c lda sCol ; get crsr col + sec + sbc EPar ; col = col - left + bpl LE4a ; stop at left.. + lda #$00 ; ..margin +LE4a tay ; y is col + ldx sRow ; x is row + jsr CPlot ; set crsr + jmp LEend + +; --- m --- font attributes +LE5 cmp #$6d ; m ? + beq LE5a + jmp LE6 ; too far to branch +LE5a jsr GetNum + pha ; save nondigit char + lda Font ; font to A + ldy EPar ; parameter to Y + ; -- 0 -- + bne LE5b ; 0 ? + tya ; set font = vanilla + jmp LE5nx + ; -- 1 -- bold +LE5b cpy #$01 + bne LE5c + ora #$02 ; bit 1 = bold + jmp LE5nx + ; -- 4 -- underline +LE5c cpy #$04 + bne LE5d + ora #$04 ; bit 2 = underline + jmp LE5nx + ; -- 7 -- reverse +LE5d cpy #$07 + bne LE5e + ora #$01 ; bit 0 = reverse + jmp LE5nx +LE5e ; -- 30 - 37 -- + cpy #38 ; >= 38? + bcs LE5g + cpy #30 ; < 30? + bcc LE5g + tya + sbc #30 + sta AFore + lda Font + ora #$80 ; bit 7 = fore + jmp LE5nx +LE5g ; -- 40 - 47 -- + cpy #48 ; >= 48? + bcs LE5nx + cpy #40 ; < 40? + bcc LE5nx + tya + sbc #40 + sta ABack + lda Font + ora #$40 ; bit 6 = back +LE5nx ; -- next char -- + sta Font + pla ; get nondigit char + cmp #$3b ; is semicolon? + beq LE5a ; then next param + ; -- set colour -- + lda Font + ; set foreground + bpl LE5h + ldx AFore + lda AColTab,x + ; avoid black or white foregr if + ; backgr is given and not black + tax + lsr ; 0(blk) or 1(wht)? + bne LE5j ; no -> keep fore + bit Font ; back? (bit 6 -> v) + bvc LE5j ; no -> keep fore + lda ABack ; back is black? + bne LE5hh ; no -> take back +LE5j txa + ; ^^^ end of avoid ^^^ + ldx #$00 ; reverse off + jmp LE5k +LE5h ; set background + bit Font ; bit 6 -> v + bvc LE5i +LE5hh ldx ABack + lda AColTab,x + ldx #$01 ; reverse on + jmp LE5k +LE5i ; set ANSI font attributes + ldx #$00 ; reverse off + lsr ; reverse? + bcc LE5l + inx ; -> reverse on +LE5l tay + lda FontTable,y +LE5k sta sColor ; set colour + stx Rvs ; set reverse mode + jmp LEend + +FontTable ; bits mean ul bo +.byt fVa, fBo ; 00 01 +.byt fUl, fUlBo ; 10 11 + +AColTab +;ANSI 30 31 32 32 34 35 36 37 +; blk red grn ye blu mag cy wh +.byt 0, 10, 5, 7, 14, 4, 3, 1 + +; --- K --- erase line +LE6 cmp #$4b ; K ? + bne LE7 + jsr GetNum ; get parameter + lda EPar ; in A + ; -- 0 -- crsr to end of line + bne LE6b + jsr ErEnLn ; erase end line + jmp LEend + ; -- 1 -- begin to crsr +LE6b cmp #$01 + bne LE6d + jsr ErBeLn ; erase beg line + jmp LEend + ; -- 2 -- whole line +LE6d cmp #$02 + bne LE6e ; par undefined + ldx sRow ; line in X + jsr ErLn ; erase line + sta sCrsrChar ; del char .. + ; ..under crsr +LE6e jmp LEend + + +; --- f --- same as H +LE7 cmp #$66 + bne LE8 + jmp LE7a ; same as H + +; --- H --- cursor position +LE8 cmp #$48 + bne LE9 +LE7a jsr clPending + cpy #$01 ; no par means home + bne LE8a + ; -- home -- + ldx #$00 + ldy #$00 + jsr CPlot ; set crsr + jmp LEend + ; -- row, col -- +LE8a jsr GetNum + cmp #$3b ; is ;? + bne LE8d ; no -> error + ; -- prepare row -- + ldy EPar ; get row + bne LE8b ; 0 means 1 + iny +LE8b dey ; line 1 -> line 0 + cpy #$19 ; >= 25?.. + bcs LE8d ; ..error! + sty xVector ; save row + ; -- prepare col + jsr GetNum + ldy EPar ; get col + bne LE8c ; 0 means 1 + iny +LE8c dey ; col 1 -> col 0 + cpy #$28 ; >= 40?.. + bcs LE8d ; ..error! + ldx xVector ; restore row to X + jsr CPlot ; set crsr +LE8d jmp LEend + +; --- J --- erase screen +LE9 cmp #$4a ; J ? + bne LE10 + jsr GetNum ; get parameter + lda EPar ; in A + ; -- 0 -- crsr to end + bne LE9a + jsr ErEnLn ; del rest of line + ldx sRow ; get crsr line +LE9b inx ; next line + cpx #$19 ; line 25? + bcs LE9f ; then end + txa + pha ; save X + jsr ErLn ; erase line + pla + tax ; restore X + jmp LE9b ; next line + ; -- 1 -- beg of screen to crsr +LE9a cmp #$01 + bne LE9e + jsr ErBeLn ; del start of ln + ldx sRow ; get crsr line +LE9c dex ; previous line + bmi LE9f ; neg line -> end + txa + pha ; save X + jsr ErLn ; erase line + pla + tax ; restore X + jmp LE9c + ; -- 2 -- del screen +LE9e cmp #$02 ; unknown? + bne LE9f ; then ingnore + ldx #$18 ; start at ln 24 +LE9d txa + pha ; save X + jsr ErLn ; erase line + pla + tax ; restore X + dex ; previous line + bpl LE9d +LE9f jmp LEend + +; --- r --- set scroll region +LE10 cmp #$72 ; r ? + bne LE11 + ; -- prepare top -- + jsr GetNum + cmp #$3b ; is ;? + bne LE10e ; no -> error + ldy EPar ; get top + dey ; line 1 -> line 0 + cpy #$19 ; >=25?.. + bcs LE10e ; ..error! + sty xVector ; save top + ; -- prepare bottom -- + jsr GetNum + ldy EPar ; get bottom + dey ; line 1 -> line 0 + cpy #$19 ; >=25?.. + bcs LE10e ; ..error! + sty yVector ; save bottom + ; -- validate lines -- + lda xVector ; restore top + cmp yVector ; >= bottom?.. + bcs LE10e ; ..error! + sta SRS ; top -> SRStart + sty SRE ; bottom -> SREnd + ; -- home crsr + jsr clPending + ldx #$00 + ldy #$00 + jsr CPlot +LE10e jmp LEend + +; --- l --- set crsr invisible +LE11 cmp #$6c ; l ? + bne LE12 + lda EBuf ; first char .. + cmp #$3f ; .. is '?' ? + bne LE11a + inx ; at second char .. + jsr GetNum + lda EPar + cmp #25 ; .. 25 ? + bne LE11a + jsr COff ; switch crsr off + sta civis ; mark invisible +LE11a jmp LEend + +; --- h --- set crsr visible +LE12 cmp #$68 ; h ? + bne LE13 + lda EBuf ; first char .. + cmp #$3f ; ... is '?' ? + bne LE12a + inx ; at second char .. + jsr GetNum + lda EPar + cmp #25 ; .. 25 ? + bne LE12a + lda #$00 + sta civis ; mark visible + jsr COn ; switch crsr off +LE12a jmp LEend + +LE13 +; --- unknown esc seqence --- +LEend lda #$00 + sta EBufL ; reset esc buffer + sta EMode ; reset esc mode + rts + +; ------------------------------------- +; GetNum - get decimal number from +; esc sequence +; +; params: esc sequence in EBuf +; first index to process in X +; affects: A, X, Y +; return: number in EPar +; first non digit char in A +; next index to process in X +; ------------------------------------- + +GetNum lda #$00 ; init value + sta EPar +GN2 lda EBuf,x ; get next char + inx + jsr TestD ; digit? + bcc GN1 ; no -> return + tay ; digit to Y + lda EPar + jsr addDecDig + sta EPar + jmp GN2 ; next char + +GN1 rts + +; ------------------------------------- +; TestL - Test letter +; +; params: char in A +; affects: none +; return: c = 1 for letter +; c = 0 for no letter +; ------------------------------------- + +TestL cmp #$41 ; smaller then A? + bcs TL1 ; no -> go on + rts ; return no letter + +TL1 cmp #$5b ; smaller then Z+1? + bcs TL2 ; no -> go on + sec ; return letter + rts + +TL2 cmp #$61 ; smaller then a? + bcs TL3 ; no -> go on + rts ; return no letter + +TL3 cmp #$7b ; smaller then z+1? + bcs TL4 ; no -> go on + sec ; return letter + rts + +TL4 clc ; return no letter + rts + +; ------------------------------------- +; TestD - test digit +; +; params: char in A +; affects: none +; return: c = 1 for digit +; c = 0 for no digit +; ------------------------------------- + +TestD cmp #$30 ; smaller then 0? + bcs TD1 ; no -> go on + rts ; return no digit + +TD1 cmp #$3a ; smaller then 9+1? + bcs TD2 ; no -> go on + sec ; return digit + rts + +TD2 clc ; return no digit + rts + +; ------------------------------------- +; addDecDig - add decimal digit +; +; multiply A * 10, add Y +; +; param: present number in A +; new digit in Y (may be ASCII digit) +; affects: A +; return: 10 times the number in A + Y +; c = 1 overflow occured, +; number invalid +; c = 0 no overflow +; ------------------------------------- + +addDecDig + ; --- inc value --- + ; old value * 10 + ; 10a = ( 4a + a ) * 2 + sta mul10buf + clc + asl ; ( 4a + bcs aDDigE + asl + bcs aDDigE + adc mul10buf ; + a ) + bcs aDDigE + asl ; *2 + bcs aDDigE + sta mul10buf + ; --- add Y --- + tya + and #$0f ; digit to val + adc mul10buf + +aDDigE rts + +; ************************************* +; * +; * outgoing data +; * +; ************************************* + +; ------------------------------------- +; process outgoing key +; +; params: key in Y +; ------------------------------------- + +ProcOut + lda pta,y ; PETSCII to ASCII + beq POrts ; ignore key + cmp #$ff + beq StrKey ; send a string + cmp #$fe + beq CmdKey ; command key + jsr putRS +POrts rts + +; ------------------------------------- +; outgoing string +; +; params: key in y +; ------------------------------------- + +ScrsrU .byt $1b, $5b, $41, $00 ; esc [ A +ScrsrD .byt $1b, $5b, $42, $00 ; esc [ B +ScrsrR .byt $1b, $5b, $43, $00 ; esc [ C +ScrsrL .byt $1b, $5b, $44, $00 ; esc [ D + +StrKey tya ; restore key + +; --- crsr U --- +K1 cmp #$91 ; test crsr U + bne K2 + ldx #ScrsrU + jsr SendStr + rts +; --- crsr L --- +K2 cmp #$9d ; test crsr L + bne K3 + ldx #ScrsrL + jsr SendStr +K3 rts + +; ------------------------------------- +; outgoing command key +; +; ------------------------------------- + +CmdKey tya ; restore character + +; --- crsr R --- +; --- ^] --- +; both events send $1d + cmp #$1d + bne C0 + lda #$04 ; test control Key + bit ControlFlags + beq crsrR ; not pressed + ; control ] is pressed + tya ; send ^] + jsr putRS + rts + + ; crsr R +crsrR ldx #ScrsrR + jsr SendStr + rts + +; --- crsr D --- +; --- ^Q --- +; both events send char $11 +C0 cmp #$11 ;^Q / crsr down + bne C8 + lda #$04 ; test control Key + bit ControlFlags + beq crsrD ; not pressed + ; control Q is pressed + tya ; send ^Q + jsr putRS + rts + + ; crsr down is pressed +crsrD ldx #ScrsrD + jsr SendStr + rts + +; --- HOME key --- +; --- ^S --- +; both events send char $13 +C8 cmp #$13 ;^S / HOME + bne C9 + lda #$04 ; test control Key + bit ControlFlags + beq C8Home ; not pressed + ; control S is pressed + tya ; send ^S + jsr putRS + rts + + ; send TAB +C8Home lda #$09 + jsr putRS + rts + +; --- HOME key --- +; --- ^T --- +; both events send char $14 +C9 cmp #$14 ;^S / DEL + bne C10 + lda #$04 ; test control Key + bit ControlFlags + beq C9Del ; not pressed + ; control T is pressed + tya ; send ^T + jsr putRS + rts + + ; send TAB +C9Del lda #$08 + jsr putRS + rts + +; --- C=Q --- +; quit CaTer +C10 cmp #$ab ; C=Q + bne C12 + jsr telnet_close + rts + +; --- unknown C=-Key --- +C12 rts + +; ************************************* +; * +; * screen handling +; * +; ************************************* + +; Variables controlling the cursor +; +; COff +; Kernal COon Plot +; sCrsrOn $cc r x +; sCrsrCnt $cd r/w x +; sCrsrPhase $cf r/w x +; sCol $d3 r x +; sRow $d6 x +; sLinePtr $d1 r x +; sLineColPtr $f3 r/w x +; sCrsrChar $ce r/w x +; sCrsrCol $0287 r/w x +; sColor $0286 r + +; Cursor blink phases: +; on (sCrsrPhase = $01) +; char on screen = revers of sCrsrChar +; color on screen = sColor +; off (sCrsrPhase = $00) +; char on screen = sCrsrChar +; color on screen = sCrsrCol + +; ------------------------------------- +; COff - switch cursor off +; +; affects: none +; +; Switch cursor off and restore char. +; This has to be done before every crsr +; movement. +; After movement COn has to be called. +; ------------------------------------- + +COff pha ; save registers + tya + pha + + lda civis ; invisible? + bne CO2 ; -> do nothing + ldy #$02 ; prevent soon.. + sty sCrsrCnt ; ..blink + sty sCrsrOn ; crsr off + lda sCrsrPhase ; crsr revers? + beq CO2 ; no -> return + dey ; normal phase + sty sCrsrPhase + ldy sCol ; get column + lda sCrsrChar ; restore char + sta (sLinePtr),y + lda sCrsrCol ; restore colour + sta (sLineColPtr),y + +CO2 pla ; restore registers + tay + pla + rts + +; ------------------------------------- +; COn - switch crsr on +; +; affects: none +; +; opposite of COff +; ------------------------------------- + +COn pha + tya + pha + + lda civis ; invisible? + bne COn1 ; -> do nothing + ldy sCol ; get column + lda (sLinePtr),y ; save chr + sta sCrsrChar + eor #$80 ; reverse char + sta (sLinePtr),y + lda (sLineColPtr),y; save colour + sta sCrsrCol + lda sColor ; set crsr colour + sta (sLineColPtr),y + lda #$14 ; set counter... + sta sCrsrCnt ; ... to max + ldy #$01 ; set rvs phase + sty sCrsrPhase + dey ; cursor on + sty sCrsrOn + +COn1 pla + tay + pla + rts + +; ------------------------------------- +; CPlot - move cursor +; +; params: coumn in Y +; line in X +; affects: A, X, Y +; +; The crsr ist turned off during +; operation (COff - COn) +; ------------------------------------- + +CPlot jsr COff + jsr Plot + jsr COn + rts + +; ------------------------------------- +; Plot - move cursor +; +; params: coumn in Y +; line in X +; affects: A, X, Y +; ------------------------------------- + +Plot stx sRow ; set row + sty sCol ; set col + jsr SLV + ldx xVector ; set screen line + ldy xVector+1 + stx sLinePtr + sty sLinePtr+1 + ldx yVector ; set color line + ldy yVector+1 + stx sLineColPtr + sty sLineColPtr+1 + rts + +; ------------------------------------- +; CPrnChr - print char to screen +; +; params: chr in A, $ff means no output +; affects: A +; uses: xVector +; +; The crsr ist turned off during +; operation (COff - COn) +; ------------------------------------- + +CPrnChr jsr COff + jsr PrnChr + jsr COn + rts + +; ------------------------------------- +; PrnChr - print char (petscii) to screen +; +; params: chr in A, $80 means no output +; affects: A +; uses: xVector +; +; Rem: The char π/~ is read from +; keyboard as $de but from screen +; (basic code, via input) as $ff. +; ------------------------------------- + +PrnChr sta xVector ; save char + txa ; save registers + pha + tya + pha + lda xVector ; restore char + + ; PETSCII to ScreenCode (SC) + ; -- $ff -- π/~ from keybd + cmp #$ff ; warn: reverse + bne PC_1 + lda #$de + jmp PCrvs + ; -- $e0-$fe -- upper graphics +PC_1 cmp #$e0 ; no output + bcc PC0 + jmp PCend + ; -- $c0-$df -- capital letters +PC0 cmp #$c0 + bcc PC1 + and #$7f + jmp PCrvs + ; -- $a0-$bf -- graphics/latin-9 +PC1 cmp #$a0 + bcc PC2 + and #$3f + ora #$40 + jmp PCrvs + ; -- $80-$9f -- upper control +PC2 cmp #$80 ; no output + bcc PC3 + jmp PCend + ; -- $60-$7f -- lower capital +PC3 cmp #$60 ; for string constants + bcc PC4 + and #$5f + jmp PCrvs + ; -- $40-$5f -- small letters +PC4 cmp #$40 + bcc PC5 + and #$1f + jmp PCrvs + ; -- $20-$3f -- numbers +PC5 cmp #$20 + bcc PC6 + jmp PCrvs + ; -- $00-$1f -- lower control +PC6 jmp PCend ; no output + + ; -- handle reverse mode -- +PCrvs ldx Rvs ; reverse mode? + beq PCput + eor #$80 ; reverse char + +PCput ldx lbPending ; need new line? + beq PC7 ; no -> skip + ldx #$00 ; clear pending + stx lbPending + jsr NewLn +PC7 ldy sCol ; get crsr col + sta (sLinePtr),y; char to screen + lda sColor ; get colour + sta (sLineColPtr),y ; set colour + + ; -- move on crsr -- + cpy #$27 ; col = 39? + bne PC8 ; no -> skip + lda #$ff ; yes -> set.. + sta lbPending ; ..pending + jmp PCend +PC8 iny ; move on crsr + sty sCol + +PCend pla ; restore registers + tay + pla + tax + rts + +; ------------------------------------- +; NewLn - move crsr to next line +; +; affects: X, Y +; +; --- INTERNAL --- +; subtask of PrnChr +; ------------------------------------- + +NewLn pha ; save char + ldx sRow ; get crsr row + cpx SRE ; end of scroll reg? + beq NL1 ; yes -> branche + cpx #$18 ; line 24? + beq NLend ; yes -> crsr stays + ; --- normal wrap --- + inx ; increase line + ldy #$00 ; begin of line + jsr Plot + jmp NLend + ; --- scroll up --- +NL1 jsr UScrl + ldy #$00 ; begin of line + sty sCol +NLend pla ; restore char + rts + +; ------------------------------------- +; DEL - move crsr to the left and +; delete char +; +; Can move through left margin. +; +; affects: A, X, Y +; ------------------------------------- + +DEL jsr COff + ldy sCol + lda lbPending + beq DEL1 + ; pending + jsr clPending + jmp DELe + +DEL1 dey + bmi DEL2 + ; middle of line + sty sCol + jmp DELe + +DEL2 ; first col + ldx sRow + beq DELee ; odd: top left corner + dex + ldy #39 + jsr Plot + ldy sCol + +DELe lda #" " ; clear char + sta (sLinePtr),y +DELee jsr COn + rts + +; ------------------------------------- +; clPending - clear pending flag +; +; affects: none +; +; Must be called in all crsr movement +; commands. +; ------------------------------------- + +clPending + pha + lda #$00 + sta lbPending + pla + rts + +; ------------------------------------- +; CUScrl - scroll up scrollregion +; +; affects: A, X, Y +; +; The crsr ist turned off during +; operation (COff - COn) +; ------------------------------------- + +CUScrl jsr COff + jsr UScrl + jsr COn + rts + +; ------------------------------------- +; UScrl - scroll up scrollregion +; +; affects: A, X, Y +; uses: xVector, yVector, +; zVector, wVector +; ------------------------------------- + +UScrl ldx SRS ; get first line + ; --- scroll one line --- +US1 ; -- new line: -- + ; -- zVector and wVector -- + jsr SLV + lda xVector ; screen line + ldy xVector+1 + sta zVector + sty zVector+1 + lda yVector ; colour line + ldy yVector+1 + sta wVector + sty wVector+1 + ; -- old line: -- + ; -- xVector and yVector + inx ; old line + jsr SLV + ; -- copy chars and colours -- + ldy #$27 ; col 39 +US2 lda (xVector),y ; copy char + sta (zVector),y + lda (yVector),y ; copy colour + sta (wVector),y + dey + bpl US2 + cpx SRE ; last line? + bne US1 ; no -> go on + jsr ErLn_ ; del last line + + rts + +; ------------------------------------- +; CDScrl - scroll down scrollregion +; +; affects: A, X, Y +; +; The crsr ist turned off during +; operation (COff - COn) +; ------------------------------------- + +CDScrl jsr COff + jsr DScrl + jsr COn + rts + +; ------------------------------------- +; DScrl - scroll down scrollregion +; +; affects: A, X, Y +; uses: xVector, yVector, +; zVector, wVector +; ------------------------------------- + +DScrl ldx SRE ; get last line + ; --- scroll one line --- +DS1 ; -- new line: -- + ; -- zVector and wVector -- + jsr SLV + lda xVector ; screen line + ldy xVector+1 + sta zVector + sty zVector+1 + lda yVector ; colour line + ldy yVector+1 + sta wVector + sty wVector+1 + ; -- old line: -- + ; -- xVector and yVector + dex ; old line + jsr SLV + ; -- copy chars ond colours -- + ldy #$27 ; col 39 +DS2 lda (xVector),y ; copy char + sta (zVector),y + lda (yVector),y ; copy colour + sta (wVector),y + dey + bpl DS2 + cpx SRS ; first line? + bne DS1 ; no -> go on + jsr ErLn_ ; del first line + + rts + +; ------------------------------------- +; ErLn - erase screen line +; +; params: line number in X +; affects: A, X, Y +; return: $20 (space) in A +; +; For internal use: +; ErLn_ needs line ptr in xVector +; and line colot ptr in yVector +; ------------------------------------- + +ErLn jsr SLV ; line start in xVector + ; col start in yVector + + ; -- erase chars -- +ErLn_ ldy #$27 ; col 39 + lda #$20 ; load space +EL1 sta (xVector),y ; clear char + dey + bpl EL1 + + ; -- set colour -- + ldy #$27 ; col 39 + lda #fVa ; load vanilla +EL2 sta (yVector),y ; clear char + dey + bpl EL2 + + rts + +; ------------------------------------- +; ErEnLn - erase to end of line +; +; affects: A, X, Y +; +; erase screen line from crsr to end of line +; ------------------------------------- + +ErEnLn + ; -- erase chars -- + ldy sCol ; get crsr col + lda #$20 ; load space +EEL1 sta (sLinePtr),y ; clear char + iny + cpy #$28 ; pos 40? + bne EEL1 ; next char + sta sCrsrChar ; del char .. + ; ..under crsr + ; -- set colour -- + ldy sCol ; get crsr col + lda #fVa ; load vanilla +EEL2 sta (sLineColPtr),y ; set colour + iny + cpy #$28 ; pos 40? + bne EEL2 ; next char + + rts + +; ------------------------------------- +; ErBeLn - erase from begin of line +; +; affects: A, X, Y +; +; erase screen line up to crsr +; ------------------------------------- + +ErBeLn + ; -- erase chars -- + ldy sCol ; get crsr col + lda #$20 ; load space +EBL1 sta (sLinePtr),y ; clear char + dey + bpl EBL1 ; pos>=0 -> next + sta sCrsrChar ; del char .. + ; ..under crsr + ; -- set colour -- + ldy sCol ; get crsr col + lda #fVa ; load vanilla +EBL2 sta (sLineColPtr),y ; clear char + dey + bpl EBL2 ; pos>=0 -> next + + rts + +; ------------------------------------- +; SLV - set line vectors +; --- INTERNAL --- +; +; params: line no in X +; affects: A, Y +; return: screen line ptr in xVector +; screen color ptr in yVector +; ------------------------------------- + +SLV lda $ecf0,x ; get lo byte + sta xVector + sta yVector + ; determin hi byte + ldy #Video ; hi byte + cpx #$07 ; line < 7? + bcc SLV1 + iny + cpx #$0d ; line < 13? + bcc SLV1 + iny + cpx #$14 ; line < 20? + bcc SLV1 + iny ; line 20-24 +SLV1 sty xVector+1 + tya + clc + adc #$d8-Video + sta yVector+1 + + rts + +; ************************************* +; * +; * Init routines +; * +; ************************************* + +; ------------------------------------- +; init memory +; +; ------------------------------------- + +InitVar lda #$00 + sta EMode + sta EBufL + sta SRS + sta Font + sta SaveF + sta SaveR + sta SaveRow + sta SaveCol + sta lbPending + sta civis + + lda #$18 ; last line + sta SRE ; = 24 + + rts + +; ------------------------------------- +; Init char +; +; at the end the font is apended. +; it is copied to $8800 and enabled +; +; uses: xVector, yVector, zVector +; ------------------------------------- + +; begin of reverse chars +Reverse = Char + $0400 + +InitChar +; enable font + sei + ldx #FontROM + stx zVector + sty zVector+1 + ldx #Char + stx yVector + sty yVector+1 + ldx #Reverse + stx xVector + sty xVector+1 + +; copy font + ldx #$04 ; copy 4 pages + ldy #$00 +IC1 lda (zVector),y + sta (yVector),y + eor #$ff ; reverse char + sta (xVector),y + iny + bne IC1 + ; switch to next page + inc zVector+1 + inc yVector+1 + inc xVector+1 + dex + bne IC1 + +; enable font + lda $dd00 + and #$fc + ora #$01 + sta $dd00 + lda $d018 + and #$f1 + ora #$02 + sta $d018 + lda #Video + sta VideoAddr + cli + rts + +; ------------------------------------- +; Exit char +; +; ------------------------------------- + +ExitChar +; disable font + sei + lda $dd00 + and #$fc + ora #$03 + sta $dd00 + lda $d018 + and #$f1 + ora #$04 + sta $d018 + lda #04 + sta VideoAddr + cli + rts + +; ------------------------------------- +; Init Screen +; +; ------------------------------------- + +InitScr + ; --- set background --- + lda #bgocolour + sta $d020 + lda #bgcolour + sta $d021 + ; --- disable Shift C= --- + lda #$80 + sta ShiftCFlag + ; --- erase screen --- + ldx #$18 ; start at ln 24 +IS1 txa + pha ; save X + jsr ErLn ; erase line + pla + tax ; restore X + dex ; previous line + bpl IS1 + lda #fVa ; load vanilla + sta sColor + ; --- put crsr --- + ldx #$00 + ldy #$00 + jsr Plot + + rts + +; ------------------------------------- +; Exit Screen +; +; ------------------------------------- + +ExitScr + ; --- set background --- + lda #$fe + sta $d020 + lda #$f6 + sta $d021 + ; --- ensable Shift C= --- + lda #$00 + sta ShiftCFlag + ; --- erase screen --- + lda #$fe + sta sColor + sta sCrsrCol + jsr $e544 + rts + +; ************************************* +; * +; * ASCII and PETSCII tables +; * +; ************************************* + +; ------------------------------------- +; table ASCII to PETSCII +; +; This tabel is used to convert incoming +; ASCII chars. +; +; pet=$00 means ignore the char +; pet=$01 do something complicated: C +; PETSCII and ASCII equal: = +; PETSCII and ASCII differ: / +; ------------------------------------- + +atp ;_0 _1 _2 _3 _4 _5 _6 _7 _8 _9 _a _b _c _d _e _f + +; --- Control chars ------------------------------------------------ +; NUL ACK BEL BS TAB LF CR +; C C C C C +.byt $00,$00,$00,$00,$00,$00,$00,$01,$01,$01,$01,$00,$00,$01,$00,$00 ; 0_ +; NAK ESC +; C +.byt $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01,$00,$00,$00,$00 ; 1_ + +; --- ASCII = PETSCII ---------------------------------------------- +; ' ' ! " # $ % & ' ( ) * + , - . / +.byt $20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2a,$2b,$2c,$2d,$2e,$2f ; 2_ +; 0 1 2 3 4 5 6 7 8 9 : ; < = > ? +.byt $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$3d,$3e,$3f ; 3_ + +; --- upper case letters ------------------------------------------- +; @ A B C D E F G H I J K L M N O +; = / / / / / / / / / / / / / / / +.byt $40,$c1,$c2,$c3,$c4,$c5,$c6,$c7,$c8,$c9,$ca,$cb,$cc,$cd,$ce,$cf ; 4_ +; P Q R S T U V W X Y Z [ \£ ] ^↑ _← +; / / / / / / / / / / / = = = = = +.byt $d0,$d1,$d2,$d3,$d4,$d5,$d6,$d7,$d8,$d9,$da,$5b,$5c,$5d,$5e,$5f ; 5_ + +; --- lower case letters ------------------------------------------- +; `━ a b c d e f g h i j k l m n o +; / / / / / / / / / / / / / / / / +.byt $c0,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4a,$4b,$4c,$4d,$4e,$4f ; 6_ +; p q r s t u v w x y z {╋ |▒ }┃ ~▒▒ DEL +; / / / / / / / / / / / / / / / +.byt $50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$5a,$db,$dc,$dd,$de,$00 ; 7_ + +; --- upper control codes --------------------------------------- +.byt $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ; 8_ +.byt $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ; 9_ + +; --- latin 9 chars --------------------------------------------- +; NBSP £ € (Š) § (š) © « - +.byt $20,$df,$df,$bf,$be,$df,$d3,$b5,$53,$bb,$df,$bc,$df,$2d,$df,$df ; a_ +; ° ± ² ³ (Ž) µ (ž) » Œ œ (Ÿ) +.byt $ba,$b8,$b6,$b7,$da,$b9,$df,$df,$5a,$df,$df,$bd,$b0,$b0,$d9,$df ; b_ +; À (Á)  (Ã) Ä Å (Ç) È É Ê (Ë) (Ì) (Í) (Î) (Ï) +.byt $a5,$c1,$a4,$c1,$a3,$a4,$df,$c3,$ad,$ab,$ac,$c5,$c9,$c9,$c9,$c9 ; c_ +; (Ð) (Ñ) (Ò) (Ó) Ô (Õ) Ö (Ø) (Ù) (Ú) (Û) Ü (Ý) ß +.byt $c4,$ce,$cf,$cf,$b1,$cf,$af,$df,$cf,$d5,$d5,$d5,$b3,$d9,$df,$b4 ; d_ +; à (á) â (ã) ä å ç è é ê ë (ì) (í) (î) (ï) +.byt $a2,$41,$a1,$41,$a0,$a1,$df,$a6,$aa,$a8,$a9,$a7,$49,$49,$49,$49 ; e_ +; (ñ) (ò) (ó) ô (õ) ö (ø) (ù) (ú) (û) ü (ý) (ÿ) +.byt $df,$4e,$4f,$4f,$b1,$4f,$ae,$df,$4f,$55,$55,$55,$b2,$59,$df,$59 ; f_ + +; ------------------------------------- +; table PETSCII to ASCII +; +; This table is used to prepare keyboard +; input for sending over the serial +; line. +; +; ascii = $00 means ignore key +; ascii = $ff menas send string +; ascii = $fe means do something +; complicated (command key) +; ------------------------------------- + +pta ;_0 _1 _2 _3 _4 _5 _6 _7 _8 _9 _a _b _c _d _e _f + +; --- Control chars ------------------------------------------------ +; {STOP} {RETURN} +; ^A ^B ^C ^D ^E ^F ^G ^H ^I ^J ^K ^L ^M ^N ^O +.byt $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0a,$0b,$0c,$0d,$0e,$0f ; 0_ +; {crsr↓} {HOME|DEL} {crsr→} +; ^P ^Q ^R ^S ^T ^U ^V ^W ^X ^Y ^Z ^[ ^\£ ^] ^↑ +.byt $10,$fe,$12,$fe,$fe,$15,$16,$17,$18,$19,$1a,$1b,$1c,$fe,$1e,$1f ; 1_ + +; --- ASCII = PETSCII ---------------------------------------------- +; ' ' ! " # $ % & ' ( ) * + , - . / +.byt $20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2a,$2b,$2c,$2d,$2e,$2f ; 2_ +; 0 1 2 3 4 5 6 7 8 9 : ; < = > ? +.byt $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$3d,$3e,$3f ; 3_ + +; --- lower case letters ------------------------------------------- +; @ a b c d e f g h i j k l m n o +; = / / / / / / / / / / / / / / / +.byt $40,$61,$62,$63,$64,$65,$66,$67,$68,$69,$6a,$6b,$6c,$6d,$6e,$6f ; 4_ +; p q r s t u v w x y z [ \£ ] ^↑ ← +; / / / / / / / / / / / = = = = ESC +.byt $70,$71,$72,$73,$74,$75,$76,$77,$78,$79,$7a,$5b,$5c,$5d,$5e,$1b ; 5_ + +; --- mirror of upper letters - should never appear ---------------- +.byt $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ; 6_ +.byt $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ; 7_ + +; --- upper control chars ------------------------------------------ +; {f1}{f3}{f5}{f7}{f2}{f4}{f6}{f8}{ShRET} +; +.byt $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ; 8_ +; {crsr↑} {CLR}{INS} {crsr←} +; DEL +.byt $00,$ff,$00,$00,$7f,$00,$00,$00,$00,$00,$00,$00,$00,$ff,$00,$00 ; 9_ + +; --- block graphics ----------------------------------------------- +; ShSP C=K C=I C=T C=@ C=G C=+ C=M C=£ Sh£ C=N C=Q C=D C=Z C=S C=P +; | +.byt $00,$00,$00,$00,$00,$00,$00,$00,$00,$7c,$00,$fe,$00,$00,$00,$00 ; a_ +; C=A C=E C=R C=W C=H C=J C=L C=Y C=U C=O Sh@ C=F C=C C=X C=V C=B +; ` +.byt $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$60,$00,$00,$00,$00,$00 ; b_ + +; --- capital letters ---------------------------------------------- +; Sh* A B C D E F G H I J K L M N O +; _ / / / / / / / / / / / / / / / +.byt $5f,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4a,$4b,$4c,$4d,$4e,$4f ; c_ +; P Q R S T U V W X Y Z Sh+ C=- Sh- π C=* +; / / / / / / / / / / / { } ~ +.byt $50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$5a,$7b,$00,$7d,$7e,$00 ; d_ + +; --- mirror of block graphics - should never appear --------------- +.byt $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ; e_ +.byt $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ; f_ + +; --- Font ROM ------------------------ + +FontROM +.incbin "c64vt100font.bin" diff --git a/drivers/vic20vt100.s b/drivers/vic20vt100.s new file mode 100644 index 0000000..2ab9acb --- /dev/null +++ b/drivers/vic20vt100.s @@ -0,0 +1,6 @@ +.export vt100_init_terminal = $1000 +.export vt100_exit_terminal = $1000 +.export vt100_process_inbound_char = $1000 +.export vt100_process_outbound_char = $1000 +.exportzp vt100_screen_cols = 22 +.exportzp vt100_screen_rows = 23 diff --git a/ip65/Makefile b/ip65/Makefile index 058ef1c..5607205 100644 --- a/ip65/Makefile +++ b/ip65/Makefile @@ -30,7 +30,6 @@ IP65OBJS=\ printf.o \ sntp.o \ string_utils.o \ - telnet.o \ udp.o \ url.o