From 3359061ce2f86f585ba989d98b8187ee13859b3e Mon Sep 17 00:00:00 2001 From: Oliver Schmidt Date: Fri, 19 May 2017 00:12:42 +0200 Subject: [PATCH] Added Telnet65 app. The file telnet.s in the 'ip65' directory for sure wasn't belonging into a library as it contained a main loop. So I introduced an 'apps' directory for actual apps coming with IP65. The file telnet.s was moved to apps, renamed telnet65.s and heavily modified. The file c64vt100.s was made up from several files taken from CaTer (www.opppf.de/Cater) and adjusted for the new use case. The was done before for KIPPERTERM. However this time I deliberately avoided unnecessary code reformatting to allow for as easy as possible integration of potential upcoming changes in CaTer. The file a2vt100.s was copied from c64vt100.s and adjusted to the monochrome 80 column screen of the Apple //e. Again unnecessary code changes were avoided to allow to easily merge upcoming changes from c64vt100.s. The files atrvt100.s and vic20vt100.s are for now just dummies to allow to successfully link Telnet65. Work for an actually functional Telnet65 would start with a copy of c64vt100.s (as it was done with a2vt100.s). --- apps/Makefile | 109 ++ ip65/telnet.s => apps/telnet65.s | 431 ++++--- drivers/Makefile | 4 + drivers/a2vt100.s | 1529 +++++++++++++++++++++++ drivers/atrvt100.s | 6 + drivers/c64vt100.s | 1937 ++++++++++++++++++++++++++++++ drivers/vic20vt100.s | 6 + ip65/Makefile | 1 - 8 files changed, 3861 insertions(+), 162 deletions(-) create mode 100644 apps/Makefile rename ip65/telnet.s => apps/telnet65.s (55%) create mode 100644 drivers/a2vt100.s create mode 100644 drivers/atrvt100.s create mode 100644 drivers/c64vt100.s create mode 100644 drivers/vic20vt100.s 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