├── test ├── .gitignore ├── echo.sh ├── charset.sh ├── fastout.sh ├── slowout.sh ├── echo.c ├── slowout.c ├── inout.h ├── charset.c ├── fastout.c ├── xfer.sh ├── crc16.h ├── xfer.c ├── crc16.c └── xmodem.c ├── ccgms_40.png ├── ccgms_80.png ├── .gitignore ├── .gitmodules ├── src ├── instrprint.s ├── encoding.inc ├── ccgmsterm.cfg ├── filetype.s ├── sound.s ├── misc.s ├── cursor.s ├── outstr.s ├── ccgmsterm.s ├── reu.s ├── configldsv.s ├── macroex.s ├── screens.s ├── instr.s ├── disk.s ├── config.s ├── theme.s ├── input.s ├── easyflash.s ├── diskcmd.s ├── misc2.s ├── dir.s ├── buffer2.s ├── declare.inc ├── ansi.s ├── init.s ├── banner.s ├── macro.s ├── configedit.s ├── terminal.s ├── xfer.s ├── multixfer.s └── buffer.s ├── rs232lib ├── rs232_kernal.inc ├── c64.inc ├── rs232.inc ├── README.md ├── rs232.s ├── rs232_userport.s ├── rs232_swiftlink.s └── rs232_up9600.s ├── .github └── workflows │ └── ci.yml ├── Testing.md ├── Internals.md ├── LICENSE.txt ├── Makefile ├── README.md └── Documentation.md /test/.gitignore: -------------------------------------------------------------------------------- 1 | xfer 2 | echo 3 | fastout 4 | slowout 5 | charset 6 | -------------------------------------------------------------------------------- /ccgms_40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mist64/ccgmsterm/HEAD/ccgms_40.png -------------------------------------------------------------------------------- /ccgms_80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mist64/ccgmsterm/HEAD/ccgms_80.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.map 3 | *.sym 4 | *.prg 5 | *.d64 6 | build 7 | test/slowout 8 | test/xmodem 9 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "exomizer"] 2 | path = exomizer 3 | url = https://bitbucket.org/magli143/exomizer/ 4 | -------------------------------------------------------------------------------- /test/echo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | cc -o echo echo.c 5 | 6 | socat -d -d tcp-l:25232,fork,reuseaddr system:"./echo" 7 | -------------------------------------------------------------------------------- /test/charset.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | cc -o charset charset.c 5 | 6 | socat -d -d tcp-l:25232,fork,reuseaddr system:"./charset" 7 | -------------------------------------------------------------------------------- /test/fastout.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | cc -o fastout fastout.c 5 | 6 | socat -d -d tcp-l:25232,fork,reuseaddr system:"./fastout" 7 | -------------------------------------------------------------------------------- /test/slowout.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | cc -o slowout slowout.c 5 | 6 | socat -d -d tcp-l:25232,fork,reuseaddr system:"./slowout" 7 | -------------------------------------------------------------------------------- /test/echo.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "inout.h" 6 | 7 | int 8 | main(int argc, char **argv) { 9 | while (!feof(stdin)) { 10 | int c = _inbyte(0); 11 | _outbyte(c); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/slowout.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "inout.h" 6 | 7 | int 8 | main(int argc, char **argv) { 9 | char c = 'A'; 10 | for (;;) { 11 | _outbyte(c); 12 | sleep(1); 13 | c++; 14 | if (c == 'Z' + 1) { 15 | c = 'A'; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /test/inout.h: -------------------------------------------------------------------------------- 1 | int 2 | _inbyte(unsigned short timeout) { 3 | int c = fgetc(stdin); 4 | fprintf(stderr, "***** SERVER: <--- %02X\n", (unsigned char)c); 5 | return c; 6 | } 7 | 8 | void 9 | _outbyte(int c) { 10 | fprintf(stderr, "***** SERVER: ---> %02X\n", (unsigned char)c); 11 | fputc(c, stdout); 12 | fflush(stdout); 13 | } 14 | 15 | -------------------------------------------------------------------------------- /test/charset.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "inout.h" 6 | 7 | int 8 | main(int argc, char **argv) { 9 | unsigned char c = 0x20; 10 | for (;;) { 11 | if ((c & 0x1f) == 0) { 12 | fputc(13, stdout); 13 | fflush(stdout); 14 | } 15 | fputc(c, stdout); 16 | c++; 17 | if (c > 0x7f) { 18 | c = 0x20; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/instrprint.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2020, Craig Smith, alwyz. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; Show instructions and credits 7 | ; 8 | 9 | show_instructions: 10 | lda #txt_instructions1 12 | jsr outstr 13 | jsr @wait 14 | lda #txt_instructions2 16 | jsr outstr 17 | @wait: jsr getin 18 | beq @wait 19 | rts 20 | -------------------------------------------------------------------------------- /test/fastout.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "inout.h" 6 | 7 | int 8 | main(int argc, char **argv) { 9 | char l = 'A'; 10 | char c = '0'; 11 | for (;;) { 12 | fputc(l, stdout); 13 | fputc(c, stdout); 14 | c++; 15 | if (c > '9') { 16 | fputc(13, stdout); 17 | fflush(stdout); 18 | l++; 19 | if (l > 'Z') { 20 | l = 'A'; 21 | } 22 | c = '0'; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /rs232lib/rs232_kernal.inc: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2022, Craig Smith, alwyz, Michael Steil. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; RS232 Driver Internal Include 7 | ; 8 | 9 | ; KERNAL 10 | STATUS = $90 11 | RIDBE = $029b 12 | RIDBS = $029c 13 | RODBS = $029d 14 | RODBE = $029e 15 | ENABL = $02a1 16 | rtail = RIDBE ; friendlier name 17 | rhead = RIDBS ; friendlier name 18 | rfree = RODBS ; re-purposed; SwiftLink only 19 | 20 | JIFFIES = $a2 ; TIME+2 21 | -------------------------------------------------------------------------------- /src/encoding.inc: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2020, Craig Smith, alwyz. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; Text encoding macros 7 | ; 8 | 9 | ; correct mapping for [A-Za-z]; no other mappings (unlike ca65 -t c64) 10 | .macro SET_PETSCII 11 | .repeat 26, i 12 | .charmap i+$41, i+$c1 13 | .endrepeat 14 | .repeat 26, i 15 | .charmap i+$61, i+$41 16 | .endrepeat 17 | .endmacro 18 | 19 | ; 1:1 mapping 20 | .macro SET_ASCII 21 | .repeat $100, i 22 | .charmap i, i 23 | .endrepeat 24 | .endmacro 25 | -------------------------------------------------------------------------------- /rs232lib/c64.inc: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2022, Craig Smith, alwyz, Michael Steil. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; C64 Hardware Constants 7 | ; 8 | 9 | ; CIA#1 I/O 10 | cia1talo = $dc04 11 | cia1tahi = $dc05 12 | cia1tblo = $dc06 13 | cia1tbhi = $dc07 14 | cia1sdr = $dc0c 15 | cia1icr = $dc0d 16 | cia1cra = $dc0e 17 | cia1crb = $dc0f 18 | ; CIA#2 I/O 19 | cia2pa = $dd00 20 | cia2pb = $dd01 21 | cia2ddrb = $dd03 22 | cia2tblo = $dd06 23 | cia2tbhi = $dd07 24 | cia2sdr = $dd0c 25 | cia2icr = $dd0d 26 | cia2crb = $dd0f 27 | -------------------------------------------------------------------------------- /rs232lib/rs232.inc: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2022, Craig Smith, alwyz, Michael Steil. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; RS232 Driver Include 7 | ; 8 | 9 | MODEM_TYPE_USERPORT = 0 10 | MODEM_TYPE_UP9600 = 1 11 | MODEM_TYPE_SWIFTLINK_DE = 2 12 | MODEM_TYPE_SWIFTLINK_DF = 3 13 | MODEM_TYPE_SWIFTLINK_D7 = 4 14 | 15 | BAUD_300 = 0 16 | BAUD_1200 = 1 17 | BAUD_2400 = 2 18 | BAUD_4800 = 3 19 | BAUD_9600 = 4 20 | BAUD_19200 = 5 21 | BAUD_38400 = 6 22 | 23 | ; API 24 | .global rs232_init 25 | .global rs232_on 26 | .global rs232_off 27 | .global rs232_get 28 | .global rs232_put 29 | .global rs232_dropdtr 30 | .global rs232_clear 31 | -------------------------------------------------------------------------------- /src/ccgmsterm.cfg: -------------------------------------------------------------------------------- 1 | # CCGMS Terminal 2 | # 3 | # Copyright (c) 2016,2020, Craig Smith, alwyz. All rights reserved. 4 | # This project is licensed under the BSD 3-Clause License. 5 | # 6 | # ld65 cfg 7 | # 8 | 9 | MEMORY { 10 | HEADER: start = $07FF, size = $0002, fill = yes; 11 | CODE: start = $0801, size = $97FF, fill = no; 12 | } 13 | 14 | SEGMENTS { 15 | HEADER: load = HEADER, type = ro; 16 | CODE: load = CODE, type = ro; 17 | RS232: load = CODE, type = ro; 18 | END: load = CODE, type = ro; # empty, used for "endprg" symbol only 19 | # Everything beyond this point is purgeable, i.e. CCGMS 20 | # will put the buffer here and overwrite what was there. 21 | CHARSET:load = CODE, type = ro; 22 | } 23 | -------------------------------------------------------------------------------- /src/filetype.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2020, Craig Smith, alwyz. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; File type prompt 7 | ; 8 | 9 | ;---------------------------------------------------------------------- 10 | txt_prg_seq_usr: 11 | .byte HILITE,"PRG, ",HILITE,"SEQ, or ",HILITE,"USR? ",0 12 | 13 | ;---------------------------------------------------------------------- 14 | ; prompt user about CBM DOS file type 15 | prompt_file_type: 16 | lda #txt_prg_seq_usr 18 | jsr outstr 19 | jsr invert_csr_char 20 | 21 | @1: jsr getin 22 | beq @1 23 | and #$7f 24 | ldx #3 25 | @2: cmp upltyp,x 26 | beq @3 27 | dex 28 | bne @2 29 | beq @1 30 | 31 | @3: stx filetype 32 | rts 33 | -------------------------------------------------------------------------------- /test/xfer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # XMODEM/PUNTER Test Program 5 | # 6 | # See "make test". 7 | # 8 | # It should print: 9 | # ***** TEST_XFER: PUNTER OK 10 | # ***** TEST_XFER: XMODEM; client: XMODEM, server: 512B/CHKSUM: OK 11 | # ***** TEST_XFER: XMODEM; client: XMODEM, server: 1KB/CRC16: OK 12 | # ***** TEST_XFER: XMODEM; client: XMODEM-CRC, server: 512B/CHKSUM: OK 13 | # ***** TEST_XFER: XMODEM; client: XMODEM-CRC, server: 1KB/CRC16: OK 14 | # ***** TEST_XFER: XMODEM; client: XMODEM-1K, server: 512B/CHKSUM: OK 15 | # ***** TEST_XFER: XMODEM; client: XMODEM-1K, server: 1KB/CRC16: OK 16 | # ***** TEST_XFER: Succeeded! 17 | 18 | set -e 19 | 20 | cc -o xfer xfer.c xmodem.c crc16.c punter.c 21 | 22 | #socat -d -d tcp-l:25232,fork,reuseaddr system:"./xfer" 23 | socat -d -d tcp-l:25232,reuseaddr system:"./xfer" 24 | -------------------------------------------------------------------------------- /src/sound.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2020, Craig Smith, alwyz. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; Sounds 7 | ; 8 | 9 | ;---------------------------------------------------------------------- 10 | bell: 11 | ldx #9 12 | stx $D413 13 | ldx #0 14 | stx $D414 15 | ldx #$40 16 | stx $D40F 17 | ldx #0 18 | stx $D412 19 | ldx #$11 20 | stx $D412 21 | rts 22 | 23 | ;---------------------------------------------------------------------- 24 | gongm1: 25 | .byte 24,6,13,20,4,11,18,15,8,1,5,19,12,14,7,0,4,11,18,24 26 | gongm2: 27 | .byte 47,0,0,0,0,0,0,4,8,16,13,13,11,28,48,68,21,21,21,15 28 | ; [XXX it's shorter to just store 25 bytes and write them backwards into the SID] 29 | 30 | gong: 31 | pha 32 | ldx #0 33 | : lda gongm1,x 34 | tay 35 | lda gongm2,x 36 | sta $d400,y 37 | inx 38 | cpx #20 39 | bcc :- 40 | pla 41 | rts 42 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | push: 5 | pull_request: 6 | release: 7 | types: [published] 8 | check_suite: 9 | types: [rerequested] 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v2 17 | with: 18 | submodules: true 19 | 20 | - name: install deps 21 | run: sudo apt install cc65 22 | 23 | - name: build CCGMS 24 | run: | 25 | make -j$(nproc) EXOMIZER=1 26 | cp build/ccgmsterm-exo.prg ccgms.prg 27 | 28 | - name: build CCGMS (EASYFLASH version) 29 | run: | 30 | make -j$(nproc) EASYFLASH=1 EXOMIZER=1 31 | cp build/ccgmsterm-exo.prg ccgms-easyflash.prg 32 | 33 | - uses: actions/upload-artifact@v2 34 | with: 35 | name: artifacts 36 | path: | 37 | *.prg 38 | 39 | - name: Create release 40 | if: startsWith(github.ref, 'refs/tags/') 41 | uses: softprops/action-gh-release@v1 42 | with: 43 | files: | 44 | *.prg 45 | fail_on_unmatched_files: true 46 | body: "Automatically created release" 47 | -------------------------------------------------------------------------------- /src/misc.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2020, Craig Smith, alwyz. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; Miscellaneous 1 7 | ; 8 | 9 | ;---------------------------------------------------------------------- 10 | text_color_save: 11 | ldx textcl 12 | stx tmp04 13 | ;---------------------------------------------------------------------- 14 | text_color_set: 15 | ldx #TCOLOR 16 | stx textcl 17 | rts 18 | ;---------------------------------------------------------------------- 19 | text_color_restore: 20 | ldx tmp04 21 | stx textcl 22 | rts 23 | 24 | ;---------------------------------------------------------------------- 25 | handle_f6_directory: 26 | jsr col80_pause 27 | lda #1 28 | ldx #dirfn 30 | dodir: 31 | jsr setnam 32 | jsr dir 33 | jsr rs232_on 34 | jsr col80_wait 35 | jmp term_mainloop 36 | 37 | ;---------------------------------------------------------------------- 38 | handle_f8_switch_term: 39 | ldx SHFLAG 40 | cpx #SHFLAG_CBM 41 | jeq cf7_screen_to_buffer 42 | 43 | lda ascii_mode 44 | eor #1 45 | sta ascii_mode 46 | php 47 | jsr col80_set_charset 48 | plp 49 | bne :+ 50 | jsr term80_toggle 51 | : jsr bell 52 | jmp term_entry 53 | 54 | ;---------------------------------------------------------------------- 55 | toggle_cursor: ; [XXX unused] 56 | jsr cursor_off 57 | lda cursor_flag 58 | eor #1 59 | sta cursor_flag 60 | jmp term_mainloop 61 | -------------------------------------------------------------------------------- /src/cursor.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2020, Craig Smith, alwyz. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; Cursor logic 7 | ; 8 | 9 | .import col80_invert, col80_restore 10 | 11 | ;---------------------------------------------------------------------- 12 | ; invert character at cursor position 13 | invert_csr_char: 14 | bit col80_active 15 | bpl :+ 16 | jmp col80_invert 17 | 18 | : jsr calc_scr_ptr 19 | sta tempch 20 | eor #$80 21 | sta (locat),y ; invert character 22 | jsr calc_col_ptr 23 | sta tempcl 24 | lda textcl 25 | sta (locat),y ; set current color 26 | rts 27 | 28 | ;---------------------------------------------------------------------- 29 | ; restore char at cursor position 30 | restore_csr_char: 31 | bit col80_active 32 | bpl :+ 33 | jmp col80_restore 34 | 35 | : jsr calc_scr_ptr 36 | lda tempch 37 | sta (locat),y 38 | jsr calc_col_ptr 39 | lda tempcl 40 | sta (locat),y 41 | rts 42 | 43 | ;---------------------------------------------------------------------- 44 | ; clear character at cursor position 45 | clear_csr_char: 46 | lda #' ' 47 | jsr chrout 48 | lda #CSR_LEFT 49 | jmp chrout 50 | 51 | ;---------------------------------------------------------------------- 52 | cursor_off: 53 | ldx cursor_flag 54 | bne restore_csr_char 55 | jsr quote_insert_off 56 | jmp clear_csr_char 57 | 58 | ;---------------------------------------------------------------------- 59 | cursor_show: 60 | lda cursor_flag 61 | bne :+ 62 | lda #CURSOR 63 | jsr chrout 64 | lda #CSR_LEFT 65 | jmp chrout 66 | : jmp invert_csr_char 67 | -------------------------------------------------------------------------------- /src/outstr.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2020, Craig Smith, alwyz. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; String output 7 | ; 8 | 9 | ;---------------------------------------------------------------------- 10 | outstr: 11 | sty zpoutstr+1 12 | sta zpoutstr 13 | ldy #0 14 | @loop: lda (zpoutstr),y 15 | beq @rts 16 | cmp #HILITE 17 | beq @hilite 18 | cmp #3 19 | bne @skip 20 | 21 | ; set cursor pos 22 | iny 23 | lda (zpoutstr),y ; [XXX should use PLOT] 24 | sta LINE 25 | lda #CR 26 | jsr chrout 27 | lda #CSR_UP 28 | jsr chrout 29 | iny 30 | lda (zpoutstr),y 31 | sta COLUMN 32 | bne @outst4 33 | 34 | @skip: cmp #'A'+$80 35 | bcc @outst3 36 | cmp #'Z'+1+$80 37 | bcs @outst3 38 | jsr get_charset 39 | php 40 | lda (zpoutstr),y 41 | plp 42 | bne @outst3 43 | and #$7f 44 | @outst3: 45 | jsr chrout 46 | @outst4: 47 | iny 48 | bne @loop 49 | inc zpoutstr+1 50 | bne @loop 51 | @rts: rts 52 | 53 | @hilite: 54 | lda textcl 55 | pha 56 | lda #1 57 | sta textcl 58 | lda #RVSON 59 | jsr chrout 60 | lda #$a1 ; '▌' LEFT HALF BLOCK 61 | jsr chrout 62 | jsr get_charset 63 | php 64 | iny 65 | lda (zpoutstr),y 66 | plp 67 | beq :+ 68 | ora #$80 69 | : jsr chrout 70 | lda #$B6 ; $B6: RIGHT THREE EIGHTHS BLOCK 71 | jsr chrout 72 | pla 73 | sta textcl 74 | lda #RVSOFF 75 | bne @outst3 76 | ;---------------------------------------------------------------------- 77 | outcap: 78 | cmp #'A'+$80 79 | bcc @2 80 | cmp #'Z'+1+$80 81 | bcs @2 82 | pha 83 | jsr get_charset 84 | beq @1 85 | pla 86 | bne @2 87 | @1: pla 88 | and #$7f 89 | @2: jmp chrout 90 | -------------------------------------------------------------------------------- /test/crc16.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2001-2010 Georges Menie (www.menie.org) 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the University of California, Berkeley nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _CRC16_H_ 29 | #define _CRC16_H_ 30 | 31 | unsigned short crc16_ccitt(const void *buf, int len); 32 | 33 | #endif /* _CRC16_H_ */ 34 | -------------------------------------------------------------------------------- /Testing.md: -------------------------------------------------------------------------------- 1 | # CCGMS Testing 2 | 3 | ## Transfer Test 4 | 5 | The commands 6 | 7 | make testup # User Port 8 | make testsw # SwiftLink/DE 9 | 10 | will build CCGMS with automation support and run an automated test in VICE for all file transfer protocols and their combinations. 11 | 12 | It should print 13 | 14 | ***** TEST_XFER: PUNTER OK 15 | ***** TEST_XFER: XMODEM; client: XMODEM, server: 512B/CHKSUM: OK 16 | ***** TEST_XFER: XMODEM; client: XMODEM, server: 1KB/CRC16: OK 17 | ***** TEST_XFER: XMODEM; client: XMODEM-CRC, server: 512B/CHKSUM: OK 18 | ***** TEST_XFER: XMODEM; client: XMODEM-CRC, server: 1KB/CRC16: OK 19 | ***** TEST_XFER: XMODEM; client: XMODEM-1K, server: 512B/CHKSUM: OK 20 | ***** TEST_XFER: XMODEM; client: XMODEM-1K, server: 1KB/CRC16: OK 21 | ***** TEST_XFER: Succeeded! 22 | 23 | You will have to quit VICE manually after the test has finished. 24 | 25 | The tests uses the respective driver at 2400 baud and takes about 5 minutes. You can speed it up using warp mode. UP9600 has to be tested on real hardware. Refer to the Makefile on how to run the `xfer.sh` server. 26 | 27 | ## Echo 28 | 29 | This test echos all input. Run the server like this: 30 | 31 | cd test 32 | sh echo.sh 33 | 34 | Running any of these 35 | 36 | make runup # User Port 37 | make runup9600 # UP9600 38 | make runsw # SwiftLink/DE 39 | 40 | will connect to the server. 41 | 42 | ## Slowout 43 | 44 | This test server prints characters slowly. 45 | 46 | cd test 47 | sh slowout.sh 48 | 49 | ## Fastout 50 | 51 | This test server prints characters at the full data rate. 52 | 53 | cd test 54 | sh fastout.sh 55 | 56 | It can easily overflow the 256 byte CCGMS input buffer if printing cannot keep up. The pattern printed makes it easy to see when characters are dropped. 57 | -------------------------------------------------------------------------------- /Internals.md: -------------------------------------------------------------------------------- 1 | # CCGMS Internals 2 | 3 | Here are some details that will help with development. 4 | 5 | ## Memory Map 6 | 7 | * Low 8 | 9 | | Range | Use | 10 | |-------------|------------------------------------------| 11 | | $0380-$03FF | UP9600 byte reversal table | 12 | | $0400-$05FF | Punter buffers (screen RAM!) | 13 | 14 | * High 15 | 16 | | Range | Use | Alt use | 17 | |-------------|------------------------------------------|-----------------------| 18 | | $C800-$CAFF | | XMODEM buffer | 19 | | $CB00-$CBFF | Multi-Punter buffer | XMODEM buffer (cont.) | 20 | | $CC00-$CCFF | buffer to save return text from dialing | CRC table lo | 21 | | $CD00-$CDFF | Punter temporary vars | CRC table hi | 22 | | $CE00-$CEFF | RS-232 input buffer | | 23 | | $CF00-$CFFF | text input buffer | | 24 | 25 | * 40 column mode: 26 | 27 | | Range | Use | 28 | |-------------|------------------------------------------| 29 | | $D000-$DFFF | unused | 30 | | $E000-$FFCF | screen snapshots | 31 | 32 | * 80 column mode: 33 | 34 | | Range | Use | 35 | |-------------|------------------------------------------| 36 | | $D000-$D3FF | 4x8 charset | 37 | | $D400-$D7E7 | 40x25 "screen memory" holding the colors | 38 | | $D800-$DFCF | logical 80x25 screen RAM | 39 | | $E000-$FE3F | bitmap | 40 | 41 | ## Banking 42 | 43 | CCGMS runs with $01 = $37. Whenever you want to turn off the KERNAL ROM, you need to store #$34 in $01. This is effectively the same as #$30, but allows the timing-critical UP9600 code to switch I/O on and off with `inc $01` and `dec $01`. -------------------------------------------------------------------------------- /src/ccgmsterm.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2022, Craig Smith, alwyz, Michael Steil. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; Main .s file 7 | ; 8 | 9 | .feature labels_without_colons 10 | .feature string_escapes 11 | .macpack longbranch 12 | 13 | ; RS232 driver API 14 | .include "../rs232lib/rs232.inc" 15 | ; symbols required by rs232lib 16 | .export modem_type, baud_rate, is_pal_system ; modem settings 17 | .export ribuf, revtabup ; buffer, temp storage 18 | 19 | ; 80columns 20 | .import col80_init, col80_set_charset, col80_on, col80_off, col80_resume, col80_pause 21 | .import col80_wait 22 | .import col80_active, col80_bg_update 23 | .import col80_read_scr_chr, col80_read_scr_col 24 | .export locat, nlocat ; for 80col 25 | 26 | .define VERSION "0.2" 27 | 28 | .include "declare.inc" 29 | .include "encoding.inc" 30 | 31 | .segment "HEADER" 32 | .word $0801 ; PRG load address 33 | 34 | .segment "CODE" 35 | 36 | .word next_line 37 | easyflash_support: ; encode EasyFlash support into the BASIC line number 38 | .word EASYFLASH ; 0 SYS2061 -> no EasyFlash; 1 SYS2061 -> EasyFlash 39 | .byte $9e,"2061" 40 | .word 0 41 | next_line: 42 | .byte 0 43 | 44 | .assert * = 2061, error 45 | .assert * = start, error 46 | .include "init.s" 47 | .include "terminal.s" 48 | .include "sound.s" 49 | .include "screens.s" 50 | .include "banner.s" 51 | .include "dir.s" 52 | .include "ansi.s" 53 | .include "cursor.s" 54 | .include "input.s" 55 | .include "misc.s" 56 | .include "diskcmd.s" 57 | .include "macroex.s" 58 | .include "buffer2.s" 59 | .include "xmodem.s" 60 | .include "xfer.s" 61 | .include "disk.s" 62 | .include "outstr.s" 63 | .include "multixfer.s" 64 | .include "buffer.s" 65 | .include "phonebook.s" 66 | .include "configldsv.s" 67 | .include "instrprint.s" 68 | .include "macro.s" 69 | .include "configedit.s" 70 | .include "reu.s" 71 | .include "theme.s" 72 | .include "config.s" 73 | .include "easyflash.s" 74 | .include "instr.s" 75 | .include "punter.s" 76 | .include "misc2.s" 77 | 78 | .segment "END" ; empty segment guaranteed by .cfg to be at the end 79 | endprg: 80 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | CCGMS Term, the Commodore Color Graphics Manipulation Systerm Terminal. 2 | 3 | Copyright (c) 2016,2022, Craig Smith, alwyz, Michael Steil 4 | All rights reserved. 5 | 6 | This project is licensed under the BSD 3-Clause License (see below). 7 | 8 | You are further kindly requested, but not required, to notify the 9 | original author if you make and distribute a significant modification of 10 | the project in a manner other than via the public source code repository 11 | at https://github.com/spathiwa/ccgmsterm. (Obtain contact info by 12 | clicking on the 'spathiwa' owner link on the repository page. I'd just 13 | like to hear what people are doing with it.) 14 | 15 | 16 | [BSD 3-Clause License] 17 | 18 | Redistribution and use in source and binary forms, with or without 19 | modification, are permitted provided that the following conditions are met: 20 | 21 | * Redistributions of source code must retain the above copyright notice, this 22 | list of conditions and the following disclaimer. 23 | 24 | * Redistributions in binary form must reproduce the above copyright notice, 25 | this list of conditions and the following disclaimer in the documentation 26 | and/or other materials provided with the distribution. 27 | 28 | * Neither the name of the copyright holder nor the names of its 29 | contributors may be used to endorse or promote products derived from 30 | this software without specific prior written permission. 31 | 32 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 33 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 34 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 35 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 36 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 38 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 39 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 40 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 41 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 42 | -------------------------------------------------------------------------------- /src/reu.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2020, Craig Smith, alwyz. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; REU Support 7 | ; 8 | ; Only uses first bank; 64 KB is more than enough 9 | 10 | ;---------------------------------------------------------------------- 11 | ; REU in use 12 | ; 0: no (RAM buffers) 13 | ; 1: yes (REU buffers) 14 | reu_enabled: 15 | .byte 0 16 | 17 | ;---------------------------------------------------------------------- 18 | ; detect REU 19 | reu_detect: 20 | ; enable this to temporarily disable REU support 21 | ;jmp noreu 22 | 23 | ldx #2 24 | : txa 25 | sta $df00,x 26 | inx 27 | cpx #6 28 | bne :- 29 | 30 | ldx #2 31 | : txa 32 | cmp $df00,x 33 | bne noreu 34 | inx 35 | cpx #6 36 | bne :- 37 | 38 | lda #1 39 | sta reu_enabled 40 | lda #0 ; set buffer start 41 | sta newbuf 42 | sta newbuf+1 43 | sta buffst 44 | sta buffst+1 45 | sta buffer_ptr 46 | sta buffer_ptr+1 47 | lda #$ff 48 | sta bufend 49 | sta bufend+1 50 | rts 51 | 52 | ;---------------------------------------------------------------------- 53 | noreu: 54 | lda #0 55 | sta reu_enabled 56 | lda #endprg 59 | sta buffst+1 60 | lda #buftop 63 | sta bufend+1 64 | rts 65 | 66 | ;---------------------------------------------------------------------- 67 | bufend: 68 | .word 0 69 | 70 | ;read/write to from reu 71 | 72 | length = 1 ; one byte at a time 73 | 74 | ;---------------------------------------------------------------------- 75 | reuwrite: 76 | sta bufptrreu 77 | pha 78 | lda #bufptrreu 81 | sta $df03 82 | lda buffer_ptr 83 | sta $df04 84 | lda buffer_ptr+1 85 | sta $df05 86 | lda #0 87 | sta $df06 88 | lda #length 91 | sta $df08 92 | lda #0 93 | sta $df0a 94 | lda #$b0 95 | sta $df01 96 | pla 97 | rts 98 | 99 | ;---------------------------------------------------------------------- 100 | reuread: 101 | lda #buffstreu 104 | sta $df03 105 | lda buffst 106 | sta $df04 107 | lda buffst+1 108 | sta $df05 109 | lda #0 110 | sta $df06 111 | lda #length 114 | sta $df08 115 | lda #0 116 | sta $df0a 117 | lda #$b1 118 | sta $df01 119 | lda buffstreu 120 | rts 121 | -------------------------------------------------------------------------------- /src/configldsv.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2020, Craig Smith, alwyz. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; Config loading and saving 7 | ; 8 | 9 | ;---------------------------------------------------------------------- 10 | losvco: 11 | jsr rs232_off 12 | jsr ercopn 13 | lda #txt_filename 15 | ldx #16 16 | jsr inpset 17 | lda #filename_config 19 | jsr outstr 20 | jsr inputl 21 | beq :+ 22 | txa 23 | ldx #inpbuf 25 | jsr setnam 26 | lda #2 27 | ldx device_disk 28 | ldy #0 29 | jsr setlfs 30 | ldx $b7 31 | : rts 32 | 33 | ;---------------------------------------------------------------------- 34 | save_config: 35 | lda easyflash_support 36 | beq :+ 37 | lda easyflash_use_disk 38 | beq save_config_easyflash 39 | : jsr losvco 40 | bne *+2 ; [XXX] 41 | ldx #LFN_DISK_CMD 42 | jsr chkout 43 | ldx #0 44 | : lda txt_cmd_scratch,x 45 | beq :+ 46 | jsr chrout 47 | inx 48 | bne :- 49 | : ldx #0 50 | : lda inpbuf,x 51 | jsr chrout 52 | inx 53 | cpx max 54 | bcc :- 55 | lda #CR 56 | jsr chrout 57 | jsr clrchn 58 | lda #config_data 61 | sta nlocat+1 62 | lda #nlocat 63 | ldx #config_data_end 65 | jsr save 66 | jsr losver 67 | losvab rts 68 | 69 | ;---------------------------------------------------------------------- 70 | save_config_easyflash: 71 | jmp easyflash_write_config 72 | 73 | ;---------------------------------------------------------------------- 74 | load_config: 75 | lda easyflash_support 76 | beq :+ 77 | lda easyflash_use_disk 78 | beq load_config_easyflash 79 | : jsr losvco 80 | beq losvab 81 | 82 | ;---------------------------------------------------------------------- 83 | load_config_file: 84 | ldx #config_data 86 | lda #0 ; load 87 | jsr $ffd5 88 | jsr losver 89 | load_config_done: 90 | jsr themeroutine 91 | jsr rsopen ; [XXX jmp] 92 | rts 93 | 94 | ;---------------------------------------------------------------------- 95 | load_config_easyflash: 96 | jsr easyflash_read_config 97 | jmp load_config_done 98 | 99 | ;---------------------------------------------------------------------- 100 | losver: 101 | jsr rs232_off 102 | ldx #LFN_DISK_CMD 103 | jsr chkin 104 | : jsr getin 105 | cmp #CR 106 | bne :- 107 | jmp clrchn 108 | -------------------------------------------------------------------------------- /src/macroex.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2020, Craig Smith, alwyz. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; Macro Execution 7 | ; 8 | 9 | ;---------------------------------------------------------------------- 10 | ; xfer id and pw to macros F5 and F7 11 | xferidpw: 12 | ldy #59 13 | : lda (nlocat),y 14 | sta macmem+69,y 15 | iny 16 | lda (nlocat),y 17 | beq :+ 18 | jmp :- ; [XXX short jmp] 19 | : sta macmem+69,y 20 | ldy #71 21 | : lda (nlocat),y 22 | sta macmem+121,y 23 | iny 24 | lda (nlocat),y 25 | beq :+ 26 | jmp :- ; [XXX short jmp] 27 | : sta macmem+121,y 28 | rts 29 | 30 | ;---------------------------------------------------------------------- 31 | macro_dry_run_mode: 32 | .byte 0 33 | macro_tmp: 34 | .byte 0 35 | 36 | ;---------------------------------------------------------------------- 37 | decode_fkey_scancode: 38 | cpx #3 ; from LSTX f-key value 39 | bne @1 40 | ldx #7 41 | @1: txa 42 | sec 43 | sbc #4 ; now a = 0..3 for f1,f3,f5,f7 44 | ldx #5 45 | : asl a 46 | dex 47 | bpl :- ; a = 0,64,128,192 48 | sta macro_tmp 49 | rts 50 | 51 | ;---------------------------------------------------------------------- 52 | print_macro: 53 | lda LSTX ; 3-6 are F7/F1/F3/F5 54 | cmp #7 55 | bcc print_macro ; wait until key released 56 | 57 | jsr decode_fkey_scancode 58 | prtmc0 59 | ldx macro_tmp ; index into macro text 60 | lda macmem,x 61 | beq @end 62 | pha 63 | ldx macro_dry_run_mode 64 | bne @mc2 ; -> don't send 65 | 66 | ; send character 67 | pla 68 | pha 69 | ldx ascii_mode 70 | beq :+ 71 | jsr petscii_to_ascii 72 | : jsr rs232_put 73 | lda #$100-3 74 | sta JIFFIES 75 | : lda JIFFIES 76 | bne :- ; wait 50 msec 77 | lda #$100-3 78 | sta JIFFIES 79 | : lda JIFFIES 80 | bne :- ; wait 50 msec [XXX combine] 81 | 82 | ; get echo 83 | jsr rs232_get 84 | cmp #0 85 | bne @mci 86 | ldx half_duplex 87 | beq @mca 88 | ldx ascii_mode 89 | beq @mc2 90 | pla 91 | jsr petscii_to_ascii 92 | bne @mck 93 | beq @mc3 94 | @mca: pla 95 | bne @mc3 96 | @mci: tax 97 | pla 98 | txa 99 | @mck: ldx ascii_mode 100 | beq :+ 101 | jsr ascii_to_petscii 102 | : pha 103 | 104 | @mc2: jsr cursor_off 105 | pla 106 | ldx macro_dry_run_mode 107 | bne :+ ; then don't put into buffer 108 | jsr buffer_put 109 | : jsr handle_control_codes 110 | bcs @mc3 111 | jsr chrout 112 | jsr quote_insert_off 113 | jsr cursor_show 114 | @mc3: inc macro_tmp 115 | cmp #255 116 | bne prtmc0 117 | @end: jmp cursor_off 118 | -------------------------------------------------------------------------------- /src/screens.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2020, Craig Smith, alwyz. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; Screen swapping, cursor logic 7 | ; 8 | 9 | ;---------------------------------------------------------------------- 10 | ; swap screen with #1-4 (behind KERNAL ROM) 11 | swap_screen: 12 | txa 13 | pha 14 | jsr cursor_off 15 | lda SHFLAG 16 | sta tmp04 17 | pla 18 | asl a 19 | asl a 20 | asl a 21 | clc 22 | adc #>SCREENS_BASE 23 | sta locat+1 24 | lda #>$0400 25 | sta tmp03 26 | lda #0 27 | sta locat 28 | sta tmp02 29 | sei 30 | lda $d011 31 | pha 32 | lda #$0b 33 | sta $d011 ; screen off 34 | lda #$34 ; disable ROMs - see Internals.md#Banking 35 | sta $01 36 | : jsr scrnl1 37 | cmp #$08 38 | bcc :- 39 | lda #>$d800 40 | sta tmp03 41 | : jsr scrnl1 42 | cmp #>$dc00 43 | bcc :- 44 | lda #$37 45 | sta $01 ; enable ROMs 46 | pla 47 | sta $d011 48 | cli 49 | jmp term_mainloop 50 | 51 | scrnl1 52 | ldx tmp04 ; SHFLAG 53 | cpx #SHFLAG_SHIFT | SHFLAG_CTRL 54 | beq scrnls 55 | ldy #0 56 | scrnlc lda (tmp02),y 57 | sta (locat),y 58 | dey 59 | bne scrnlc 60 | beq scrnl3 61 | scrnls ldy #0 62 | scrnl2 ;swap screen page 63 | lda (tmp02),y 64 | tax 65 | lda (locat),y 66 | sta (tmp02),y 67 | txa 68 | sta (locat),y 69 | iny 70 | bne scrnl2 71 | scrnl3 inc locat+1 72 | inc tmp03 73 | lda tmp03 74 | rts 75 | outspc 76 | lda #CSR_RIGHT 77 | outsp1 78 | jsr chrout 79 | dex 80 | bne outsp1 81 | rts 82 | bufclr 83 | lda buffst 84 | sta buffer_ptr 85 | lda buffst+1 86 | sta buffer_ptr+1 87 | rts 88 | 89 | ;---------------------------------------------------------------------- 90 | ; calculate screen pointer (and read) 91 | calc_scr_ptr: 92 | ldy LINE 93 | lda LDTB2,y ; low byte of screen address for line 94 | sta locat 95 | lda LDTB1,y ; hi byte 96 | and #$7f 97 | sta locat+1 98 | lda COLUMN 99 | cmp #40 100 | bcc :+ 101 | sbc #40 102 | clc 103 | : adc locat 104 | sta locat 105 | lda locat+1 106 | adc #0 107 | sta locat+1 108 | ldy #0 109 | lda (locat),y 110 | rts 111 | 112 | ;---------------------------------------------------------------------- 113 | ; calculate color RAM pointer (and read) 114 | calc_col_ptr: 115 | jsr calc_scr_ptr 116 | lda #$d4 117 | clc 118 | adc locat+1 119 | sta locat+1 120 | lda (locat),y 121 | rts 122 | 123 | ;---------------------------------------------------------------------- 124 | ; turn off quote mode and insert mode 125 | quote_insert_off: 126 | lda #0 127 | sta qmode 128 | sta imode 129 | rts 130 | 131 | -------------------------------------------------------------------------------- /src/instr.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2020, Craig Smith, alwyz. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; Instructions and credits 7 | ; 8 | 9 | SET_PETSCII 10 | txt_instructions1: 11 | .byte CLR,10,LTGRAY,15,LOCASE,RED," C",ORANGE,"C",YELLOW,"G",GREEN,"M",BLUE,"S",PURPLE,"! ",WHITE,"Term FUTURE ",VERSION,CR,CR 12 | .byte RVSON,YELLOW,"Commands:",RVSOFF,CR,CR 13 | .byte BLUE,"C",RED,"= ",WHITE,"STOP ",CYAN,"Disconnect.",LTBLUE," (Drop DTR)",CR 14 | .byte WHITE,"CTRL J/K ",LTGREEN,"Dest/Non Dest Cursor",CR 15 | .byte BLUE,"C",RED,"= ",WHITE,"CTRL 1-4 ",YELLOW,"Take a 'snapshot' of the",CR 16 | .byte " screen into storage 1-4",CR 17 | .byte WHITE,"SHFT CTRL 1-4 ",YELLOW,"Recall Snapshot 1-4",CR 18 | .byte " (Swaps w/current screen)",CR 19 | .byte BLUE,"C",RED,"= ",WHITE,"F7 ",YELLOW,"Stores Current Snapshot",CR 20 | .byte " in buffer",CR 21 | .byte WHITE,"CTRL F1/F3 ",PURPLE,"Macros.",CR 22 | .byte WHITE,"CTRL F5/F7 ",PURPLE,"Send User ID/Password.",CR,CR 23 | .byte CYAN,"At disk prompt, \"#X\" changes to dev#x.",CR 24 | .byte "Devices 8-29 are valid.",CR 25 | .byte "SD2IEC: \"cd/x\" changes to subdir x",CR 26 | .byte "AND \"cd:",$5f,"\" changes to root dir.",CR 27 | .byte LTBLUE,"At the buffer cmd prompt, ",WHITE,"< ",LTBLUE,"and ",WHITE,">",CR 28 | .byte LTBLUE,"moves the buffer pointer.",CR 29 | .byte LTGREEN,"On-line, ",WHITE,"CTRL-B ",LTGREEN,"changes",CR 30 | .byte "the background color.",WHITE," CTRL-N",LTGREEN," makes ",CR 31 | .byte "background black.",WHITE," CTRL-G",LTGREEN," bell sound",CR 32 | .byte WHITE,"CTRL-V ",LTGREEN,"sfx sound",WHITE," Press a key...",0 33 | 34 | txt_instructions2: 35 | .byte CLR,10,LTGRAY,15,WHITE," This Version of CCGMS is based on",CR 36 | .byte LOCASE," ",RED,"C",ORANGE,"C",YELLOW,"G",GREEN,"M",BLUE,"S",WHITE,"! Term (c) 2016",CR 37 | .byte " by Craig Smith, All Rights Reserved.",CR,CR 38 | .byte LTGREEN,"This program is open source.",CR 39 | .byte "redistribution and use in source and",CR 40 | .byte "binary forms, with or without modifi-",CR 41 | .byte "cation, are permitted under the terms",CR 42 | .byte "of the BSD 3-clause license.",CR 43 | .byte "For details, or to contribute, visit:",CR 44 | .byte YELLOW," https://github.com/mist64/ccgmsterm",CR,CR 45 | .byte PURPLE,"A",LTBLUE,"l",CYAN,"w",LTGREEN,"y",YELLOW,"z",GRAY," would like to thank ",LTGREEN,"the CBM",CR 46 | .byte "Hackers Mailing List,",YELLOW," IRC #c64friends,",CR 47 | .byte ORANGE,"pcollins/excess, larry/role, xlar54,",CR 48 | .byte ORANGE,"and the users of AFTERLIFE BBS who",CR 49 | .byte "helped with ",LTRED,"testing, tips, and bugfixes.",CR,CR 50 | .byte LTGREEN,WHITE,"Press a key...",0 51 | SET_ASCII 52 | 53 | .byte 0 ; [XXX unused] 54 | -------------------------------------------------------------------------------- /src/disk.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2020, Craig Smith, alwyz. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; Send file or buffer to screen and/or modem 7 | ; 8 | 9 | ; bufflg 10 | ; $80: 0: disk, 1: buffer 11 | ; $40: 0: no delay, 1: delay 12 | ; buffl2: 13 | ; 0: output to screen 14 | ; !=0: output to screen and modem 15 | 16 | dskout: 17 | jsr clrchn 18 | jsr cursor_show 19 | lda bufflg 20 | bpl @dskmo ; -> disk 21 | 22 | ; buffer 23 | jsr buffer_get_byte 24 | bit bufflg 25 | bvs @timdel ; -> buffer & delay 26 | ldx #$ff 27 | : dex ; short delay (about 1ms) 28 | bne :- 29 | beq @chstat ; always 30 | 31 | ; disk 32 | @dskmo: 33 | jsr rs232_off 34 | ldx #LFN_FILE 35 | jsr chkin 36 | jsr getin ; get byte from disk 37 | pha 38 | pla ; [XXX] 39 | @timdel: 40 | bit bufflg 41 | bvc @chstat ; -> no delay 42 | jsr sleep_50ms 43 | @chstat: 44 | pha 45 | lda status 46 | and #$40 47 | jne @dskext ; -> EOF 48 | jsr clrchn 49 | jsr cursor_off 50 | pla 51 | pha 52 | jsr handle_control_codes 53 | jsr chrout 54 | jsr quote_insert_off 55 | ldx buffl2 56 | bne @dskmo1 ; non zero: also output to modem 57 | pla 58 | jmp @chkkey ; skip 59 | 60 | ; output to modem 61 | @dskmo1: 62 | jsr rs232_clear 63 | jsr rs232_on 64 | jsr rs232_clear 65 | pla 66 | ldx ascii_mode 67 | beq :+ 68 | jsr petscii_to_ascii 69 | : jsr rs232_put 70 | 71 | ; eat echo from modem 72 | ; (this timeout failsafe makes sure the byte is received back from modem 73 | ; before accessing disk for another byte otherwise we can have 74 | ; all sorts of nmi related issues.... this solves everything. 75 | ; uses the 'fake' rtc / jiffy counter function / same as xmmget...) 76 | ; [XXX this is a duplicate of rs232_get_timeout] 77 | lda #70 ; timeout failsafe 78 | sta xmodel 79 | lda #0 80 | sta rtca1 81 | sta rtca2 82 | sta rtca0 83 | 84 | : jsr rs232_get ; get byte (and ignore) 85 | jcc @chkkey ; done 86 | jsr xmmrtc ; count up 87 | lda rtca1 88 | cmp xmodel 89 | bcc :- ; retry until time is up 90 | 91 | @chkkey: 92 | jsr get_key 93 | jeq dskout ; loop 94 | 95 | ; handle keypress 96 | cmp #3 ; STOP key 97 | beq @dskex2 98 | 99 | jsr rs232_on 100 | cmp #'S' 101 | bne @nos 102 | 103 | ; 'S' 104 | lda bufflg ; only in memory mode 105 | bpl @nos 106 | jsr buffer_skip_256 107 | ldx status ; EOI? 108 | bne @dskex2 ; end 109 | jsr rs232_on 110 | jmp dskout ; loop 111 | @nos: 112 | 113 | : jsr get_key 114 | beq :- 115 | 116 | jsr rs232_on 117 | jmp dskout 118 | @dskext: 119 | jsr rs232_on 120 | pla 121 | @dskex2: 122 | jsr clrchn 123 | jmp cursor_off 124 | 125 | ;---------------------------------------------------------------------- 126 | get_key: 127 | jsr clrchn 128 | jsr getin 129 | cmp #0 130 | rts 131 | -------------------------------------------------------------------------------- /rs232lib/README.md: -------------------------------------------------------------------------------- 1 | # CCGMS rs232lib 2 | 3 | This is `rs232lib`, a library for RS-232 communication on the Commodore 64. It is derived from the [CCGMS Future](https://github.com/mist64/ccgmsterm) driver code. 4 | 5 | The following table summarizes the included drivers and their supported baud rates: 6 | 7 | | Driver | 300 | 1200 | 2400 | 4800 | 9600 | 19200 | 3400 | 8 | |--------------------|-----|------|------|------|------|-------|------| 9 | | User Port | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | 10 | | UP9600 | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | 11 | | SwiftLink/Turbo232 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | 12 | 13 | It uses a 256 byte input buffer and no output buffer. 14 | 15 | ## API 16 | 17 | ### `rs232_init` 18 | 19 | Init the driver. This has to be called at least once to initialize the modem. This will evaluate the symbols `modem_type`, `baud_rate` and `is_pal_system`. 20 | 21 | ### `rs232_on` 22 | 23 | Enable the driver. This has to be called at least once, and to re-enable the driver after `rs232_off`. 24 | 25 | ### `rs232_off` 26 | 27 | Disable the driver. This needs to be called if the serial disk is supposed to be used. 28 | 29 | ### `rs232_get` 30 | 31 | Get a byte. 32 | 33 | ### `rs232_put` 34 | 35 | Send a byte. 36 | 37 | ### `rs232_dropdtr` 38 | 39 | Drop the DTR line (hangup). 40 | 41 | ### `rs232_clear` 42 | 43 | Clear the input buffer. 44 | 45 | 46 | ## Dependencies 47 | 48 | The library requires the following symbols to be defined: 49 | 50 | ### `modem_type` 51 | 52 | Must be set to the driver/config. 53 | 54 | MODEM_TYPE_USERPORT = 0 55 | MODEM_TYPE_UP9600 = 1 56 | MODEM_TYPE_SWIFTLINK_DE = 2 57 | MODEM_TYPE_SWIFTLINK_DF = 3 58 | MODEM_TYPE_SWIFTLINK_D7 = 4 59 | 60 | ### `baud_rate` 61 | 62 | BAUD_300 = 0 63 | BAUD_1200 = 1 64 | BAUD_2400 = 2 65 | BAUD_4800 = 3 66 | BAUD_9600 = 4 67 | BAUD_19200 = 5 68 | BAUD_38400 = 6 69 | 70 | ### `is_pal_system` 71 | 72 | 0: NTSC 73 | 1: PAL 74 | 75 | ## `ribuf` 76 | 77 | 256 bytes of memory the driver can use for the input buffer. 78 | 79 | ## `revtabup` 80 | 81 | 128 bytes of memory the driver can use for temporary storage. 82 | 83 | # Banking 84 | 85 | rs232lib uses the $0314/$0315 and $0318/$0319 vectors to hook IRQs and NMIs. It also installs vectors at $FFFA/$FFFB and $FFFE/$FFFF to hook IRQs and NMIs even with the KERNAL off, and fowards them through the usual vectors. 86 | 87 | This requires all software that turns off the KERNAL ROM to do this by storing #$34 in $01 instead of #$30. It is equivalent, but allows the timing-critical UP9600 code to switch I/O on and off with `inc $01` and `dec $01`. 88 | 89 | # License 90 | 91 | Copyright (c) 2016,2022, Craig Smith, alwyz, Michael Steil. All rights reserved. 92 | This project is licensed under the BSD 3-Clause License. 93 | -------------------------------------------------------------------------------- /src/config.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2020, Craig Smith, alwyz. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; Configuration data & phone book 7 | ; 8 | 9 | ;---------------------------------------------------------------------- 10 | ;---------------------------------------------------------------------- 11 | ; This data gets saved to disk/EasyFlash 12 | config_data: 13 | 14 | baud_rate: 15 | ; DEFAULT_BAUDRATE: defined by build system 16 | .if DEFAULT_BAUDRATE = 2400 17 | .byte BAUD_2400 18 | .elseif DEFAULT_BAUDRATE = 9600 19 | .byte BAUD_9600 20 | .else 21 | .error 22 | .endif 23 | 24 | ; indicates whether dialing should use ATD, followed by a quote 25 | firmware_zimmers: 26 | .byte 0 27 | 28 | mopo2: 29 | .byte $20 ; unused, but needs to stay for bin compat 30 | 31 | modem_type: 32 | .byte DEFAULT_DRIVER; defined by build system 33 | 34 | ;---------------------------------------------------------------------- 35 | ; Phone book 36 | phbmem: 37 | ; | len | contents | 38 | ; |-----|----------| 39 | ; | 2 | ? | 40 | ; | 18 | name | 41 | ; | 33 | address | 42 | ; | 6 | port? | 43 | ; | 12 | user | 44 | ; | 12 | password | 45 | ; total: 83 bytes 46 | 47 | SET_PETSCII 48 | ;.byte 0,6 49 | ;.byte "Afterlife " 50 | ;.byte "192.168.0.8 ",0," ",0 51 | ;.byte "6401 ",0 52 | ;.byte "MYUSERID ",0 53 | ;.byte "MYPASSWORD1",0 54 | 55 | ;.byte 0,6 56 | ;.byte "Afterlife " 57 | ;.byte "192.168.0.8:6401 ",0 58 | ;.byte "6400 ",0 59 | ;.byte "ANOTHERUSER",0 60 | ;.byte "MYPASSWORD1",0 61 | 62 | ;.byte 0,6 63 | ;.byte "Afterlife " 64 | ;.byte "192.168.0.8:6401 ",0 65 | ;.byte "23 ",0 66 | ;.byte "MYID ",0 67 | ;.byte "MYPASSWORD1",0 68 | 69 | .repeat 29 70 | .res 83,0 ; empty entry 71 | .endrep 72 | 73 | .byte 0,6 74 | .byte "Commodoreserver " 75 | .byte "commodoreserver.com",0,CR,0,0,0,0,0,0,0,0,0,0,0,0 76 | .byte "1541",0,13 77 | .byte "id ",0 78 | .byte "pin ",0 79 | .byte 0,0 80 | 81 | ;---------------------------------------------------------------------- 82 | ; Macros 83 | macmem: 84 | macmm1: 85 | .byte "Hello World" 86 | .res 64,0 ; [XXX too many 0s] 87 | macmm2: 88 | .res 64,0 89 | macmm3: 90 | .res 64,0 91 | macmm4: 92 | .res 64,0 93 | 94 | ;---------------------------------------------------------------------- 95 | ; file transmission protocol 96 | protoc: 97 | .byte PROTOCOL_PUNTER 98 | 99 | ; current theme; see theme.s 100 | theme: 101 | .byte 0 102 | 103 | ; save config to disk even though we have an EasyFlash 104 | easyflash_use_disk: 105 | .byte 0 106 | 107 | config_data_end: 108 | ;---------------------------------------------------------------------- 109 | 110 | .byte 0 ; [XXX unused; not part of config file] 111 | 112 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | export PATH:=$(abspath bin):$(PATH) 2 | EASYFLASH ?= 0 3 | EXOMIZER ?= 0 4 | AUTOMATION ?= 0 5 | DEFAULT_DRIVER ?= 0 6 | DEFAULT_BAUDRATE ?= 2400 7 | 8 | EXO_PATH := build/bin/exomizer 9 | EXO_ARGS := sfx sys -q -n -T4 -M256 -Di_perf=2 10 | 11 | ifeq ($(EXOMIZER),1) 12 | RUN_PRG = build/ccgmsterm-exo.prg 13 | else 14 | RUN_PRG = build/ccgmsterm.prg 15 | endif 16 | 17 | .PHONY: all 18 | all: $(EXO_PATH) 19 | make build/rs232.lib 20 | 21 | ca65 -g src/ccgmsterm.s -o build/ccgmsterm.o -DEASYFLASH=$(EASYFLASH) -DAUTOMATION=$(AUTOMATION) -DDEFAULT_DRIVER=$(DEFAULT_DRIVER) -DDEFAULT_BAUDRATE=$(DEFAULT_BAUDRATE) 22 | 23 | ca65 -g src/80columns.s -o build/80columns.o -DEASYFLASH=$(EASYFLASH) 24 | ca65 -g src/charset.s -o build/charset.o -DEASYFLASH=$(EASYFLASH) 25 | 26 | cl65 -g -C src/ccgmsterm.cfg \ 27 | -o build/ccgmsterm.prg \ 28 | -Ln build/ccgmsterm.sym -m build/ccgmsterm.map \ 29 | build/ccgmsterm.o \ 30 | build/80columns.o \ 31 | build/charset.o \ 32 | build/rs232.lib 33 | 34 | ifeq ($(EXOMIZER),1) 35 | $(EXO_PATH) $(EXO_ARGS) -o build/ccgmsterm-exo.prg build/ccgmsterm.prg 36 | endif 37 | 38 | $(EXO_PATH): 39 | [ -d exomizer/src ] || git submodule update --init exomizer 40 | mkdir -p build/bin 41 | $(MAKE) -C exomizer/src CFLAGS="-Wall -Wstrict-prototypes -pedantic -O3" 42 | cp exomizer/src/exomizer build/bin 43 | 44 | build/rs232.lib: rs232lib/c64.inc rs232lib/rs232.inc rs232lib/rs232_kernal.inc rs232lib/rs232.s rs232lib/rs232_swiftlink.s rs232lib/rs232_up9600.s rs232lib/rs232_userport.s 45 | mkdir -p build 46 | ca65 -g rs232lib/rs232.s -o build/rs232.o 47 | ca65 -g rs232lib/rs232_userport.s -o build/rs232_userport.o 48 | ca65 -g rs232lib/rs232_up9600.s -o build/rs232_up9600.o 49 | ca65 -g rs232lib/rs232_swiftlink.s -o build/rs232_swiftlink.o 50 | ar65 a build/rs232.lib build/rs232.o build/rs232_userport.o build/rs232_up9600.o build/rs232_swiftlink.o 51 | 52 | build/disk.d64: 53 | c1541 -format ccgms,fu d64 build/disk.d64 54 | 55 | # run with User Port interface 56 | .PHONY: runup 57 | runup: all build/disk.d64 58 | x64sc -silent -autostartprgmode 1 +cart +rsuserup9600 -userportdevice 2 -rsuserdev 0 -rsuserbaud 2400 -rsdev1 localhost:25232 -rsdev1baud 2400 -8 build/disk.d64 build/ccgmsterm.prg 59 | 60 | # run with UP9600 interface 61 | .PHONY: runup9600 62 | runup9600: all build/disk.d64 63 | x64sc -silent -autostartprgmode 1 +cart -rsuserup9600 -userportdevice 2 -rsuserdev 0 -rsuserbaud 9600 -rsdev1 localhost:25232 -rsdev1baud 9600 -8 build/disk.d64 build/ccgmsterm.prg 64 | 65 | # run with SwiftLink/DE interface 66 | .PHONY: runsw 67 | runsw: all build/disk.d64 68 | x64sc -silent -autostartprgmode 1 +cart -acia1 -acia1base 0xDE00 -acia1irq 1 -acia1mode 1 -myaciadev 0 -rsdev1 localhost:25232 -rsdev1baud 9600 -8 build/disk.d64 $(RUN_PRG) 69 | 70 | .PHONY: usb 71 | usb: all 72 | cp build/ccgmsterm.prg /Volumes/C64/; diskutil unmountDisk force /Volumes/C64 73 | 74 | .PHONY: testup 75 | testup: 76 | (cd test; ./xfer.sh 2>&1 | grep TEST_XFER) & 77 | AUTOMATION=1 make clean all runup 78 | 79 | .PHONY: testsw 80 | testsw: 81 | (cd test; ./xfer.sh 2>&1 | grep TEST_XFER) & 82 | AUTOMATION=1 DEFAULT_DRIVER=2 DEFAULT_BAUDRATE=9600 make clean all runsw 83 | 84 | .PHONY: clean 85 | clean: 86 | rm -rf build 87 | -------------------------------------------------------------------------------- /src/theme.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2020, Craig Smith, alwyz. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; Theming 7 | ; 8 | 9 | ; The columns are: 10 | ; 0: Classic CCGMS v5.5 11 | ; 1: Iman / XPB v7.1 12 | ; 2: Predator / FCC v8.1 13 | ; 3: Ice theme v9.4 14 | ; 4: Defcon/Unicess v17.2 15 | ; 5: Alwyz / CCGMS 2021 16 | 17 | tc1: .byte WHITE,BLUE,WHITE,WHITE,BLUE,DKGRAY ; f1 18 | tc2: .byte LTRED,LTRED,BLUE,DKGRAY,DKGRAY,PURPLE ; Upload 19 | tc3: .byte WHITE,LTBLUE,WHITE,WHITE,PURPLE,GRAY ; f3 20 | tc4: .byte YELLOW,YELLOW,LTBLUE,BLUE,GRAY,LTBLUE ; Download 21 | tc5: .byte WHITE,CYAN,WHITE,WHITE,LTBLUE,LTGRAY ; f5 22 | tc6: .byte LTGREEN,LTGREEN,BLUE,PURPLE,LTGRAY,CYAN ; Disk 23 | tc7: .byte WHITE,LTGREEN,WHITE,WHITE,CYAN,LTGRAY ; f7 24 | tc8: .byte GREEN,CYAN,LTBLUE,LTBLUE,LTGRAY,LTGREEN ; Options 25 | tc9: .byte WHITE,BLUE,WHITE,WHITE,BLUE,DKGRAY ; f2 26 | tc10: .byte LTRED,LTRED,BLUE,BLUE,DKGRAY,PURPLE ; send/rec 27 | tc11: .byte WHITE,LTBLUE,WHITE,WHITE,PURPLE,GRAY ; f4 28 | tc12: .byte YELLOW,YELLOW,LTBLUE,PURPLE,GRAY,LTBLUE ; Buffer menu 29 | tc13: .byte WHITE,CYAN,WHITE,WHITE,LTBLUE,LTGRAY ; f6 30 | tc14: .byte LTGREEN,LTGREEN,BLUE,LTBLUE,LTGRAY,CYAN 31 | tc15: .byte WHITE,LTGREEN,WHITE,WHITE,CYAN,LTGRAY ; f8 32 | tc16: .byte GREEN,CYAN,LTBLUE,LTGRAY,LTGRAY,LTGREEN ; f8 text 33 | tc17: .byte BLUE,BLUE,CYAN,DKGRAY,DKGRAY,BLUE ; C 34 | tc18: .byte WHITE,YELLOW,WHITE,WHITE,LTGRAY,GRAY ; cf1 35 | tc19: .byte CYAN,LTBLUE,BLUE,LTGRAY,GRAY,YELLOW ; cf1 text 36 | tc20: .byte WHITE,YELLOW,WHITE,WHITE,LTGRAY,GRAY ; f3 37 | tc21: .byte CYAN,LTBLUE,BLUE,CYAN,GRAY,YELLOW ; f3 txt 38 | tc22: .byte WHITE,LTRED,WHITE,WHITE,WHITE,DKGRAY ; f5 39 | tc23: .byte LTBLUE,BLUE,LTBLUE,CYAN,DKGRAY,LTRED ; f5txt 40 | tc24: .byte WHITE,LTRED,WHITE,WHITE,WHITE,DKGRAY ; f7 41 | tc25: .byte LTBLUE,BLUE,LTBLUE,YELLOW,DKGRAY,LTRED ; f7txt 42 | tc26: .byte RED,RED,RED,GRAY,GRAY,RED ; = sign 43 | tc27: .byte WHITE,LTGREEN,LTGREEN,LTGREEN,LTGREEN,GRAY; f7 menu color 44 | tc28: .byte CYAN,LTRED,LTRED,LTRED,LTRED,LTBLUE ; phonebook color 45 | 46 | themeroutine: 47 | ldy theme 48 | lda tc1,y 49 | sta tcol1 50 | lda tc2,y 51 | sta tcol2 52 | lda tc9,y 53 | sta tcol9 54 | lda tc10,y 55 | sta tcol10 56 | lda tc3,y 57 | sta tcol3 58 | lda tc4,y 59 | sta tcol4 60 | lda tc11,y 61 | sta tcol11 62 | lda tc12,y 63 | sta tcol12 64 | lda tc5,y 65 | sta tcol5 66 | lda tc6,y 67 | sta tcol6 68 | lda tc13,y 69 | sta tcol13 70 | lda tc14,y 71 | sta tcol14 72 | lda tc7,y 73 | sta tcol7 74 | lda tc8,y 75 | sta tcol8 76 | lda tc15,y 77 | sta tcol15 78 | lda tc16,y 79 | sta tcol16 80 | lda tc17,y 81 | sta tcol17a 82 | sta tcol17b 83 | sta tcol17c 84 | sta tcol17d 85 | lda tc26,y 86 | sta tcol26a 87 | sta tcol26b 88 | sta tcol26c 89 | sta tcol26d 90 | lda tc18,y 91 | sta tcol18 92 | lda tc20,y 93 | sta tcol20 94 | lda tc22,y 95 | sta tcol22 96 | lda tc24,y 97 | sta tcol24 98 | lda tc19,y 99 | sta tcol19 100 | lda tc21,y 101 | sta tcol21 102 | lda tc23,y 103 | sta tcol23 104 | lda tc25,y 105 | sta tcol25 106 | lda tc27,y 107 | sta tcol27a 108 | sta tcol27b 109 | lda tc28,y 110 | sta tcol28a 111 | sta tcol28b 112 | sta tcol28c 113 | sta tcol28d 114 | sta tcol28e 115 | sta tcol28f 116 | rts 117 | -------------------------------------------------------------------------------- /src/input.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2020, Craig Smith, alwyz. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; String input from user 7 | ; 8 | 9 | ;---------------------------------------------------------------------- 10 | input: 11 | jsr inpset 12 | jmp inputl 13 | 14 | ;---------------------------------------------------------------------- 15 | inpset: 16 | stx max 17 | cpy #0 18 | beq :+ 19 | jsr outstr 20 | : jsr clrchn 21 | sec 22 | jsr plot 23 | stx tmp9e 24 | sty tmp9f 25 | jsr calc_scr_ptr; set up begin & 26 | lda locat+1 ; end of input 27 | sta begpos+1 ; ptrs 28 | sta endpos+1 29 | lda locat 30 | sta begpos 31 | clc 32 | adc max 33 | sta endpos 34 | lda endpos+1 35 | adc #0 36 | sta endpos+1 37 | rts 38 | 39 | ;---------------------------------------------------------------------- 40 | inputl: 41 | lda #0 42 | sta BLNSW 43 | jsr invert_csr_char 44 | inpwat: 45 | jsr getin 46 | beq inpwat 47 | sta tmp03 48 | and #$7f 49 | cmp #CSR_DOWN 50 | beq inpcud 51 | cmp #'"' 52 | beq inpwat 53 | cmp #CR 54 | jeq inpret 55 | lda tmp03 56 | cmp #DEL 57 | beq inpdel 58 | cmp #CSR_LEFT 59 | beq inpdel 60 | and #$7f 61 | cmp #HOME 62 | beq inpcls 63 | bne inpprc 64 | inpcud 65 | jsr restore_csr_char 66 | lda tmp03 67 | cmp #CSR_UP 68 | beq inphom 69 | jsr inpcu1 70 | jmp inpmov 71 | inpcu1 ldy max 72 | inpcu2 73 | dey 74 | bmi inpcu3 75 | lda (begpos),y 76 | cmp #' ' 77 | beq inpcu2 78 | inpcu3 79 | iny 80 | tya 81 | clc 82 | adc tmp9f 83 | tay 84 | rts 85 | inpcls 86 | jsr restore_csr_char 87 | lda tmp03 88 | cmp #CLR 89 | bne inphom 90 | ldy max 91 | lda #' ' 92 | inpcl2 sta (begpos),y 93 | dey 94 | bpl inpcl2 95 | inphom 96 | ldy tmp9f 97 | inpmov 98 | ldx tmp9e 99 | clc 100 | jsr plot 101 | jmp inputl 102 | inpdel 103 | jsr calc_scr_ptr 104 | lda locat 105 | cmp begpos 106 | bne inprst 107 | lda locat+1 108 | cmp begpos+1 109 | beq inpwat 110 | bne inprst 111 | inpprc 112 | jsr calc_scr_ptr 113 | lda locat 114 | cmp endpos 115 | bne inpins 116 | lda locat+1 117 | cmp endpos+1 118 | bne inpins 119 | jmp inpwat 120 | inpins 121 | lda tmp03 122 | cmp #INST 123 | bne inprst 124 | dec endpos+1 125 | ldy #$ff 126 | lda (endpos),y 127 | inc endpos+1 128 | cmp #' ' 129 | beq inprst 130 | jmp inpwat 131 | inprst 132 | ldx #3 133 | stx KOUNT 134 | jsr restore_csr_char 135 | lda tmp03 136 | jsr chrout 137 | jsr quote_insert_off 138 | jmp inputl 139 | 140 | inpret: 141 | jsr restore_csr_char 142 | jsr inpcu1 143 | cmp COLUMN 144 | bcc :+ 145 | ldx tmp9e 146 | clc 147 | jsr plot 148 | : jsr calc_scr_ptr 149 | lda locat 150 | sec 151 | sbc begpos 152 | pha 153 | tay 154 | lda #' ' 155 | : sta (begpos),y 156 | cpy max 157 | beq :+ 158 | iny 159 | bne :- 160 | : pla 161 | sta max 162 | ldx tmp9e 163 | ldy tmp9f 164 | clc 165 | jsr plot 166 | lda #1 167 | sta BLNSW 168 | lda #3 169 | ldy #0 170 | tax 171 | jsr setlfs 172 | lda #0 173 | jsr setnam 174 | jsr open 175 | ldx #3 176 | jsr chkin 177 | ldy #0 178 | : cpy max 179 | beq :+ 180 | jsr chrin 181 | sta inpbuf,y 182 | iny 183 | bne :- 184 | : lda #0 185 | sta inpbuf,y 186 | jsr clrchn 187 | lda #3 188 | jsr close 189 | ldx max 190 | rts 191 | -------------------------------------------------------------------------------- /src/easyflash.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2020, Craig Smith, alwyz. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; EasyFlash config loading and saving 7 | ; 8 | 9 | ;---------------------------------------------------------------------- 10 | easyflash_write_config: 11 | jsr easyflash_init 12 | 13 | lda #$30 ; bank $30 (this is where the config is going to be stored). 14 | ldy #$80 ; lorom 15 | jsr $df83 ; erase sector (banks 30:0, 31:0, 32:0, 33:0, 34:0, 35:0, 36:0 and 37:0 are set to $ff) 16 | jsr delay_1500ms ; delay 1.5 seconds after erase to let c64 physically finish its job for compatibility. 17 | lda #$30 ; set bank $30 for the next read/write command. 18 | jsr $df86 19 | lda #$b0 ; set bank mode to llll (continue to next lo bank after current lo bank is full) 20 | ldx #<$8000 ; set address to $8000, 21 | ldy #>$8000 ; this is the position in the bank where the config is being stored, ie top of bank) 22 | jsr $df8c 23 | ldx #0 24 | efaddr1=*+1 25 | : lda $5100,x ; this is where the config is positioned. 26 | jsr $df95 ; write byte to ef, $0305 to $8000, $0306 to $8001, etc. 27 | inx 28 | bne :- 29 | inc efaddr1+1 30 | lda efaddr1+1 31 | cmp #$5c 32 | bne :- 33 | lda #$51 34 | sta efaddr1+1 35 | 36 | lda #$04 ; cart off. 37 | sta $de02 38 | rts 39 | 40 | ;---------------------------------------------------------------------- 41 | delay_500ms: 42 | ldy #0 43 | ldx #0 44 | : inx 45 | bne :- 46 | dey 47 | bne :- 48 | rts 49 | delay_1500ms: 50 | jsr delay_500ms ; delay 0.5 seconds 51 | jsr delay_500ms ; delay 0.5 seconds 52 | jsr delay_500ms ; delay 0.5 seconds 53 | rts 54 | 55 | ;---------------------------------------------------------------------- 56 | easyflash_read_config: 57 | jsr easyflash_init 58 | 59 | ; lda #$30 ; bank $30 (this is where the config is going to be stored). 60 | ; ldy #$80 ; lorom 61 | ; jsr $df83 ; erase sector (banks 30:0, 31:0, 32:0, 33:0, 34:0, 35:0, 36:0 and 37:0 are set to $ff) 62 | ; jsr delay_1500ms ; delay 1.5 seconds after erase to let c64 physically finish its job for compatibility. 63 | 64 | lda #$30 ; set bank $30 for the next read/write command. 65 | jsr $df86 66 | lda #$b0 ; set bank mode to llll (continue to next lo bank after current lo bank is full) 67 | ldx #$00 ; set address to $8000, 68 | ldy #$80 ; this is the position in the bank where the config is being stored, ie top of bank) 69 | jsr $df8c 70 | ldx #$00 71 | 72 | : jsr $df92; read byte to ef, $0305 to $8000, $0306 to $8001, etc. 73 | efaddr2=*+1 74 | sta $5100,x ; this is where the config is positioned. 75 | inx 76 | bne :- 77 | inc efaddr2+1 78 | lda efaddr2+1 79 | cmp #$5c 80 | bne :- 81 | lda #$51 82 | sta efaddr2+1 83 | 84 | lda #$04 ; cart off. 85 | sta $de02 86 | rts 87 | 88 | ;---------------------------------------------------------------------- 89 | easyflash_init: 90 | lda #$07 ; cart on. banks visible from $8000-$bfff 91 | sta $de02 92 | lda #$00 ; select bank 0. 93 | sta $de00 94 | ldx #$00 ; copy eapi driver from bank 0 to ram at $1800. (eapi is always at $b800 in bank 0). 95 | : lda $b800,x 96 | sta $cb00,x 97 | lda $b900,x 98 | sta $cc00,x 99 | lda $ba00,x 100 | sta $cd00,x 101 | inx 102 | bne :- 103 | jsr $cb14 ; init eapi driver. (routines copied to extra cart ram $df80-dfff) 104 | rts 105 | 106 | -------------------------------------------------------------------------------- /src/diskcmd.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2020, Craig Smith, alwyz. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; Disk Command 7 | ; 8 | 9 | ;---------------------------------------------------------------------- 10 | txt_diskcommand: 11 | .byte WHITE,CR 12 | .byte "#" 13 | txt_diskcommand_devno: 14 | .byte "**" 15 | .byte "> " 16 | .byte CSR_LEFT,CSR_LEFT,CSR_LEFT,CSR_LEFT,CSR_LEFT,CSR_LEFT,0 17 | int2dectab: 18 | .byte "8 " ; [XXX potential for optimization ($bdcd] 19 | .byte "9 " 20 | .byte "10" 21 | .byte "11" 22 | .byte "12" 23 | .byte "13" 24 | .byte "14" 25 | .byte "15" 26 | .byte "16" 27 | .byte "17" 28 | .byte "18" 29 | .byte "19" 30 | .byte "20" 31 | .byte "21" 32 | .byte "22" 33 | .byte "23" 34 | .byte "24" 35 | .byte "25" 36 | .byte "26" 37 | .byte "27" 38 | .byte "28" 39 | .byte "29" 40 | .byte "30" 41 | 42 | ;---------------------------------------------------------------------- 43 | handle_f5_diskcommand: 44 | jsr col80_pause 45 | jsr rs232_off 46 | jsr ercopn 47 | jsr text_color_save 48 | dskcmd 49 | lda device_disk 50 | sec 51 | sbc #$08 52 | asl a 53 | tay 54 | lda int2dectab,y 55 | sta txt_diskcommand_devno 56 | lda int2dectab+1,y 57 | sta txt_diskcommand_devno+1 58 | lda #txt_diskcommand 60 | ldx #36;1 - what does this do? limit length of command? 61 | jsr input 62 | beq drverr ; nothing entered, drive error code? 63 | lda inpbuf 64 | cmp #'#' ; drive 65 | beq chgdev 66 | jsr is_drive_present 67 | bmi drvext 68 | lda #CR ; exit 69 | jsr chrout 70 | lda inpbuf 71 | cmp #'$' ; directory 72 | bne drvsnd 73 | lda max 74 | ldx #inpbuf 76 | jmp dodir 77 | drvsnd 78 | ldx device_disk 79 | stx 612 ; dev# table, log#15 80 | ldx #LFN_DISK_CMD 81 | jsr chkout 82 | ldx #0 83 | drvlop 84 | lda inpbuf,x 85 | jsr chrout 86 | inx 87 | cpx max 88 | bne drvlop 89 | lda #CR 90 | jsr chrout 91 | drvext 92 | jsr clrchn 93 | jsr text_color_restore 94 | lda #CR 95 | jsr chrout 96 | jsr rs232_on 97 | jmp term_mainloop 98 | drverr 99 | jsr is_drive_present 100 | bmi drvext 101 | jsr clrchn 102 | ldx #LFN_DISK_CMD 103 | jsr chkin 104 | drver2 105 | jsr getin 106 | drver3 107 | jsr chrout 108 | cmp #CR 109 | bne drver2 110 | jsr clrchn 111 | jsr col80_wait 112 | jmp drvext 113 | 114 | ;---------------------------------------------------------------------- 115 | chgdev: 116 | ldy #1 117 | ldx inpbuf,y 118 | txa 119 | sec 120 | sbc #$30 121 | beq chgdv2 ; if first char is 0 as in 08 or 09 122 | cmp #$03 ; devices 10-29 "1x or 2x" 123 | bpl chgdv8 ; might be 8 or 9.. anything over 3 doesnt count here so lets try and see if it matches 8 or 9. 124 | clc ; definitely starts with 1 or 2 if it makes it this far 125 | adc #$09 ; $0a-$0b for device starting with 1x or 2x, convert to hex 126 | jmp chgdv2 127 | chgdv8 128 | cmp #$07 129 | bpl chgdv9 ; assume its 8 or 9, which is the only options when it starts with 8 or 9 130 | jmp drvext ; nope there was nothing in the 00-29 range 131 | chgdv2 iny ; get the second character 132 | sta drivetemp 133 | lda inpbuf,y 134 | sec 135 | sbc #'0' ; decimal petscii to hex, again... 136 | clc 137 | adc drivetemp 138 | chgdv9 139 | cmp #8 ; lowest drive # (8) 140 | bcc drvext 141 | cmp #30 ; highest drive # (30) 142 | bcs drvext 143 | tay ;y now holds complete hex of drive # 144 | lda device_disk 145 | pha 146 | sty device_disk 147 | sty 612 148 | jsr is_drive_present 149 | bmi chgdv3 150 | pla 151 | lda #CSR_UP 152 | jsr chrout 153 | jmp dskcmd 154 | chgdv3 155 | pla 156 | sta device_disk 157 | sta 612 158 | chgdv4 159 | lda #' ' 160 | jsr chrout 161 | lda #'-' 162 | jsr chrout 163 | lda #' ' 164 | jsr chrout 165 | ldy #0 166 | chgdv5 167 | lda $a1d0,y ;device not present 168 | php 169 | and #$7f 170 | jsr chrout 171 | plp 172 | bmi chgdv6 173 | iny 174 | bne chgdv5 175 | chgdv6 176 | jmp drvext 177 | -------------------------------------------------------------------------------- /src/misc2.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2020, Craig Smith, alwyz. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; Miscellaneous 2 7 | ; 8 | 9 | ;---------------------------------------------------------------------- 10 | SET_PETSCII 11 | txt_newpunter: 12 | .byte CR,CR,WHITE,"NEW Punter",0 13 | txt_up: 14 | .byte "Up",0 15 | txt_down: 16 | .byte "Down",0 17 | txt_load: 18 | .byte "load.",CR,0 19 | txt_enter_filename: 20 | .byte "Enter Filename: ",0 21 | txt_yellow: 22 | .byte CR,YELLOW," ",0 23 | txt_loading: 24 | .byte "loading: ",CYAN,0 25 | txt_press_c_to_abort: 26 | .byte CR,WHITE," (Press C= to abort.)",CR,CR,0 27 | txt_aborted: 28 | .byte "Aborted.",CR,0 29 | txt_good_bad_blocks: 30 | .byte LTGREEN," ","Good Blocks: ",WHITE,"000",WHITE," - " 31 | .byte LTGREEN,"Bad Blocks: ",WHITE,"000",CR,0 32 | txt_graphics: 33 | .byte LTGREEN,"PETSCII",0 34 | txt_ascii: 35 | .byte CYAN,"ASCII",0 36 | txt_terminal_ready: 37 | .byte " Mode Ready.",LTGRAY,CR,CR,0 38 | txt_disconnecting: 39 | .byte CR,CR,WHITE,"Disconnecting...",LTGRAY,CR,CR,0 40 | SET_ASCII 41 | 42 | ;---------------------------------------------------------------------- 43 | drtype: .byte "DSPUR" 44 | drtyp2: .byte "EERSE" 45 | drtyp3: .byte "LQGSL" 46 | 47 | ;---------------------------------------------------------------------- 48 | directory_format: 49 | .byte YELLOW 50 | .byte $02 ; ctrl-b: blocks 51 | .byte 157 52 | .byte 157 53 | .byte WHITE 54 | .byte $06 ; ctrl-f: file type 55 | .byte " " 56 | .byte CYAN 57 | .byte $0e ; ctrl-n: file name 58 | .byte LTGREEN 59 | .byte " " 60 | .byte 63 61 | .byte " " 62 | .byte 0 63 | directory_format_end: 64 | 65 | ;---------------------------------------------------------------------- 66 | aciaemu_filename: 67 | .byte $08 ; 2400 baud 68 | .byte $00 69 | 70 | .byte $51,$0d ; [XXX unused] 71 | 72 | aciaemu_filename_len: 73 | .byte 2 ; [XXX only read; should be constant] 74 | 75 | filename_i0: 76 | .byte "I0" 77 | 78 | ; device number of the (first) disk drive 79 | device_disk: 80 | .byte 8 81 | 82 | ; is a drive present in the system 83 | drive_present: 84 | .byte 1 85 | 86 | config_file_loaded: 87 | .byte 0 88 | 89 | prev_char: 90 | .byte 0 91 | 92 | newbuf .word endprg 93 | 94 | ; System Timing 95 | ; 0: NTSC 96 | ; 1: PAL 97 | is_pal_system: 98 | .byte 0 99 | 100 | ; SuperCPU detected 101 | ; 0: no SuperCPU 102 | ; 1: SuperCPU detected 103 | ; 2: SuperCPU detected, message already printed (don't print again) 104 | supercpu: 105 | .byte 0 106 | 107 | SET_PETSCII 108 | txt_supercpu_enabled: 109 | .byte "SuperCPU Enabled!",CR,CR,0 110 | SET_ASCII 111 | 112 | nicktemp: 113 | .byte 0 ; [XXX unused] 114 | 115 | drivetemp: 116 | .byte 0 117 | 118 | ;---------------------------------------------------------------------- 119 | ; pre-calculate CRC16 tables for XMODEM-CRC 120 | crctable: 121 | ldx #0 122 | txa 123 | : sta crclo,x 124 | sta crchi,x 125 | inx 126 | bne :- 127 | ldx #0 128 | @1: txa 129 | eor crchi,x 130 | sta crchi,x 131 | ldy #8 132 | @2: asl crclo,x 133 | rol crchi,x 134 | bcc @3 135 | lda crchi,x 136 | eor #$10 137 | sta crchi,x 138 | lda crclo,x 139 | eor #$21 140 | sta crclo,x 141 | @3: dey 142 | bne @2 143 | inx 144 | bne @1 145 | rts 146 | 147 | ;---------------------------------------------------------------------- 148 | ; SuperCPU 149 | supercpu_on: 150 | lda supercpu 151 | beq scpuout 152 | lda #1 153 | sta $d07b 154 | scpuout rts 155 | 156 | supercpu_off: 157 | lda supercpu 158 | beq scpuout 159 | lda #1 160 | sta $d07a 161 | rts 162 | 163 | ;---------------------------------------------------------------------- 164 | ; [XXX this should be closer to the PUNTER code] 165 | puntdelay: 166 | ; you got a better way to do this? have at it! 167 | pha 168 | txa 169 | pha 170 | tya 171 | pha 172 | ldx #0 173 | ldy #0 174 | : inx 175 | bne :- 176 | iny 177 | bne :- 178 | pla 179 | tay 180 | pla 181 | tax 182 | pla 183 | rts 184 | -------------------------------------------------------------------------------- /test/xfer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "inout.h" 6 | 7 | extern int xmodemTransmit(unsigned char *src, int srcsz, int use_1k); 8 | extern int xmodemReceive(unsigned char *dest, int destsz, int crc); 9 | extern int punter_xmit(void *data, int len); 10 | extern int punter_recv(void); 11 | 12 | unsigned char *data_out_punter; 13 | int data_out_punter_index; 14 | // PUNTER callback 15 | int xfer_save_data(unsigned char *data, int length) { 16 | memcpy(data_out_punter + data_out_punter_index, data, length); 17 | data_out_punter_index += length; 18 | return length; 19 | } 20 | 21 | 22 | FILE *f; 23 | 24 | void 25 | automate(char *s) { 26 | printf("\x03%s\x03", s); 27 | fflush(stdout); 28 | } 29 | 30 | char * 31 | config_str(int i) { 32 | switch (i) { 33 | case 0: return "XMODEM"; 34 | case 1: return "XMODEM-CRC"; 35 | case 2: return "XMODEM-1K"; 36 | } 37 | return NULL; 38 | } 39 | 40 | int 41 | main(int argc, char **argv) { 42 | char *fn_in = "crc16.h"; // just under 2 KB 43 | 44 | f = fopen(fn_in, "rb"); 45 | fseek(f, 0L, SEEK_END); 46 | long size_in = ftell(f); 47 | rewind(f); 48 | unsigned char *data_in = malloc(size_in); 49 | fread(data_in, 1, size_in, f); 50 | fclose(f); 51 | int capacity = size_in * 2; 52 | 53 | data_out_punter = malloc(capacity); 54 | unsigned char *data_out1 = malloc(capacity); 55 | unsigned char *data_out2 = malloc(capacity); 56 | 57 | int failed = 0; 58 | 59 | sleep(4); 60 | printf("\r\nxfer test...\r\n"); 61 | fflush(stdout); 62 | sleep(1); 63 | 64 | #define F1 "\x85" 65 | #define F3 "\x86" 66 | #define F7 "\x88" 67 | #define CR "\r" 68 | 69 | // PUNTER DOWNLOAD 70 | automate(F3 "A" CR); 71 | sleep(1); 72 | punter_xmit(data_in, size_in); 73 | 74 | sleep(5); 75 | 76 | // PUNTER UPLOAD 77 | automate(F1 "A" CR); 78 | sleep(1); 79 | data_out_punter_index = 0; 80 | punter_recv(); 81 | sleep(8); 82 | 83 | // compare input and output 84 | int good = !memcmp(data_in, data_out_punter, size_in); 85 | fprintf(stderr, "***** TEST_XFER: PUNTER %s\n", good ? "OK" : "BAD"); 86 | if (!good) { 87 | failed++; 88 | } 89 | 90 | for (int i = 0; i < 3; i++) { 91 | // switch protocol 92 | // 0: XMODEM 93 | // 1: XMODEM-CRC 94 | // 2: XMODEM-1K 95 | automate(F7 "P" CR); // // "F7", "P", "RETURN" 96 | sleep(1); 97 | 98 | // XMODEM 512B DOWNLOAD 99 | automate(F3 "B" CR "P" CR); 100 | sleep(1); 101 | xmodemTransmit(data_in, size_in, 0); 102 | sleep(4); 103 | 104 | // XMODEM CHKSUM UPLOAD 105 | automate(F1 "B" CR); 106 | sleep(1); 107 | int size_out1 = xmodemReceive(data_out1, capacity, 0); 108 | sleep(4); 109 | 110 | // compare input and output 111 | good = !memcmp(data_in, data_out1, size_in); 112 | fprintf(stderr, "***** TEST_XFER: XMODEM; client: %s, server: 512B/CHKSUM: %s\n", config_str(i), good ? "OK" : "BAD"); 113 | if (!good) { 114 | failed++; 115 | } 116 | 117 | // XMODEM 1KB DOWNLOAD 118 | automate(F3 "C" CR "P" CR); 119 | sleep(1); 120 | xmodemTransmit(data_in, size_in, 1); 121 | sleep(4); 122 | 123 | // XMODEM CRC16 UPLOAD 124 | automate(F1 "C" CR); 125 | sleep(1); 126 | int size_out2 = xmodemReceive(data_out2, capacity, 0); 127 | sleep(4); 128 | 129 | int good = !memcmp(data_in, data_out2, size_in); 130 | fprintf(stderr, "***** TEST_XFER: XMODEM; client: %s, server: 1KB/CRC16: %s\n", config_str(i), good ? "OK" : "BAD"); 131 | if (!good) { 132 | failed++; 133 | } 134 | } 135 | if (failed == 0) { 136 | fprintf(stderr, "***** TEST_XFER: Succeeded!\n"); 137 | printf("\r\nxfer test succeeded!\r\n"); 138 | fflush(stdout); 139 | } else { 140 | fprintf(stderr, "***** TEST_XFER: Failed!\n"); 141 | printf("\r\nxfer test failed!\r\n"); 142 | fflush(stdout); 143 | } 144 | } 145 | 146 | // fprintf(stderr, "***** SERVER: data_out_punter_index %d\n", data_out_punter_index); 147 | // f = fopen("/tmp/xxx", "wb"); 148 | // fwrite(data_out_punter, 1, data_out_punter_index, f); 149 | // fclose(f); 150 | -------------------------------------------------------------------------------- /test/crc16.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2001-2010 Georges Menie (www.menie.org) 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the University of California, Berkeley nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "crc16.h" 29 | 30 | /* CRC16 implementation acording to CCITT standards */ 31 | 32 | static const unsigned short crc16tab[256]= { 33 | 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7, 34 | 0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef, 35 | 0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6, 36 | 0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de, 37 | 0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485, 38 | 0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d, 39 | 0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4, 40 | 0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc, 41 | 0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823, 42 | 0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b, 43 | 0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12, 44 | 0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a, 45 | 0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41, 46 | 0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49, 47 | 0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70, 48 | 0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78, 49 | 0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f, 50 | 0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067, 51 | 0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e, 52 | 0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256, 53 | 0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d, 54 | 0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405, 55 | 0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c, 56 | 0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634, 57 | 0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab, 58 | 0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3, 59 | 0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a, 60 | 0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92, 61 | 0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9, 62 | 0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1, 63 | 0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8, 64 | 0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0 65 | }; 66 | 67 | unsigned short crc16_ccitt(const void *buf, int len) 68 | { 69 | register int counter; 70 | register unsigned short crc = 0; 71 | for( counter = 0; counter < len; counter++) 72 | crc = (crc<<8) ^ crc16tab[((crc>>8) ^ *(char *)buf++)&0x00FF]; 73 | return crc; 74 | } 75 | -------------------------------------------------------------------------------- /rs232lib/rs232.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2022, Craig Smith, alwyz, Michael Steil. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; RS232 Driver Dispatch 7 | ; 8 | 9 | .include "rs232_kernal.inc" 10 | .include "rs232.inc" 11 | 12 | ; settings 13 | .import modem_type, baud_rate, is_pal_system 14 | 15 | ; drivers 16 | .import rsuser_funcs, up9600_funcs, sw_funcs 17 | .export rs232_rti 18 | 19 | tmpzp = $a7 ; reused KERNAL RS-232 driver var 20 | ram_flag = $f9 ; reused KERNAL RS-232 driver var 21 | 22 | .segment "RS232" 23 | 24 | ;---------------------------------------------------------------------- 25 | ; Dispatch: Init modem 26 | rs232_init: 27 | jsr setup_ram_irq_nmi 28 | 29 | ldx #MODEM_TYPE_SWIFTLINK_DE 30 | lda modem_type 31 | cmp #MODEM_TYPE_SWIFTLINK_DE 32 | bcc :+ 33 | txa 34 | : asl 35 | tax 36 | lda modem_drivers,x 37 | sta tmpzp 38 | lda modem_drivers+1,x 39 | sta tmpzp+1 40 | ldx #1 41 | ldy #0 42 | : lda (tmpzp),y 43 | sta rs232_funcs,x 44 | iny 45 | inx 46 | lda (tmpzp),y 47 | sta rs232_funcs,x 48 | iny 49 | inx 50 | inx 51 | cpy #2*6 52 | bne :- 53 | 54 | lda modem_type 55 | ldx baud_rate 56 | ldy is_pal_system 57 | jsr func_setup 58 | jmp rs232_clear 59 | 60 | rs232_funcs: 61 | func_setup: 62 | jmp $ffff 63 | func_enable: 64 | jmp $ffff 65 | func_disable: 66 | jmp $ffff 67 | func_getxfer: 68 | jmp $ffff 69 | func_putxfer: 70 | jmp $ffff 71 | func_dropdtr: 72 | jmp $ffff 73 | 74 | .res 6*2 75 | 76 | modem_drivers: 77 | .word rsuser_funcs ; MODEM_TYPE_USERPORT 78 | .word up9600_funcs ; MODEM_TYPE_UP9600 79 | .word sw_funcs ; MODEM_TYPE_SWIFTLINK_DE, ... 80 | 81 | ;---------------------------------------------------------------------- 82 | ; Dispatch: Enable 83 | rs232_on: 84 | pha 85 | txa 86 | pha 87 | tya 88 | pha 89 | jsr func_enable 90 | jmp xferout 91 | 92 | ;---------------------------------------------------------------------- 93 | ; Dispatch: Disable 94 | rs232_off: 95 | pha 96 | txa 97 | pha 98 | tya 99 | pha 100 | jsr func_disable 101 | xferout: 102 | pla 103 | tay 104 | pla 105 | tax 106 | pla 107 | rts 108 | 109 | ;---------------------------------------------------------------------- 110 | ; Dispatch: Get byte from modem 111 | rs232_get: 112 | jsr func_getxfer 113 | pha 114 | php 115 | lda #0 116 | rol 117 | sta STATUS ; some callers want STATUS set 118 | plp ; others want C set on error/no data 119 | pla 120 | rts 121 | 122 | ;---------------------------------------------------------------------- 123 | ; Dispatch: Send byte to modem 124 | rs232_put: 125 | pha 126 | lda #0 127 | sta STATUS 128 | pla 129 | jmp func_putxfer 130 | 131 | ;---------------------------------------------------------------------- 132 | ; Dispatch: Hang up 133 | rs232_dropdtr = func_dropdtr 134 | 135 | ;---------------------------------------------------------------------- 136 | ; Clear RS232 buffer 137 | rs232_clear: 138 | pha 139 | lda #0 140 | sta rtail 141 | sta rhead 142 | sta rfree 143 | pla 144 | rts 145 | 146 | ;---------------------------------------------------------------------- 147 | setup_ram_irq_nmi: 148 | lda #0 149 | sta ram_flag 150 | lda #ramnmi 153 | sta $fffb 154 | lda #ramirq 157 | sta $ffff 158 | rts 159 | 160 | ;---------------------------------------------------------------------- 161 | ; high-speed version to minimize NMI latency 162 | ramnmi: 163 | inc $01 164 | dec ram_flag 165 | jmp ($0318) 166 | rs232_rti: 167 | bit ram_flag 168 | bpl :+ 169 | inc ram_flag 170 | dec $01 171 | : rti 172 | 173 | ;---------------------------------------------------------------------- 174 | ; low-speed version - IRQs are not timing critical 175 | ramirq: 176 | pha 177 | lda $01 178 | pha 179 | lda #$37 180 | sta $01 181 | lda #>ramirq2 182 | pha 183 | lda #$d800)-(>$0400) 222 | sta locat+1 223 | lda (locat),y ; read color 224 | and #15 225 | rts 226 | -------------------------------------------------------------------------------- /src/declare.inc: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2020, Craig Smith, alwyz. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; Global constants 7 | ; 8 | 9 | numfil = $98 10 | locat = $fb 11 | nlocat = $fd 12 | 13 | backgr = $d021 14 | border = $d020 15 | 16 | textcl = 646 17 | scrtop = 648 18 | LINE = 214 19 | COLUMN = 211 20 | llen = 213 21 | qmode = 212 22 | imode = 216 23 | 24 | BCOLOR = 0 25 | TCOLOR = 15 26 | 27 | ascii_mode = $0313 ; PETSCII or ASCII 28 | 29 | revtabup = $0380 30 | 31 | ; Please keep this in sync with Internals.md#Memory_Map 32 | 33 | buftop = $c7fd 34 | bufptrreu = $c7fe 35 | buffstreu = $c7ff 36 | xmodem_buffer = $c800; 1 KB, overlaps with mulfil 37 | mulfil = $cb00 ; punter only 38 | endmulfil = $cc00 ;end area for multipunter 39 | crclo = $cc00 ; temp for runtime tables;use tempbuf and numbuf 40 | crchi = $cd00 ; temp for runtime tables 41 | tempbuf = $cc00 ; dialer temp buf to print on screen after connect. check for busy and all that. 42 | numbuf = $cd00 ; dialer number buffer. holds phone number and port number 43 | codebuf = $cd00 ; punter buffer. can use same area as xmodem crc hi and phone buffer 44 | ribuf = $ce00 ; rs232 receive input buffer (we don't use an output buffer) 45 | inpbuf = $cf00 46 | SCREENS_BASE = $e000 ; 4 saved screens 47 | 48 | tmp07e8 = $07e8 ; temp. filename storage for file selection from directory 49 | mulskp = $07fc 50 | mlsall = $07fd 51 | mulfln = $07fe 52 | mulcnt = $07ff 53 | 54 | rtail = RIDBE ; friendlier name 55 | rhead = RIDBS ; friendlier name 56 | rfree = RODBS ; re-purposed; SwiftLink only 57 | 58 | ; zero page 59 | tmp02 = $02 60 | max = $02 61 | tmp03 = $03 62 | tmp04 = $04 63 | tempch = $05 ; saved character 64 | tmp05 = $05 65 | tempcl = $06 ; saved character color 66 | tmp06 = $06 67 | begpos = $07 68 | tmp0b = $0b 69 | bufflg = $0b ; $80: 0: disk, 1: buffer; $40: 1: delay 70 | buffl2 = $0c 71 | buffer_open = $10 72 | half_duplex = $12 73 | zpoutstr = $22 ; 2 bytes 74 | tmp9e = $9e 75 | tmp9f = $9f 76 | endpos = $ac 77 | buffer_ptr = $b0 ; 2 bytes 78 | buffst = $b2 79 | tmpfd = $fd 80 | cursor_flag = $fe 81 | 82 | ; BASIC symbols 83 | outnum = $bdcd 84 | 85 | ; KERNAL symbols 86 | status = $90 87 | DFLTN = $99 88 | DFLTO = $9a 89 | JIFFIES = $a2 ; TIME+2 90 | FA = $ba 91 | LSTX = $c5 ; last key pressed 92 | NDX = $c6 ; number of characters in keyboard queue 93 | BLNSW = $cc ; cursor blinking 94 | LDTB1 = $d9 ; screen line link table 95 | KEYD = $0277 ; keyboard buffer 96 | RPTFLA = $028a ; key repeat flag 97 | KOUNT = $028b ; counter for timing delay between key repeats 98 | SHFLAG = $028d ; bitfield: modifier keys currently pressed 99 | SHFLAG_SHIFT = 1 100 | SHFLAG_CBM = 2 101 | SHFLAG_CTRL = 4 102 | KEYLOG = $028f 103 | MODE = $0291 104 | RIDBE = $029b 105 | RIDBS = $029c 106 | RODBS = $029d 107 | RODBE = $029e 108 | ENABL = $02a1 109 | 110 | untalk = $ffab 111 | unlstn = $ffae 112 | load = $ffd5 113 | save = $ffd8 114 | setlfs = $ffba 115 | setnam = $ffbd 116 | open = $ffc0 117 | chkin = $ffc6 118 | chkout = $ffc9 119 | chrin = $ffcf 120 | chrout = $ffd2 121 | getin = $ffe4 122 | close = $ffc3 123 | clrchn = $ffcc 124 | clall = $ffe7 125 | readst = $ffb7 126 | plot = $fff0 127 | listen = $ffb1 128 | second = $ff93 129 | talk = $ffb4 130 | tksa = $ff96 131 | unlsn = $ffae 132 | untlk = $ffab 133 | acptr = $ffa5 134 | ciout = $ffa8 135 | rstkey = $fe56 136 | norest = $fe72 137 | return = $febc 138 | oldout = $f1ca 139 | oldchk = $f21b 140 | ochrin = $f157 141 | ogetin = $f13e 142 | findfn = $f30f 143 | devnum = $f31f 144 | nofile = $f701 145 | COLTAB = $e8da ; PETSCII codes for the colors 0-15 146 | LDTB2 = $ecf0 ; line offsets low 147 | 148 | ; logical file numbers 149 | LFN_FILE = 2 ; for upload/download 150 | LFN_PRINTER = 4 ; printing buffers 151 | LFN_DIR = 13 152 | LFN_DISK_CMD = 15 153 | 154 | DEV_MODEM = $02 ; modem device 155 | SA_MODEM = $03 ; modem secondary address 156 | 157 | HILITE = $02 ; extension: draw next char reverse 158 | SETCSR = $03 159 | CR = $0d 160 | LCKCASE = $08 161 | LOCASE = $0e 162 | CSR_DOWN = $11 163 | RVSON = $12 164 | HOME = $13 165 | DEL = $14 166 | CSR_RIGHT = $1d 167 | CSR_UP = $91 168 | RVSOFF = $92 169 | CLR = $93 170 | INST = $94 171 | CSR_LEFT = $9d 172 | UNDERLINE = $a4 173 | 174 | BLACK = $90 175 | WHITE = $05 176 | RED = $1c 177 | CYAN = $9f 178 | PURPLE = $9c 179 | GREEN = $1e 180 | BLUE = $1f 181 | YELLOW = $9e 182 | ORANGE = $81 183 | BROWN = $95 184 | LTRED = $96 185 | DKGRAY = $97 186 | GRAY = $98 187 | LTGREEN = $99 188 | LTBLUE = $9a 189 | LTGRAY = $9b 190 | 191 | CURSOR = '_' ; cursor, ASCII "_" 192 | 193 | PROTOCOL_PUNTER = 0 194 | PROTOCOL_XMODEM = 1 195 | PROTOCOL_XMODEM_CRC = 2 196 | PROTOCOL_XMODEM_1K = 3 197 | -------------------------------------------------------------------------------- /src/ansi.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2020, Craig Smith, alwyz. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; ASCII/PETSCII conversion and ANSI control code emulation 7 | ; 8 | 9 | ; 0: not escape mode 10 | ; 1: ESC encountered 11 | ; 2: ESC-set-color encountered 12 | ansi_escape_mode: 13 | .byte 0 14 | 15 | ansitemp: 16 | .byte 0 17 | 18 | ansi_color_table: 19 | .byte 0 20 | 21 | ansi0colors: 22 | .byte RVSOFF,RED,GREEN,BROWN,BLUE,PURPLE,CYAN,GRAY,0,0,0 23 | ansi1colors: 24 | .byte DKGRAY,LTRED,LTGREEN,YELLOW,LTBLUE,PURPLE,CYAN,WHITE,0,0,0 25 | 26 | ;---------------------------------------------------------------------- 27 | ; Convert an ASCII character to PETSCII; interpret ANSI control codes 28 | ascii_to_petscii: 29 | pha 30 | lda ansi_escape_mode 31 | jeq plain_mode ; not in ANSI escape mode, check for it 32 | 33 | ; in ANSI escape mode 34 | cmp #2 ; is ansi color code on? 35 | beq coloron2 36 | 37 | pla 38 | cmp #'2' 39 | beq ansi_clrhome 40 | cmp #'3' 41 | beq ansi_set_color_mode 42 | cmp #'4' 43 | beq ansi_set_color_mode ; ansi_rvs_on when we figure out rvs 44 | cmp #'0' 45 | beq ansi_set_color_table_0 46 | cmp #'7' 47 | beq ansi_rvs_on ; rvs 48 | cmp #'1' 49 | beq ansi_set_color_table_1 50 | cmp #';' 51 | jeq ansi_semicolon 52 | cmp #'[' 53 | beq ansi_leftbracket ; [ after escape code 54 | cmp #'M' 55 | bne :+ 56 | @end: jmp ansi_end ; [XXX beq @end] 57 | : cmp #'m' 58 | beq @end 59 | cmp #'J' 60 | beq ansi_end 61 | cmp #'j' 62 | beq ansi_end 63 | cmp #'H' 64 | beq ansi_end 65 | cmp #'h' 66 | beq ansi_end 67 | cmp #']' 68 | beq ansi_return_0 69 | jmp ansi_return ; out of ideas,move on 70 | 71 | ansi_set_color_table_0: 72 | lda #0 73 | sta ansi_color_table 74 | jmp ansi_return_0 75 | 76 | ansi_set_color_table_1: 77 | lda #1 78 | sta ansi_color_table 79 | jmp ansi_return_0 80 | 81 | ansi_rvs_on: 82 | lda #1 ; escape mode stays on 83 | sta ansi_escape_mode 84 | lda #RVSON 85 | jmp ansi_return 86 | 87 | ansi_clrhome: 88 | lda #1 ; escape mode stays on 89 | sta ansi_escape_mode 90 | lda #CLR 91 | jmp ansi_return 92 | 93 | ansi_leftbracket: ; ansi is on and got the left bracket 94 | lda #1 ; escape mode stays on 95 | sta ansi_escape_mode 96 | lda #0 ; display nothing and move on in ansi mode 97 | jmp ansi_return 98 | 99 | ansi_set_color_mode: 100 | lda #2 101 | sta ansi_escape_mode 102 | ansi_return_0: 103 | lda #0 104 | jmp ansi_return 105 | 106 | ; in ANSI escape *color* mode 107 | coloron2: 108 | lda ansi_color_table 109 | beq @1 110 | 111 | ; color table 1 112 | lda #0 113 | sta ansi_color_table 114 | pla 115 | sec 116 | sbc #'0' 117 | tay 118 | lda #1 119 | sta ansi_escape_mode 120 | lda ansi1colors,y 121 | jmp ansi_return 122 | 123 | ; color table 0 124 | @1: pla 125 | sec 126 | sbc #'0' 127 | tay 128 | lda #1 129 | sta ansi_escape_mode 130 | lda ansi0colors,y 131 | jmp ansi_return 132 | 133 | ansi_semicolon: 134 | lda #1 ; escape mode stays on 135 | sta ansi_escape_mode 136 | lda #0 137 | jmp ansi_return 138 | 139 | ansi_end: 140 | lda #0 141 | sta ansi_escape_mode 142 | jmp ansi_return 143 | 144 | ; not in ANSI escape mode 145 | plain_mode: 146 | pla 147 | cmp #27 ; ESC: ANSI escape code 148 | beq :+ 149 | jmp plain_char ; [XXX bne plain_char] 150 | 151 | : lda #1 152 | sta ansi_escape_mode 153 | lda #0 154 | jmp ansi_return 155 | 156 | plain_char: 157 | cmp #UNDERLINE 158 | bne @0 159 | lda #UNDERLINE ; [XXX remove] 160 | bne ansi_return 161 | @0: and #$7f 162 | cmp #'z'+1 163 | bcs ansi_return 164 | cmp #'a' 165 | bcc @1 166 | sbc #' ' 167 | bne ansi_return 168 | @1: cmp #'A' 169 | bcc @2 170 | cmp #'Z'+1 171 | bcs ansi_return 172 | adc #$80 173 | bne ansi_return 174 | @2: cmp #8 ; backspace 175 | bne @3 176 | lda #DEL 177 | @3: cmp #$0c ; form feed 178 | bne @4 179 | lda #CLR 180 | @4: cmp #' ' 181 | bcs ansi_return 182 | cmp #7 ; bell 183 | beq ansi_return 184 | cmp #CR 185 | beq ansi_return 186 | cmp #DEL 187 | beq ansi_return ; [XXX] 188 | bne ansi_return_0b 189 | 190 | ansi_return: 191 | cmp #0 192 | rts 193 | ansi_return_0b: ; [XXX duplicate] 194 | lda #0 195 | beq ansi_return 196 | 197 | ;---------------------------------------------------------------------- 198 | ; Convert PETSCII to ASCII 199 | petscii_to_ascii: 200 | cmp #DEL 201 | bne @0 202 | lda #8 ; ctrl-h (backspace) 203 | bne @exit 204 | 205 | @0: cmp #UNDERLINE ; [XXX no-op] 206 | bne @1 ; [XXX no-op] 207 | lda #UNDERLINE ; [XXX no-op] 208 | @1: cmp #'A' 209 | bcc ansi_return ; if < then no conv 210 | cmp #'Z'+1 211 | bcs @2 212 | adc #' ' ; lower a...z..._ 213 | bne @exit 214 | 215 | @2: cmp #' '+$80 216 | bne @3 217 | lda #' ' ; shift to space 218 | bne @exit 219 | 220 | @3: and #$7f 221 | cmp #'A' 222 | bcc ansi_return_0b 223 | cmp #'a' ; upper a...z 224 | bcs ansi_return_0b 225 | @exit: cmp #0 226 | rts 227 | -------------------------------------------------------------------------------- /src/init.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2020, Craig Smith, alwyz. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; Initialization 7 | ; 8 | 9 | ; PAL/NTSC detection 10 | start: 11 | @1: lda $d012 12 | @2: cmp $d012 13 | beq @2 14 | bmi @1 15 | cmp #$20 16 | bcc :+ ; NTSC 17 | ldx #1 18 | stx is_pal_system 19 | : 20 | 21 | ; SuperCPU detection 22 | ; "it should just tell you to turn that shit off. 23 | ; who needs 20MHz for 9600 baud, anyway?" 24 | lda $d0bc 25 | asl a 26 | bcs :+ 27 | lda #1 28 | sta supercpu 29 | : 30 | 31 | ; system setup 32 | jsr $e3bf ; refresh basic reset - mostly an easyflash fix 33 | sei 34 | cld 35 | ldx #$ff 36 | txs 37 | lda #$2f 38 | sta $00 39 | lda #$37 40 | sta $01 41 | 42 | jsr col80_init 43 | 44 | ; editor/screen setup 45 | lda #1 46 | sta BLNSW ; disable cursor blinking 47 | lda #BCOLOR 48 | sta backgr 49 | sta border 50 | lda #TCOLOR 51 | sta textcl 52 | 53 | lda #$80 54 | sta RPTFLA ; key repeat on 55 | lda #$0e 56 | sta $d418 ; *almost* full volume 57 | 58 | bit col80_active 59 | bmi :+ 60 | jsr clear_screens 61 | : 62 | cli 63 | 64 | ; find first disk drive 65 | lda FA ; current dev# 66 | jmp @dsk1 67 | @loop: inc device_disk 68 | lda device_disk 69 | cmp #16 ; try #30 here for top drive #? 70 | beq :+ 71 | jmp @dsk1 72 | : lda #0 73 | sta drive_present; we have no drives 74 | lda #8 75 | sta device_disk 76 | jmp @dsk2 77 | @dsk1: sta device_disk 78 | jsr is_drive_present 79 | bmi @loop 80 | lda #1 81 | sta drive_present; we have a drive! 82 | @dsk2: 83 | 84 | ; REU detection 85 | lda easyflash_support 86 | beq @ef1 ; skip REU detection if we have EasyFlash 87 | jsr noreu 88 | jmp @ef2 89 | @ef1: 90 | jsr reu_detect 91 | @ef2: 92 | 93 | ; init. buffer & open rs232 94 | lda newbuf 95 | sta buffer_ptr 96 | lda newbuf+1 97 | sta buffer_ptr+1 98 | 99 | jsr rsopen 100 | jsr ercopn 101 | jmp init ; [XXX the next two functions are in the way] 102 | 103 | ;---------------------------------------------------------------------- 104 | ; open rs232 file 105 | ; [XXX This used to open a channel on device #2, which most serial ] 106 | ; [XXX communication went through. Now, this doesn't do much any ] 107 | ; [XXX more, but it's still called from several places, which is ] 108 | ; [XXX probably not necessary. ] 109 | ; [XXX It needs to be called once though ("jsr rsopen" above!) to ] 110 | ; [XXX init the RS232 dispatch jump table. ] 111 | rsopen: 112 | jsr rs232_init 113 | jsr clall 114 | jsr rs232_off 115 | rts ; [XXX jmp] 116 | 117 | ;---------------------------------------------------------------------- 118 | ercopn: 119 | lda drive_present 120 | beq :+ 121 | lda #2;file length ;open err chan 122 | ldx #filename_i0 124 | jsr setnam 125 | lda #15 126 | ldx device_disk 127 | tay 128 | jsr setlfs 129 | jsr open 130 | : rts 131 | 132 | ;---------------------------------------------------------------------- 133 | init 134 | lda #1 135 | sta cursor_flag ; non-destructive 136 | lda #0 137 | sta $9d ; suppress all KERNAL messages 138 | sta ascii_mode ; PETSCII mode 139 | ;sta allcap ; upper/lower 140 | sta buffer_open 141 | sta half_duplex ; full duplex 142 | lda #$93 143 | jsr chrout ; clear screen 144 | lda config_file_loaded; already loaded config file? 145 | bne @noload 146 | lda drive_present 147 | beq @noload ; no drive exists 148 | 149 | ; load config file from disk 150 | jsr rs232_off 151 | lda #1 152 | sta config_file_loaded 153 | ldx #filename_config 155 | lda #11 156 | jsr setnam 157 | lda #2 158 | ldx device_disk 159 | ldy #0 160 | jsr setlfs 161 | jsr load_config_file 162 | 163 | @noload: 164 | jmp term_entry_first 165 | 166 | ;---------------------------------------------------------------------- 167 | ; clear secondary screens 168 | .export clear_screens 169 | clear_screens: 170 | lda #SCREENS_BASE 173 | sta locat+1 174 | lda #$20 175 | ldy #0 176 | ldx #4*8-1 ; 4 screens, 8 pages (4 scr, 4 col) minus last one 177 | : sta (locat),y 178 | iny 179 | bne :- 180 | inc locat+1 181 | dex 182 | bne :- 183 | ; only clear the necessary part of the last page 184 | ; so we don't overwrite the $fffa-$ffff NMI & IRQ vectors 185 | : sta SCREENS_BASE+(4*8-1)*256,x 186 | inx 187 | cpx #<1000 188 | bne :- 189 | rts 190 | 191 | ;---------------------------------------------------------------------- 192 | get_charset: 193 | bit col80_active 194 | bpl :+ 195 | lda #2 196 | rts 197 | : lda $d018 198 | and #2 199 | rts 200 | 201 | ;---------------------------------------------------------------------- 202 | set_bgcolor_0: 203 | lda #0 204 | set_bgcolor: 205 | sta $d020 206 | sta $d021 207 | jmp col80_bg_update 208 | 209 | term80_toggle: 210 | lda col80_enabled 211 | eor #$80 212 | sta col80_enabled 213 | bne :+ 214 | jmp col80_off 215 | : jmp col80_on 216 | 217 | ;---------------------------------------------------------------------- 218 | .export col80_enabled 219 | col80_enabled: 220 | .byte 0 221 | -------------------------------------------------------------------------------- /src/banner.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2020, Craig Smith, alwyz. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; Startup message and instructions 7 | ; 8 | 9 | ;---------------------------------------------------------------------- 10 | print_banner: 11 | lda #txt_banner0a 13 | jsr outstr 14 | bit col80_active 15 | bmi :+ 16 | lda #txt_banner0b 18 | bne @1 19 | : lda #txt_banner0c 21 | @1: jsr outstr 22 | lda #txt_banner0d 24 | jsr outstr 25 | lda #txt_author 27 | jsr outstr 28 | ldx #80 29 | bit col80_active 30 | bmi :+ 31 | ldx #40 32 | : lda #$b7 ; UPPER ONE QUARTER BLOCK 33 | jsr chrout 34 | dex 35 | bne :- 36 | rts 37 | 38 | ;---------------------------------------------------------------------- 39 | print_instr: 40 | bit col80_enabled 41 | bmi @col80 42 | lda #txt_banner1a 44 | jsr outstr 45 | lda #txt_banner1b 47 | jsr outstr 48 | lda #txt_banner1c 50 | jsr outstr 51 | lda #txt_banner1d 53 | jsr outstr 54 | lda #txt_banner2a 56 | jsr outstr 57 | lda #txt_banner2b 59 | jsr outstr 60 | lda #13 61 | jsr chrout 62 | lda #txt_banner2c 64 | jsr outstr 65 | lda #txt_banner2d 67 | jsr outstr 68 | jmp @cont 69 | @col80: 70 | lda #txt_banner1a 72 | jsr outstr 73 | lda #txt_banner2a 75 | jsr outstr 76 | lda #13 77 | jsr chrout 78 | lda #txt_banner1b 80 | jsr outstr 81 | lda #txt_banner2b 83 | jsr outstr 84 | lda #13 85 | jsr chrout 86 | lda #txt_banner1c 88 | jsr outstr 89 | lda #txt_banner2c 91 | jsr outstr 92 | lda #13 93 | jsr chrout 94 | lda #txt_banner1d 96 | jsr outstr 97 | lda #txt_banner2d 99 | jsr outstr 100 | @cont: 101 | ldx ascii_mode 102 | bne @2 103 | lda #txt_graphics 105 | bne @3 106 | @2: lda #txt_ascii 108 | @3: jsr outstr 109 | lda #txt_terminal_ready 111 | jmp outstr 112 | 113 | ;---------------------------------------------------------------------- 114 | SET_PETSCII 115 | txt_banner0a: 116 | .byte CLR,LOCASE,LCKCASE,RVSON 117 | .byte 0 118 | txt_banner0b: ; 40 col version 119 | .byte WHITE," ",RED 120 | .byte " C " 121 | .byte ORANGE 122 | .byte " C " 123 | .byte YELLOW 124 | .byte " G " 125 | .byte GREEN 126 | .byte " M " 127 | .byte BLUE 128 | .byte " S " 129 | .byte PURPLE 130 | .byte " ! " 131 | .byte 0 132 | txt_banner0c: ; 80 col version 133 | .byte WHITE," " 134 | .byte RED 135 | .byte "C " 136 | .byte ORANGE 137 | .byte "C " 138 | .byte YELLOW 139 | .byte "G " 140 | .byte GREEN 141 | .byte "M " 142 | .byte BLUE 143 | .byte "S " 144 | .byte PURPLE 145 | .byte "! " 146 | .byte WHITE 147 | .byte " " 148 | .byte 0 149 | txt_banner0d: 150 | .byte WHITE 151 | .byte " Terminal FUTURE ",VERSION," " 152 | .byte 0 153 | 154 | txt_author: 155 | .byte " by Craig Smith, Alwyz, Michael Steil " 156 | .byte RVSOFF,DKGRAY,0 157 | 158 | txt_banner1a: 159 | tcol1: .byte WHITE 160 | .byte " ",RVSON,"F1",RVSOFF," " 161 | tcol2: .byte LTRED 162 | .byte "Upload " 163 | tcol9: .byte WHITE 164 | .byte RVSON,"F2",RVSOFF," " 165 | tcol10: .byte LTRED 166 | .byte "Send/Read file ",0 167 | txt_banner1b: 168 | tcol3: .byte WHITE 169 | .byte " ",RVSON,"F3",RVSOFF," " 170 | tcol4: .byte YELLOW 171 | .byte "Download " 172 | tcol11: .byte WHITE 173 | .byte RVSON,"F4",RVSOFF," " 174 | tcol12: .byte YELLOW 175 | .byte "Buffer commands ",0 176 | txt_banner1c: 177 | tcol5: .byte WHITE 178 | .byte " ",RVSON,"F5",RVSOFF," " 179 | tcol6: .byte LTGREEN 180 | .byte "Disk command " 181 | tcol13: .byte WHITE 182 | .byte RVSON,"F6",RVSOFF," " 183 | tcol14: .byte LTGREEN 184 | .byte "Directory ",0 185 | txt_banner1d: 186 | tcol7: .byte WHITE 187 | .byte " ",RVSON,"F7",RVSOFF," " 188 | tcol8: .byte GREEN 189 | .byte "Dialer/Params " 190 | tcol15: .byte WHITE 191 | .byte RVSON,"F8",RVSOFF," " 192 | tcol16: .byte GREEN 193 | .byte "Switch terms ",0 194 | 195 | txt_banner2a: 196 | tcol17a .byte BLUE 197 | .byte "C" 198 | tcol26a .byte RED 199 | .byte "=" 200 | tcol18 .byte WHITE 201 | .byte RVSON,"F1",RVSOFF," " 202 | tcol19 .byte CYAN 203 | .byte "Multi-Send ",0 204 | txt_banner2b: 205 | tcol17b .byte BLUE 206 | .byte "C" 207 | tcol26b .byte RED 208 | .byte "=" 209 | tcol20 .byte WHITE 210 | .byte RVSON,"F3",RVSOFF," " 211 | tcol21 .byte CYAN 212 | .byte "Multi-Receive",0 213 | txt_banner2c: 214 | tcol17c .byte BLUE 215 | .byte "C" 216 | tcol26c .byte RED 217 | .byte "=" 218 | tcol22 .byte WHITE 219 | .byte RVSON,"F5",RVSOFF," " 220 | tcol23 .byte LTBLUE 221 | .byte "Send dir. ",0 222 | txt_banner2d: 223 | tcol17d .byte BLUE 224 | .byte "C" 225 | tcol26d .byte RED 226 | .byte "=" 227 | tcol24 .byte WHITE 228 | .byte RVSON,"F7",RVSOFF," " 229 | tcol25 .byte LTBLUE 230 | .byte "Screen to Buff.",CR,CR,0 231 | 232 | mlswrn: ; [XXX code that uses this is commented out] 233 | .byte CR,WHITE,"Buffer too big - Save or Clear First!",CR,0 234 | SET_ASCII 235 | -------------------------------------------------------------------------------- /src/macro.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2020, Craig Smith, alwyz. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; Macro editor 7 | ; 8 | 9 | prwcmc: 10 | lda macro_tmp 11 | and #$c0 12 | asl a 13 | rol a 14 | rol a 15 | asl a 16 | clc 17 | adc #'1' 18 | sta txt_edit_index 19 | rts 20 | 21 | ;---------------------------------------------------------------------- 22 | SET_PETSCII 23 | txt_edit_which_macro: 24 | .byte CLR,WHITE,CR,CR,"Edit which macro?",CR 25 | .byte YELLOW,"(CTRL F1 / F3 or RETURN to abort.) ",WHITE,SETCSR,2,RVSON,0 26 | 27 | txt_edit: 28 | .byte 19,CR,WHITE,"Edit F" 29 | txt_edit_index: 30 | .byte '1' 31 | .byte " Macro... to end:",CR,CR,CR,CR,0 32 | SET_ASCII 33 | 34 | ;---------------------------------------------------------------------- 35 | wchmac: 36 | .byte 0 37 | 38 | macfull: 39 | .byte 0 40 | 41 | ;---------------------------------------------------------------------- 42 | edtmac: 43 | lda #txt_edit_which_macro 45 | jsr outstr 46 | jsr invert_csr_char 47 | edtmlp lda LSTX ; key code 48 | cmp #1 ; RETURN 49 | bne edtmc2 50 | lda #0 51 | sta NDX ; clear key from buffer 52 | edtmab rts 53 | edtmc2 cmp #4 54 | bcc edtmlp 55 | cmp #6 56 | bcs edtmlp 57 | pha 58 | jsr restore_csr_char 59 | pla 60 | tax 61 | edtmc3 62 | lda LSTX 63 | cmp #7 64 | bcc edtmc3 65 | jsr decode_fkey_scancode 66 | sta wchmac 67 | edtmen 68 | lda #0 69 | sta NDX 70 | lda #CLR 71 | jsr chrout 72 | lda #0 73 | sta $d020 74 | sta $d021 75 | edtstr 76 | jsr prwcmc 77 | lda #txt_edit 79 | jsr outstr 80 | lda #1 81 | sta macro_dry_run_mode 82 | sta cursor_flag 83 | lda wchmac 84 | sta macro_tmp 85 | clc 86 | adc #62 87 | sta macfull 88 | jsr restore_csr_char 89 | lda #' ' 90 | jsr chrout 91 | lda #CSR_LEFT 92 | jsr chrout 93 | jsr prtmc0 94 | edtinp jsr cursor_show 95 | edtkey 96 | jsr getin 97 | beq edtkey 98 | cmp #16 ;ctrl-p 99 | beq edtmen 100 | cmp #HOME ; no home or clr 101 | beq edtkey 102 | cmp #CLR 103 | bne edtky1 104 | ldx macro_tmp 105 | edtclr 106 | lda #0 107 | sta macmem,x 108 | cpx wchmac 109 | beq edtky0 110 | dex 111 | jmp edtclr 112 | edtky0 ldx wchmac 113 | stx macro_tmp 114 | jmp edtmen 115 | edtky1 116 | cmp #24 ;ctrl-x 117 | beq edtbye 118 | cmp #DEL 119 | bne edtky2 120 | lda macro_tmp 121 | cmp wchmac 122 | beq edtkey 123 | tax 124 | jsr edtdel 125 | jcs edtmen 126 | lda macro_tmp 127 | and #$3f 128 | cmp #$3f 129 | bne edtkey 130 | jmp edtmen 131 | edtky2 132 | ldx LINE 133 | cpx #23 134 | bcs edtkey 135 | cpx #3 136 | bcc edtkey 137 | edtky3 138 | ldx macro_tmp 139 | cpx macfull;64 bytes of memory per macro 140 | bcs edtkey 141 | sta macmem,x 142 | pha 143 | txa 144 | cmp wchmac 145 | beq edtky4 146 | and #$3f 147 | bne edtky4 148 | pla 149 | jsr bell 150 | jmp edtmen 151 | edtky4 152 | inc macro_tmp 153 | jsr cursor_off 154 | pla 155 | jsr handle_control_codes 156 | bcc edtky5 157 | jmp edtinp 158 | edtky5 159 | jsr chrout 160 | jsr quote_insert_off 161 | jmp edtinp 162 | edtbye ldx macro_tmp 163 | lda #0 164 | sta macmem,x 165 | rts 166 | 167 | macrvs: 168 | .byte RVSOFF 169 | maccty: 170 | .byte 10 171 | maccol: 172 | .byte 5 173 | maccas: 174 | .byte LOCASE 175 | macbkg: 176 | .byte 0 177 | 178 | edtdel 179 | lda #RVSOFF 180 | sta macrvs 181 | lda #10 182 | sta maccty 183 | lda #5 184 | sta maccol 185 | lda #LOCASE 186 | sta maccas 187 | lda #0 188 | sta macbkg 189 | lda macmem-1,x 190 | cmp #UNDERLINE 191 | beq edtde2 192 | and #$7f 193 | cmp #$20 194 | bcc edtde0 195 | jmp edtdle 196 | edtde0 197 | cmp #CSR_DOWN 198 | beq edtde1 199 | cmp #CSR_RIGHT 200 | bne edtde3 201 | edtde1 lda macmem-1,x 202 | edtdeo eor #$80 203 | jmp edtdln 204 | edtde2 205 | lda #INST 206 | jsr edprrv 207 | lda #CSR_RIGHT 208 | jmp edtdln 209 | edtde3 lda macmem-1,x 210 | cmp #INST 211 | bne edtde4 212 | lda #CSR_RIGHT 213 | jsr edprrv 214 | lda #INST 215 | bne edtdeo 216 | edtde4 jsr edtcok 217 | bmi edtde7 218 | ldx macro_tmp 219 | lda macmem-2,x 220 | sta macbkg 221 | edtde5 dex 222 | cpx wchmac 223 | beq edtde6 224 | lda macmem-1,x 225 | jsr edtcok 226 | bmi edtde5 227 | ldy macmem-2,x 228 | cpy macbkg 229 | beq edtdcl 230 | cpy #2 231 | beq edtde5 232 | ldy macbkg 233 | cpy #2 234 | beq edtde5 235 | edtdcl 236 | sta maccol 237 | edtde6 238 | lda macbkg 239 | cmp #2 240 | bne edtclh 241 | sta prev_char 242 | cpx wchmac 243 | beq edtclb 244 | lda maccol 245 | jsr edtcok 246 | bmi edtclb 247 | tya 248 | tax 249 | edtclb 250 | stx $d020 251 | stx $d021 252 | jmp edtdla 253 | edtclh 254 | lda #0 255 | sta prev_char 256 | lda maccol 257 | jmp edtdln 258 | edtde7 259 | cmp #10 260 | beq edtde8 261 | cmp #11 262 | bne edtd12 263 | edtde8 ldx macro_tmp 264 | edtde9 dex 265 | cpx wchmac 266 | beq edtd11 267 | lda macmem-1,x 268 | cmp #10 269 | beq edtd10 270 | cmp #11 271 | bne edtde9 272 | edtd10 sta maccty 273 | edtd11 lda maccty 274 | jmp edtdln 275 | edtd12 and #$7f 276 | cmp #18 277 | bne edtd15 278 | ldx macro_tmp 279 | edtd13 dex 280 | cpx wchmac 281 | beq edtd14 282 | lda macmem-1,x 283 | and #$7f 284 | cmp #18 285 | bne edtd13 286 | lda macmem-1,x 287 | sta macrvs 288 | edtd14 lda macrvs 289 | and #$80 290 | eor #$80 291 | sta 199 292 | lda macrvs 293 | jmp edtdln 294 | edtd15 295 | cmp #12 296 | beq edtd16 297 | cmp #LOCASE 298 | beq edtd16 299 | cmp #21 300 | bne edtd19 301 | edtd16 ldx macro_tmp 302 | edtdlc dex 303 | cpx wchmac 304 | beq edtd18 305 | lda macmem-1,x 306 | cmp #12 307 | beq edtd17 308 | cmp #LOCASE 309 | beq edtd17 310 | cmp #21 311 | bne edtdlc 312 | edtd17 sta maccas 313 | edtd18 lda maccas 314 | jmp edtdln 315 | edtd19 316 | cmp #CR 317 | bne edtdla 318 | lda #0 319 | sta 199 320 | lda #RVSOFF 321 | jsr edprrv 322 | dec macro_tmp 323 | ldx macro_tmp 324 | lda #0 325 | sta macmem,x 326 | sec 327 | rts 328 | edtdle 329 | lda #20 330 | jsr edprrv 331 | lda #INST 332 | edtdln 333 | jsr edprrv 334 | edtdla 335 | dec macro_tmp 336 | ldx macro_tmp 337 | lda #0 338 | sta macmem,x 339 | clc 340 | rts 341 | edprrv 342 | sta tmp02 343 | lda 199 344 | pha 345 | lda #0 346 | sta 199 347 | jsr cursor_off 348 | lda tmp02 349 | jsr handle_control_codes 350 | bcs edprr2 351 | jsr chrout 352 | jsr quote_insert_off 353 | edprr2 pla 354 | sta 199 355 | jmp cursor_show 356 | edtcok 357 | ldy #15 358 | edtco2 cmp COLTAB,y 359 | beq edtco3 360 | dey 361 | bpl edtco2 362 | edtco3 rts 363 | -------------------------------------------------------------------------------- /rs232lib/rs232_userport.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2022, Craig Smith, alwyz, Michael Steil. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; RS232 Userport Driver, 300-2400 baud 7 | ; based on Novaterm 9.6 8 | ; 9 | 10 | .include "rs232_kernal.inc" 11 | .include "c64.inc" ; CIA#1/CIA#2 defines 12 | .import ribuf ; external 13 | .import rs232_rti 14 | 15 | ; zero page: this reuses the KERNAL's RS232 locations 16 | inbits = $a8 ; BITCI: Bit counter during RS232 input 17 | inbyte = $aa ; RIDATA: Byte buffer during RS232 input 18 | outbits = $b4 ; BITTS: Bit counter and stop bit switch during RS232 output 19 | outbit = $b5 ; NXTBIT: Bit buffer (in bit #2) during RS232 output 20 | outbyte = $b6 ; RODATA: Byte buffer during RS232 output 21 | 22 | ; function table for dispatcher 23 | .export rsuser_funcs 24 | 25 | .segment "RS232" 26 | 27 | ;---------------------------------------------------------------------- 28 | rsuser_funcs: 29 | .word rsuser_setup 30 | .word rsuser_enable 31 | .word rsuser_disable 32 | .word rsuser_getxfer 33 | .word rsuser_putxfer 34 | .word rsuser_dropdtr 35 | 36 | ;---------------------------------------------------------------------- 37 | rsuser_setup: 38 | sei 39 | 40 | jsr rsuser_setbaud 41 | 42 | lda #nmi64 44 | sta $0318 ; NMINV 45 | sty $0319 46 | 47 | cli 48 | rts 49 | 50 | ;---------------------------------------------------------------------- 51 | bdloc: 52 | bntsc: .word 3408,851,425 ; NTSC: transmit times 53 | .word 4915,1090,459 ; NTSC: startup bit times 54 | .word 3410,845,421 ; NTSC: full bit times 55 | bpal: .word 3283,820,409 ; PAL: transmit times 56 | .word 4735,1050,442 ; PAL: startup bit times 57 | .word 3285,814,406 ; PAL: full bit times 58 | OFFSET = bpal-bntsc 59 | 60 | ;---------------------------------------------------------------------- 61 | isbyte: 62 | .byte 0 63 | lastring: ; [XXX unused] 64 | .byte 0 65 | 66 | ;---------------------------------------------------------------------- 67 | ; get byte from serial interface 68 | rsuser_getxfer: 69 | jsr $f04f ; KERNAL code to set up user port 70 | ldx rhead 71 | cpx rtail 72 | beq :+ ; skip (empty buffer, return with carry set) 73 | lda ribuf,x 74 | pha 75 | inc rhead 76 | clc 77 | pla 78 | : rts 79 | 80 | ;---------------------------------------------------------------------- 81 | ; new NMI handler 82 | nmi64: 83 | pha 84 | txa 85 | pha 86 | tya 87 | pha 88 | cld 89 | ldx $dd07 ; sample timer b hi byte 90 | lda #$7f ; disable cia nmi's 91 | sta $dd0d 92 | lda $dd0d ; read/clear flags 93 | ;bpl notcia ; (restore key) 94 | cpx $dd07 ; timer B timeout? 95 | ldy $dd01 ; sample pin C for receive NMI 96 | bcs :+ ; no timeout 97 | ora #$02 ; set flag 98 | ora $dd0d ; read flags again (changed since timeout) 99 | : and ENABL ; mask out non-enabled interrupts 100 | tax ; bitmask of ints to be serviced 101 | lsr ; check timer A 102 | bcc :+ 103 | lda $dd00 ; put output bit on pin M 104 | and #$fb 105 | ora outbit 106 | sta $dd00 107 | : txa ; check flag NMI 108 | and #$10 ; indicates new byte coming in 109 | beq nmion 110 | strtlo=*+1 111 | lda #0 ; initialize timer B with start bit time 112 | sta $dd06 113 | strthi=*+1 114 | lda #0 115 | sta $dd07 116 | lda #$11 117 | sta $dd0f ; start timer B, load latched value to counter 118 | lda #$12 119 | eor ENABL 120 | sta ENABL 121 | sta $dd0d ; enable flag, timer B interrupts 122 | fulllo=*+1 123 | lda #0 ; latch full bit value for next countdown 124 | sta $dd06 125 | fullhi=*+1 126 | lda #0 127 | sta $dd07 128 | lda #8 129 | sta inbits 130 | jmp chktxd 131 | 132 | ;notcia ldy #0 133 | ; jmp rstkey ; or jmp norest 134 | 135 | nmion: lda ENABL ; receive a bit 136 | sta $dd0d 137 | txa 138 | and #$02 139 | beq chktxd 140 | tya 141 | lsr 142 | ror inbyte 143 | dec inbits 144 | bne txd 145 | lda inbyte 146 | ldx rtail ; index to buffer 147 | sta ribuf,x ; and store it 148 | inc rtail ; move index to next slot 149 | lda #0 150 | sta $dd0f 151 | lda #$12 152 | switch: ldy #$7f 153 | sty $dd0d 154 | sty $dd0d 155 | eor ENABL 156 | sta ENABL 157 | sta $dd0d 158 | txd: txa 159 | lsr 160 | chktxd: bcc @nmiflow 161 | dec outbits 162 | bmi @endbyte 163 | lda #4 164 | ror outbyte 165 | bcs :+ 166 | lda #0 167 | : sta outbit 168 | @nmiflow: 169 | lda inbits 170 | and #8 171 | beq :+ 172 | clc 173 | : pla 174 | tay 175 | pla 176 | tax 177 | pla 178 | jmp rs232_rti 179 | 180 | @endbyte: 181 | lda #0 182 | sta isbyte 183 | ldx #0 ; turn transmit int off 184 | stx $dd0e 185 | lda #1 186 | bne switch 187 | jmp rsuser_disable 188 | 189 | ;---------------------------------------------------------------------- 190 | rsuser_putxfer: 191 | pha 192 | stx save_x 193 | sty save_y 194 | sta outbyte 195 | lda #0 196 | sta outbit 197 | lda #9 198 | sta outbits 199 | lda #$ff 200 | sta isbyte 201 | xmitlo=*+1 202 | lda #0 203 | sta $dd04 204 | xmithi=*+1 205 | lda #0 206 | sta $dd05 207 | lda #$11 208 | sta $dd0e 209 | lda #$81 210 | jsr change 211 | clc 212 | save_x=*+1 213 | ldx #0 214 | save_y=*+1 215 | ldy #0 216 | pla 217 | rts 218 | 219 | ;---------------------------------------------------------------------- 220 | ; disable rs232 input 221 | rsuser_disable: 222 | pha 223 | : 224 | ; lda ENABL;this fucks shit up... get rid of it... 225 | ; and #$03 226 | ; bne :- 227 | lda isbyte 228 | bne :- 229 | lda #$10 230 | sta $dd0d 231 | lda #2 232 | and ENABL 233 | bne :- 234 | sta ENABL 235 | pla 236 | rts 237 | 238 | ;---------------------------------------------------------------------- 239 | ; enable rs232 input 240 | rsuser_enable: 241 | lda ENABL 242 | and #$12 243 | beq :+ 244 | rts 245 | : sta $dd0f 246 | lda #$90 247 | change: 248 | sta $dd0d 249 | php 250 | sei 251 | ldy #$7f 252 | sty $dd0d 253 | sty $dd0d 254 | ora ENABL 255 | sta ENABL 256 | sta $dd0d 257 | plp 258 | : bit isbyte 259 | bmi :- 260 | rts 261 | 262 | ;---------------------------------------------------------------------- 263 | ; X: baud_rate 264 | ; Y: is_pal_system 265 | rsuser_setbaud: 266 | txa ; baud_rate 267 | asl 268 | cpy #0 ; is_pal_system 269 | beq :+ 270 | clc 271 | adc #OFFSET 272 | : tay 273 | lda bdloc,y 274 | sta xmitlo 275 | lda bdloc+1,y 276 | sta xmithi 277 | lda bdloc+6,y 278 | sta strtlo 279 | lda bdloc+7,y 280 | sta strthi 281 | lda bdloc+12,y 282 | sta fulllo 283 | lda bdloc+13,y 284 | sta fullhi 285 | rts 286 | 287 | ;---------------------------------------------------------------------- 288 | ; Hang up 289 | rsuser_dropdtr: 290 | lda #%00000100 291 | sta $dd03 292 | lda #0 293 | sta cia2pb 294 | ldx #$100-30 295 | stx JIFFIES 296 | : bit JIFFIES 297 | bmi :- 298 | lda #4 299 | sta cia2pb 300 | rts 301 | -------------------------------------------------------------------------------- /rs232lib/rs232_swiftlink.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2022, Craig Smith, alwyz, Michael Steil. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; RS232 SwiftLink/Turbo232 (MOS 6551 ACIA) Driver 7 | ; based on Jeff Brown adaptation of Novaterm version 8 | ; 9 | 10 | .include "rs232_kernal.inc" 11 | .include "rs232.inc" ; for MODEM_TYPE_* 12 | .import ribuf ; external 13 | .import rs232_rti 14 | 15 | ; function table for dispatcher 16 | .export sw_funcs 17 | 18 | stopsw = 1 19 | startsw = 0 20 | 21 | ; SwiftLink registers 22 | swift = $de00 ; will be runtime-patched to $DE00/$DF00/$D700 23 | sw_data = swift 24 | sw_stat = swift+1 25 | sw_cmd = swift+2 26 | sw_ctrl = swift+3 27 | sw_baud = swift+7 28 | 29 | .segment "RS232" 30 | 31 | ;---------------------------------------------------------------------- 32 | sw_funcs: 33 | .word sw_setup 34 | .word sw_enable 35 | .word sw_disable 36 | .word sw_getxfer 37 | .word sw_putxfer 38 | .word sw_dropdtr 39 | 40 | ;---------------------------------------------------------------------- 41 | ; new NMI handler 42 | nmisw: 43 | pha 44 | txa 45 | pha 46 | tya 47 | pha 48 | sm1: lda sw_stat 49 | and #%00001000 ; mask out all but receive interrupt reg 50 | bne sm2 ; get outta here if interrupts are disabled (disk access etc) 51 | sec ; set carry upon return 52 | bcs recch1 53 | sm2: lda sw_cmd 54 | ora #%00000010 ; disable receive interrupts 55 | sm3: sta sw_cmd 56 | sm4: lda sw_data 57 | ldx rtail 58 | sta ribuf,x 59 | inc rtail 60 | inc rfree 61 | lda rfree 62 | cmp #200 ; check byte count against tolerance 63 | bcc :+ ; is it over the top? 64 | ldx #stopsw 65 | stx paused ; x=1 for stop, by the way 66 | jsr flow 67 | : 68 | sm5: lda sw_cmd 69 | and #%11111101 ; re-enable receive interrupt 70 | sm6: sta sw_cmd 71 | clc 72 | recch1: pla 73 | tay 74 | pla 75 | tax 76 | pla 77 | jmp rs232_rti 78 | 79 | ;---------------------------------------------------------------------- 80 | flow: 81 | sm7: lda sw_cmd 82 | and #%11110011 83 | cpx #stopsw 84 | beq :+ 85 | ora #%00001000 86 | : 87 | sm8: sta sw_cmd 88 | rts 89 | 90 | ;---------------------------------------------------------------------- 91 | swwait: 92 | sm9: lda sw_cmd 93 | ora #%00001000 ; enable transmitter 94 | sm10: sta sw_cmd 95 | sm11: lda sw_stat 96 | and #%00110000 97 | beq swwait 98 | rts 99 | 100 | ;---------------------------------------------------------------------- 101 | sw_disable: 102 | sm12: lda sw_cmd 103 | ora #%00000010 ; disable receive interrupt 104 | sm13: sta sw_cmd 105 | rts 106 | 107 | ;---------------------------------------------------------------------- 108 | sw_enable: 109 | sm14: lda sw_cmd 110 | and #%11111101 ; enable receive interrupt 111 | sm15: sta sw_cmd 112 | rts 113 | 114 | ;---------------------------------------------------------------------- 115 | ; A: modem_type 116 | ; X: baud_rate 117 | sw_setup: 118 | ; set SwiftLink address by modifying all access code 119 | cmp #MODEM_TYPE_SWIFTLINK_DE 120 | beq @de 121 | cmp #MODEM_TYPE_SWIFTLINK_DF 122 | beq @df 123 | lda #$d7 ; else MODEM_TYPE_SWIFTLINK_D7 124 | bne @cont 125 | @de: lda #$de 126 | bne @cont 127 | @df: lda #$df 128 | @cont: sta sm1+2 129 | sta sm2+2 130 | sta sm3+2 131 | sta sm4+2 132 | sta sm5+2 133 | sta sm6+2 134 | sta sm7+2 135 | sta sm8+2 136 | sta sm9+2 137 | sta sm10+2 138 | sta sm11+2 139 | sta sm12+2 140 | sta sm13+2 141 | sta sm14+2 142 | sta sm15+2 143 | sta sm16+2 144 | sta sm17+2 145 | sta sm18+2 146 | sta sm19+2 147 | sta sm20+2 148 | sta sm21+2 149 | sta sm22+2 150 | sta sm23+2 151 | sta sm24+2 152 | sta sm25+2 153 | 154 | sei 155 | ; .------------------------- parity control, 156 | ; :.------------------------ bits 5-7 157 | ; ::.----------------------- 000 = no parity 158 | ; ::: 159 | ; :::.------------------- echo mode, 0 = normal (no echo) 160 | ; :::: 161 | ; ::::.----------- transmit interrupt control, bits 2-3 162 | ; :::::.---------- 10 = xmit interrupt off, RTS low 163 | ; :::::: 164 | ; ::::::.------ receive interrupt control, 0 = enabled 165 | ; ::::::: 166 | ; :::::::.--- DTR control, 1=DTR low 167 | lda #%00001001 168 | sm16: sta sw_cmd 169 | ; .------------------------- 0 = one stop bit 170 | ; : 171 | ; :.-------------------- word length, bits 6-7 172 | ; ::.------------------- 00 = eight-bit word 173 | ; ::: 174 | ; :::.------------- clock source, 1 = internal generator 175 | ; :::: 176 | ; ::::.----- baud 177 | ; :::::.---- rate 178 | ; ::::::.--- bits ;1010 == 4800 baud, changes later 179 | ; :::::::.-- 0-3 180 | lda #%00010000 181 | sm17: sta sw_ctrl 182 | 183 | sm18: lda sw_ctrl 184 | and #$f0 185 | ora swbaud,x ; baud_rate 186 | sm19: sta sw_ctrl 187 | 188 | lda #nmisw 190 | sta $0318 ; NMINV 191 | stx $0319 192 | 193 | cli 194 | rts 195 | 196 | ;---------------------------------------------------------------------- 197 | sw_putxfer: 198 | pha 199 | sm20: lda sw_cmd 200 | sta temp 201 | jsr swwait 202 | pla 203 | pha 204 | sm21: sta sw_data 205 | jsr swwait 206 | temp=*+1 207 | lda #0 ; restore rts state 208 | sm22: sta sw_cmd 209 | pla 210 | clc 211 | rts 212 | 213 | ;---------------------------------------------------------------------- 214 | ; Hang up 215 | sw_dropdtr: 216 | sm23: lda sw_cmd 217 | and #%11111110 218 | sm24: sta sw_cmd 219 | ldx #226 220 | stx JIFFIES 221 | : bit JIFFIES 222 | bmi :- 223 | ora #%00000001 224 | sm25: sta sw_cmd 225 | rts 226 | 227 | ;---------------------------------------------------------------------- 228 | ; get byte from serial interface 229 | sw_getxfer: 230 | ldx rhead 231 | cpx rtail 232 | beq @1 ; skip (empty buffer, return with carry set) 233 | lda ribuf,x 234 | pha 235 | inc rhead 236 | dec rfree 237 | ldx paused ; are we stopped? 238 | beq :+ ; no, don't bother 239 | lda rfree ; check buffer free 240 | cmp #50 ; against restart limit 241 | bcs :+ ; is it larger than 50? 242 | ldx #startsw ; if no, then don't start yet 243 | stx paused 244 | jsr flow 245 | : clc 246 | pla 247 | @1: rts 248 | 249 | ;---------------------------------------------------------------------- 250 | paused: 251 | .byte 0 252 | 253 | ;---------------------------------------------------------------------- 254 | ; MOS 6551 ACIA baud rate constants 255 | SW_BAUD_50 = %10001 256 | SW_BAUD_75 = %10010 257 | SW_BAUD_109_92 = %10011 258 | SW_BAUD_134_58 = %10100 259 | SW_BAUD_150 = %10101 260 | SW_BAUD_300 = %10110 261 | SW_BAUD_600 = %10111 262 | SW_BAUD_1200 = %11000 263 | SW_BAUD_1800 = %11001 264 | SW_BAUD_2400 = %11010 265 | SW_BAUD_3600 = %11011 266 | SW_BAUD_4800 = %11100 267 | SW_BAUD_7200 = %11101 268 | SW_BAUD_9600 = %11110 269 | SW_BAUD_19200 = %11111 270 | 271 | swbaud: 272 | ; The SwiftLink/Turbo232 baud rate generator is 2x that of the spec, 273 | ; so the ACIA has half the rates set up. 274 | .byte SW_BAUD_150 ; 300 275 | .byte SW_BAUD_600 ; 1200 276 | .byte SW_BAUD_1200 ; 2400 277 | .byte SW_BAUD_2400 ; 2400 278 | .byte SW_BAUD_4800 ; 4800 279 | .byte SW_BAUD_9600 ; 9600 280 | .byte SW_BAUD_19200 ; 38400 281 | 282 | .byte $10,$10,$10 ; [XXX unused] 283 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CCGMS *Future* 2 | 3 | *Commodore Color Graphics Manipulation System Terminal*
*by Craig Smith (1985-1988), alwyz (2017-2020), Michael Steil (2022)* 4 | 5 | * based on 5.5 source by [Craig Smith](https://github.com/spathiwa) 01/1988. 6 | * 2017-2021 mods by [alwyz](http://1200baud.wordpress.com) (see [ccgmsterm2021](https://github.com/mist64/ccgmsterm/tree/ccgmsterm2021) for final alwyz version) 7 | * fixes and additions by [Michael Steil](https://www.pagetable.com/), 2022 8 | 9 | ![](ccgms_40.png) ![](ccgms_80.png) 10 | 11 | ## Features 12 | 13 | * 40 column color mode 14 | * 80 column color mode 🔴 15 | * PETSCII and ASCII/ANSI encoding 16 | * Serial drivers (stable on NTSC and PAL 🔴) 17 | * User Port (300-2400 baud) 18 | * UP9600 (300-9600 baud) 19 | * SwiftLink $DE00/$DF00/$D700/NMI (300-38400 baud) 20 | * File transfer protocols: 21 | * Punter, Multi-Punter 22 | * XMODEM, XMODEM-CRC, XMODEM-1K 🔴 23 | * Phone book with 30 entries and auto-dialer 24 | * Configuration & phone book load/save (disk or EasyFlash) 25 | * DOS command and directory 26 | * Macros 27 | * Screenshots 28 | * Themes 29 | * REU buffer (64 KB) 30 | 31 | ## Documentation 32 | 33 | [CCGMS Future Documentation](Documentation.md) 34 | 35 | ## Missing Features 36 | 37 | * [RR-Net support](https://github.com/mist64/ccgmsterm/issues/1) 38 | * [WiC64 support](https://github.com/mist64/ccgmsterm/issues/3) 39 | * [YMODEM](https://github.com/mist64/ccgmsterm/issues/15)/ZMODEM/HMODEM protocols 40 | * IDE64 compatibility 41 | * Additional cartridges (e.g. Lt. Kernal) 42 | * 100% support for [hardware acceleration devices](https://github.com/mist64/ccgmsterm/issues/14) (SuperCPU etc). Certain conditions may affect file transfer handshake timing. 43 | 44 | ## Known Bugs 45 | 46 | * [#5](https://github.com/mist64/ccgmsterm/issues/5): XMODEM (and possibly PUNTER) transmission may be broken for UP9600 devices 47 | * [#10](https://github.com/mist64/ccgmsterm/issues/10): XMODEM/1K may fail for SwiftLink cartridges with a real 6551 chip 48 | 49 | ## Build 50 | 51 | Build with make & [ca65](https://github.com/cc65/cc65). 52 | 53 | Regular build: 54 | 55 | make 56 | 57 | EasyFlash build: 58 | 59 | EASYFLASH=1 make 60 | 61 | The EasyFlash version gives you the option of loading/saving the phonebook to cart and removes Swiftlink. 62 | 63 | In either case, the resulting file will be `build/ccgmsterm.prg`. 64 | 65 | ## Running in VICE 66 | 67 | To run CCGMS in x64sc with SwiftLink at $DE00: 68 | 69 | make runsw 70 | 71 | x64sc with User Port: 72 | 73 | make runup 74 | 75 | x64sc VICE with UP9600 ([receiving OK but sending broken as of VICE 3.6.2](https://sourceforge.net/p/vice-emu/bugs/1219/)): 76 | 77 | make runup9600 78 | 79 | The x64sc command line has changed recently, so these need at least VICE 3.6. 80 | 81 | ## Testing 82 | 83 | This repository includes automated and manual tests. See [Testing](Testing.md). 84 | 85 | ## Interals 86 | 87 | [Internals](Internals.md). 88 | 89 | ## Changelog 90 | 91 | ### 2022-03-20: Future 0.2 92 | 93 | * Added support for a software 80 column screen mode 94 | * F8 now cycles: 40c PETSCII -> 40c ASCII -> 80c PETSCII -> 80c ASCII 95 | * All menus, transfers etc. temporarily switch back to 40 col screen. The 80 column contents will be preserved when temporarily switching. 96 | * In 80 color ASCII mode, the characters \^_`{|}~ are available, matching ASCII (unlike 40 col ASCII). 97 | * Fixed ASCII-PETSCII conversion of codes 0x60 and 0x7B 98 | * Changed some wording to be clearer (imho): 99 | * "Graphics" and "C/G" to "PETSCII" 100 | * "Anscii" to "ASCII" 101 | * "Author's Message" to "Instructions" 102 | * Internal changes 103 | * rewrote RS232 driver model 104 | * cleaned up code memory layout 105 | 106 | ### 2022-02-25: Future 0.1 107 | 108 | * Fixed timing for PAL in User Port and UP9600 drivers 109 | * Implemented XMODEM-1K 110 | * protocol XMODEM-1K forces 1K on upload 111 | * any XMODEM protocol will accept 1K blocks on download 112 | * XMODEM-CRC autodetect on upload 113 | * protocols XMODEM-CRC/-1K will force CRC on download 114 | * any XMODEM protocol will accept CRC on upload 115 | 116 | ### 2020-12-08: v2021 final 117 | * Punter stack and Unlisted dialer bugs have been eliminated 118 | * Support in autodialer for Zimodem and related WiFi device firmware that prefer an ATD prefix to ATDT. 119 | 120 | ### 2020-09-22: v2021 pre-beta2 121 | bo zimmermans firmware (and maybe others) take issue with atdt, and prefer using atd instead for bbsing (uploads/downloads issue). hopefully this is the only issue with firmware compatibility. willing to solve this issue on the software side, though i'd prefer firmware uses a better standard. but fuck it, it's 2020 and who gives a shit anymore about standards on an 8 bit computer from the 1980s? so i added an atd/atdt menu option 122 | 123 | ### 2020-06-30: v2021 beta 1 124 | * doing some bugfixing. dial unlisted doesnt restore bottom of screen after dial. now it does. cosmetic fix. 125 | * abort punter crashes stack pointer because i bypassed jump table and apparently that is neccessary so its back in the calls from dowmen and f3 routines. 126 | 127 | ### 2020-05-23: v2020 beta 8 128 | * easyflash false positive with reu detect. since ef and reu cant work together, added provisions at startup to prevent easyflash mode from even looking for an reu 129 | 130 | ### 2020-05-21: v2020 beta 7 131 | * did some tweaks to autodialer. try counter now works to 99, and dial unlisted had some weird issues with that so that has been sorted as well. 132 | * found one bug in the bottom screen display routine which has probably been there since ccgms 2017, but its good now. 133 | 134 | ### 2020-05-19: v2020 beta 6 135 | * merged easyflash version into this one. only added 2 blocks. easier for maintaining 136 | * still have some room from $5000-$5100 for more code/routines if need be. And can always add more code at $5c00 before the end 137 | 138 | ### 2020-05-18: v2020 beta 5 139 | * fixing some possible issues with multi-upload. crashes between files. enablexfer not getting turned back on at the right time? 140 | * re-did cf1 multi-upload enable/disablexfer calls... seems good now 141 | 142 | ### 2020-05-17: v2020 beta 4 143 | * found a bug on the original punter sourcecode that incorrectly references var "delay" as delay 1 on 0 off, but in truth it is 1 off 0 on, so ive set both to delay on now update... ahh fuck it, no matter what, add delays every chance we can.... i disabled every opportunity to bypass delay around pnt106. 144 | 145 | ### 2020-05-16: v2020 beta 3 146 | * f3 disablexfer improvements 147 | * multi-receive disablexfer imrovements / trying to prevent crashing on multidownloads (noted on up9600) 148 | * added punter handshake delays from ultimate version back in. baudrates faster than 2400 are definitely having problems with handshakes so its back! 149 | * added jsr call to rsopen to baudrate changer. see if that fixes some weirdness 150 | 151 | ### 2020-05-14: v2020 beta 2 152 | * first public beta. rewrite of pretty much everything.... 153 | * file transfers finally incorporate flow control. they never did before. 154 | * resetvectors removed. 155 | * re-wrote and optimized all modem drivers. 156 | * removed a bunch of spaghetti code of my own making... 157 | 158 | ### ultimate version 159 | * 2019 by alwyz 160 | 161 | ### version 2019 162 | * 2019 by alwyz 163 | 164 | ### version 2017 165 | * 2017 by alwyz 166 | 167 | ### Historic Versions 168 | by Craig Smith 169 | 170 | * version 5.5 -- jan 1988 171 | * version 5.0 -- jan 1988 172 | * version 4.5 -- may 1987 173 | * version 4.1 -- oct 1986 174 | * version 4.0 -- date unknown (mods by greg pfoutz,w/permission) 175 | * version 3.0 -- aug 1985 176 | -------------------------------------------------------------------------------- /test/xmodem.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2001-2010 Georges Menie (www.menie.org) 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the University of California, Berkeley nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | extern int _inbyte(unsigned short timeout); // msec timeout 29 | extern void _outbyte(int c); 30 | #include 31 | #include 32 | #include "crc16.h" 33 | 34 | #define SOH 0x01 35 | #define STX 0x02 36 | #define EOT 0x04 37 | #define ACK 0x06 38 | #define NAK 0x15 39 | #define CAN 0x18 40 | #define CTRLZ 0x1A 41 | 42 | #define DLY_1S 1000 43 | #define MAXRETRANS 25 44 | 45 | static int check(int crc, const unsigned char *buf, int sz) 46 | { 47 | if (crc) { 48 | unsigned short crc = crc16_ccitt(buf, sz); 49 | unsigned short tcrc = (buf[sz]<<8)+buf[sz+1]; 50 | if (crc == tcrc) { 51 | fprintf(stderr, "***** SERVER: CRC GOOD\n"); 52 | return 1; 53 | } else { 54 | fprintf(stderr, "***** SERVER: CRC BAD, %02x!=%02x\n", crc, tcrc); 55 | } 56 | } 57 | else { 58 | int i; 59 | unsigned char cks = 0; 60 | for (i = 0; i < sz; ++i) { 61 | cks += buf[i]; 62 | } 63 | if (cks == buf[sz]) { 64 | fprintf(stderr, "***** SERVER: CHKSUM GOOD\n"); 65 | return 1; 66 | } else { 67 | fprintf(stderr, "***** SERVER: CHKSUM BAD, %02x!=%02x\n", cks, buf[sz]); 68 | } 69 | } 70 | 71 | return 0; 72 | } 73 | 74 | static void flushinput(void) 75 | { 76 | // while (_inbyte(((DLY_1S)*3)>>1) >= 0) 77 | // ; 78 | } 79 | 80 | int xmodemReceive(unsigned char *dest, int destsz, int use_crc) 81 | { 82 | unsigned char xbuff[1030]; /* 1024 for XModem 1k + 3 head chars + 2 crc + nul */ 83 | unsigned char *p; 84 | int bufsz, crc = 0; 85 | unsigned char trychar = use_crc ? 'C' : NAK; 86 | unsigned char packetno = 1; 87 | int i, c, len = 0; 88 | int retry, retrans = MAXRETRANS; 89 | 90 | for(;;) { 91 | for( retry = 0; retry < 16; ++retry) { 92 | if (trychar) _outbyte(trychar); 93 | if ((c = _inbyte((DLY_1S)<<1)) >= 0) { 94 | switch (c) { 95 | case SOH: 96 | fprintf(stderr, "***** SERVER: SOH\n"); 97 | bufsz = 128; 98 | goto start_recv; 99 | case STX: 100 | fprintf(stderr, "***** SERVER: STX\n"); 101 | bufsz = 1024; 102 | goto start_recv; 103 | case EOT: 104 | fprintf(stderr, "***** SERVER: EOT\n"); 105 | flushinput(); 106 | fprintf(stderr, "***** SERVER: EOT->ACK\n"); 107 | _outbyte(ACK); 108 | return len; /* normal end */ 109 | case CAN: 110 | fprintf(stderr, "***** SERVER: CAN\n"); 111 | if ((c = _inbyte(DLY_1S)) == CAN) { 112 | flushinput(); 113 | _outbyte(ACK); 114 | return -1; /* canceled by remote */ 115 | } 116 | break; 117 | default: 118 | break; 119 | } 120 | } 121 | } 122 | if (trychar == 'C') { trychar = NAK; continue; } 123 | flushinput(); 124 | _outbyte(CAN); 125 | _outbyte(CAN); 126 | _outbyte(CAN); 127 | return -2; /* sync error */ 128 | 129 | start_recv: 130 | if (trychar == 'C') crc = 1; 131 | trychar = 0; 132 | p = xbuff; 133 | *p++ = c; 134 | for (i = 0; i < (bufsz+(crc?1:0)+3); ++i) { 135 | if ((c = _inbyte(DLY_1S)) < 0) goto reject; 136 | fprintf(stderr, "***** SERVER: DATA(%d) %02x\n", i, c); 137 | *p++ = c; 138 | } 139 | fprintf(stderr, "***** SERVER: DATA DONE\n"); 140 | 141 | if (xbuff[1] == (unsigned char)(~xbuff[2]) && 142 | (xbuff[1] == packetno || xbuff[1] == (unsigned char)packetno-1) && 143 | check(crc, &xbuff[3], bufsz)) { 144 | if (xbuff[1] == packetno) { 145 | register int count = destsz - len; 146 | if (count > bufsz) count = bufsz; 147 | if (count > 0) { 148 | memcpy (&dest[len], &xbuff[3], count); 149 | len += count; 150 | } 151 | ++packetno; 152 | retrans = MAXRETRANS+1; 153 | } 154 | if (--retrans <= 0) { 155 | fprintf(stderr, "***** SERVER: CAN\n"); 156 | flushinput(); 157 | _outbyte(CAN); 158 | _outbyte(CAN); 159 | _outbyte(CAN); 160 | return -3; /* too many retry error */ 161 | } 162 | fprintf(stderr, "***** SERVER: ACK\n"); 163 | _outbyte(ACK); 164 | continue; 165 | } 166 | reject: 167 | fprintf(stderr, "***** SERVER: NAK\n"); 168 | flushinput(); 169 | _outbyte(NAK); 170 | } 171 | } 172 | 173 | int xmodemTransmit(unsigned char *src, int srcsz, int use_1k) 174 | { 175 | unsigned char xbuff[1030]; /* 1024 for XModem 1k + 3 head chars + 2 crc + nul */ 176 | int bufsz, crc = -1; 177 | unsigned char packetno = 1; 178 | int i, c, len = 0; 179 | int retry; 180 | 181 | for(;;) { 182 | for( retry = 0; retry < 16; ++retry) { 183 | if ((c = _inbyte((DLY_1S)<<1)) >= 0) { 184 | switch (c) { 185 | case 'C': 186 | crc = 1; 187 | goto start_trans; 188 | case NAK: 189 | crc = 0; 190 | goto start_trans; 191 | case CAN: 192 | if ((c = _inbyte(DLY_1S)) == CAN) { 193 | _outbyte(ACK); 194 | flushinput(); 195 | return -1; /* canceled by remote */ 196 | } 197 | break; 198 | default: 199 | break; 200 | } 201 | } 202 | } 203 | _outbyte(CAN); 204 | _outbyte(CAN); 205 | _outbyte(CAN); 206 | flushinput(); 207 | return -2; /* no sync */ 208 | 209 | for(;;) { 210 | start_trans: 211 | if (use_1k) { 212 | xbuff[0] = STX; bufsz = 1024; 213 | } else { 214 | xbuff[0] = SOH; bufsz = 128; 215 | } 216 | xbuff[1] = packetno; 217 | xbuff[2] = ~packetno; 218 | c = srcsz - len; 219 | if (c > bufsz) c = bufsz; 220 | if (c > 0) { 221 | memset (&xbuff[3], 0, bufsz); 222 | memcpy (&xbuff[3], &src[len], c); 223 | if (c < bufsz) xbuff[3+c] = CTRLZ; 224 | if (crc) { 225 | unsigned short ccrc = crc16_ccitt(&xbuff[3], bufsz); 226 | xbuff[bufsz+3] = (ccrc>>8) & 0xFF; 227 | xbuff[bufsz+4] = ccrc & 0xFF; 228 | } 229 | else { 230 | unsigned char ccks = 0; 231 | for (i = 3; i < bufsz+3; ++i) { 232 | ccks += xbuff[i]; 233 | } 234 | xbuff[bufsz+3] = ccks; 235 | } 236 | for (retry = 0; retry < MAXRETRANS; ++retry) { 237 | for (i = 0; i < bufsz+4+(crc?1:0); ++i) { 238 | _outbyte(xbuff[i]); 239 | } 240 | if ((c = _inbyte(DLY_1S)) >= 0 ) { 241 | switch (c) { 242 | case ACK: 243 | ++packetno; 244 | len += bufsz; 245 | goto start_trans; 246 | case CAN: 247 | if ((c = _inbyte(DLY_1S)) == CAN) { 248 | _outbyte(ACK); 249 | flushinput(); 250 | return -1; /* canceled by remote */ 251 | } 252 | break; 253 | case NAK: 254 | default: 255 | break; 256 | } 257 | } 258 | } 259 | _outbyte(CAN); 260 | _outbyte(CAN); 261 | _outbyte(CAN); 262 | flushinput(); 263 | return -4; /* xmit error */ 264 | } 265 | else { 266 | for (retry = 0; retry < 10; ++retry) { 267 | _outbyte(EOT); 268 | if ((c = _inbyte((DLY_1S)<<1)) == ACK) break; 269 | } 270 | flushinput(); 271 | return (c == ACK)?len:-5; 272 | } 273 | } 274 | } 275 | } 276 | -------------------------------------------------------------------------------- /src/configedit.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2020, Craig Smith, alwyz. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; Configuration editor 7 | ; 8 | 9 | ;---------------------------------------------------------------------- 10 | ; change terminal params/dial 11 | handle_f7_config: 12 | jsr col80_pause 13 | jsr rs232_off 14 | lda #0 15 | sta $d020 16 | sta $d021 17 | lda #txt_settings_menu 19 | jsr outstr 20 | lda easyflash_support 21 | beq @1 22 | lda #txt_edit_macros_cfg_device 24 | jsr outstr 25 | jmp @2 26 | @1: lda #txt_edit_macros 28 | jsr outstr 29 | @2: lda #txt_load_save_config 31 | jsr outstr 32 | lda #txt_press_return_to_abort 34 | jsr outstr 35 | 36 | config_loop: 37 | jsr f7parm 38 | f7chos 39 | lda JIFFIES 40 | and #$0f 41 | bne f7chgk 42 | lda JIFFIES 43 | and #$10 44 | beq f7oprt 45 | lda #txt_press_return_to_abort 47 | jsr outstr 48 | jmp f7chgk 49 | f7oprt 50 | lda #txt_return 52 | jsr outstr 53 | f7chgk 54 | jsr getin 55 | cmp #0 56 | beq f7chos 57 | 58 | ; A: auto-dial 59 | and #$7f 60 | cmp #'A' 61 | bne @no1 62 | 63 | lda baud_rate 64 | sta bautmp 65 | lda ascii_mode 66 | sta gratmp 67 | jmp phonebook 68 | @no1: 69 | 70 | ; B: Baud Rate 71 | cmp #'B' 72 | bne @no2 73 | 74 | ldy modem_type 75 | beq @baud1 ; MODEM_TYPE_USERPORT 76 | cpy #MODEM_TYPE_UP9600 77 | beq @baud2 78 | cpy #MODEM_TYPE_SWIFTLINK_DF; skip REU if there's SwiftLink at $DF00 79 | bne @inc 80 | jsr noreu 81 | jmp @inc 82 | @baud1: lda baud_rate 83 | cmp #BAUD_2400 84 | bmi @inc 85 | jmp @reset 86 | @baud2: lda baud_rate 87 | cmp #BAUD_9600 88 | bmi @inc 89 | jmp @reset 90 | @inc: inc baud_rate 91 | lda baud_rate 92 | cmp #BAUD_38400+1 93 | bne :+ 94 | @reset: lda #BAUD_300 95 | sta baud_rate 96 | : jsr rsopen ;5-16 add failsafe.... 97 | jmp config_loop 98 | @no2: 99 | 100 | ; D: Duplex 101 | cmp #'D' 102 | bne @no3 103 | 104 | lda half_duplex 105 | eor #1 106 | sta half_duplex 107 | jmp config_loop 108 | @no3: 109 | 110 | ; F: Firmware 111 | cmp #'F' 112 | bne @no4 113 | 114 | lda firmware_zimmers 115 | eor #1 116 | sta firmware_zimmers 117 | jmp config_loop 118 | @no4: 119 | 120 | ; T: theme 121 | cmp #'T' 122 | bne @no5 123 | inc theme 124 | lda theme 125 | cmp #6 126 | bne :+ 127 | lda #0 128 | sta theme 129 | : jsr themeroutine 130 | jmp config_loop 131 | @no5: 132 | 133 | ; C: Config EF/Disk (EasyFlash only) 134 | cmp #'C' 135 | bne @no6 136 | lda easyflash_support 137 | beq @no6 138 | lda easyflash_use_disk 139 | eor #1 140 | sta easyflash_use_disk 141 | jmp config_loop 142 | @no6: 143 | 144 | ; M: modem type 145 | cmp #'M' 146 | bne @no7 147 | 148 | inc modem_type 149 | lda modem_type 150 | pha 151 | lda easyflash_support 152 | beq @mod1 153 | pla 154 | cmp #2 ; only 2 modems in easyflash mode 155 | bcc @incmod 156 | jmp @mod2 157 | @mod1: pla 158 | cmp #5 ; max # of modems 159 | bcc @incmod 160 | @mod2: lda #0 161 | sta modem_type 162 | lda #BAUD_2400 163 | sta baud_rate 164 | @incmod: 165 | jsr rsopen 166 | jmp config_loop 167 | @no7: 168 | 169 | ; P: Protocol 170 | cmp #'P' 171 | bne @no8 172 | 173 | inc protoc 174 | lda protoc 175 | cmp #4 176 | bcc :+ 177 | lda #0 178 | sta protoc 179 | : jmp config_loop 180 | @no8: 181 | 182 | ; S: save 183 | cmp #'S' 184 | bne @no9 185 | jsr save_config 186 | jmp handle_f7_config 187 | @no9: 188 | 189 | ; L: load 190 | cmp #'L' 191 | bne @no10 192 | jsr load_config 193 | jmp handle_f7_config 194 | @no10: 195 | 196 | ; E: edit macros 197 | cmp #'E' 198 | bne @no11 199 | jsr edtmac 200 | jmp handle_f7_config 201 | @no11: 202 | 203 | ; V: view message 204 | cmp #'V' 205 | bne @no12 206 | jsr show_instructions 207 | jmp handle_f7_config 208 | @no12: 209 | 210 | cmp #CR 211 | jne f7chos 212 | 213 | ; return to terminal 214 | lda nicktemp ; [XXX no-op] 215 | beq *+2 ; [XXX no-op] 216 | 217 | jsr rs232_init 218 | jmp term_entry 219 | 220 | ;---------------------------------------------------------------------- 221 | prmopt: 222 | .word op1txt 223 | .word op2txt 224 | .word op6txt 225 | .word op3txt 226 | .word op4txt 227 | .word op5txt 228 | 229 | prmlen: 230 | .byte 4,18,8,10,20,19 231 | 232 | ;---------------------------------------------------------------------- 233 | SET_PETSCII 234 | op1txt: 235 | .byte "Full" 236 | .byte "Half" 237 | 238 | op2txt: 239 | .byte "User Port 300-2400" 240 | .byte "UP9600 / EZ232 " 241 | .byte "Swift / Turbo DE " 242 | .byte "Swift / Turbo DF " 243 | .byte "Swift / Turbo D7 " 244 | 245 | op6txt: 246 | .byte "Standard" 247 | .byte "Zimodem " 248 | 249 | op3txt: 250 | .byte "Punter " 251 | .byte "XMODEM " 252 | .byte "XMODEM-CRC" 253 | .byte "XMODEM-1K " 254 | 255 | op4txt: 256 | .byte "Classic CCGMS v5.5 " 257 | .byte "Iman / XPB v7.1 " 258 | .byte "Predator / FCC v8.1 " 259 | .byte "Ice theme v9.4 " 260 | .byte "Defcon/Unicess v17.2" 261 | .byte "Alwyz / CCGMS 2021 " 262 | 263 | op5txt: 264 | .res 15,CSR_RIGHT 265 | .byte "EF " 266 | .res 15,CSR_RIGHT 267 | .byte "Disk" 268 | SET_ASCII 269 | 270 | ;---------------------------------------------------------------------- 271 | prmtab: 272 | lda #CR 273 | jsr chrout 274 | jsr chrout 275 | ldx #17 276 | jmp outspc 277 | 278 | ; display duplex, modem type, protocol 279 | prmclc: 280 | tya 281 | asl a 282 | tax 283 | lda prmopt,x 284 | sta prmadr 285 | lda prmopt+1,x 286 | sta prmadr+1 287 | rts 288 | 289 | prmprt: 290 | dex 291 | bmi prmpr2 292 | lda prmadr 293 | clc 294 | adc prmlen,y 295 | sta prmadr 296 | lda prmadr+1 297 | adc #0 298 | sta prmadr+1 299 | bne prmprt 300 | prmpr2 301 | inx 302 | prmadr=*+1 303 | : lda op1txt,x 304 | jsr chrout 305 | inx 306 | txa 307 | cmp prmlen,y 308 | bne :- 309 | jmp prmtab 310 | 311 | ;---------------------------------------------------------------------- 312 | f7parm: 313 | lda #HOME 314 | jsr chrout 315 | lda #1 316 | sta textcl 317 | ldy f7thob 318 | : jsr prmtab 319 | dey 320 | bne :- 321 | jsr prmclc 322 | lda baud_rate 323 | asl a 324 | tax 325 | lda baudrates+1,x 326 | pha 327 | lda baudrates,x 328 | tax 329 | pla 330 | jsr outnum 331 | lda #' ' 332 | jsr chrout 333 | jsr chrout 334 | jsr prmtab 335 | ldy #0 ; duplex 336 | jsr prmclc 337 | ldx half_duplex 338 | jsr prmprt 339 | iny 340 | jsr prmclc 341 | ldx modem_type 342 | jsr prmprt 343 | ldy #2 344 | jsr prmclc 345 | ldx firmware_zimmers 346 | jsr prmprt 347 | ldy #3 348 | jsr prmclc 349 | ldx protoc 350 | jsr prmprt 351 | ldy #4 352 | jsr prmclc 353 | ldx theme 354 | jsr prmprt 355 | lda easyflash_support 356 | beq :+ 357 | ldy #5 358 | jsr prmclc 359 | ldx easyflash_use_disk 360 | jmp prmprt 361 | : rts 362 | 363 | ;---------------------------------------------------------------------- 364 | txt_cmd_scratch: 365 | .byte "S0:",0 366 | 367 | SET_PETSCII 368 | txt_filename: 369 | .byte CLR,CR,WHITE,"Filename: ",0 370 | 371 | filename_config: 372 | .byte "ccgms-phone",0 373 | 374 | f7thob: 375 | .byte 2 376 | 377 | txt_settings_menu: 378 | .byte CLR,16,LOCASE,WHITE 379 | .byte " Dialer/Parameters",CR 380 | .byte BLUE," " 381 | .res 17,$a3 ; $A3: UPPER ONE EIGHTH BLOCK ('▔') 382 | .byte CR,WHITE,16 383 | tcol27a .byte WHITE 384 | .byte " ",HILITE,"auto-Dialer/Phonebook",CR,CR 385 | .byte " ",HILITE,"baud Rate -",CR,CR 386 | .byte " ",HILITE,"duplex -",CR,CR 387 | .byte " ",HILITE,"modem Type -",CR,CR 388 | .byte " ",HILITE,"f" 389 | tcol27b .byte " " 390 | .byte "irmware -",CR,CR 391 | .byte " ",HILITE,"protocol -",CR,CR 392 | .byte " ",HILITE,"theme -",CR,CR,0 393 | 394 | txt_edit_macros: 395 | .byte " ",HILITE,"edit Macros",CR,CR,0 396 | txt_edit_macros_cfg_device: 397 | .byte " ",HILITE,"edit Macros ",HILITE,"cfg Device -",CR,CR,0 398 | 399 | txt_load_save_config: 400 | .byte " ",HILITE,"load/",HILITE,"save Phone Book and Config.",CR,CR 401 | .byte " ",HILITE,"view Instructions",CR,CR,0 402 | 403 | txt_press_return_to_abort: 404 | .byte SETCSR,22,0,WHITE,"Press <",YELLOW,RVSON,"RETURN",RVSOFF,WHITE,"> to abort.",CR,0 405 | 406 | txt_return: 407 | .byte SETCSR,22,7,CYAN,"RETURN",CR,0 408 | SET_ASCII 409 | 410 | ;---------------------------------------------------------------------- 411 | baudrates: 412 | .word 300 413 | .word 1200 414 | .word 2400 415 | .word 4800 416 | .word 9600 417 | .word 19200 418 | .word 38400 419 | 420 | -------------------------------------------------------------------------------- /src/terminal.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2020, Craig Smith, alwyz. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; CCGMS Main Terminal Code 7 | ; 8 | 9 | ; enter here on program start 10 | term_entry_first: 11 | jsr rs232_init 12 | jsr bell 13 | jsr themeroutine 14 | 15 | ; enter here to print banner again 16 | term_entry: 17 | bit col80_enabled 18 | bpl :+ 19 | jsr col80_resume 20 | : jsr print_banner; title screen/CCGMS! 21 | jsr print_instr ; display commands f1 etc to terminal ready 22 | 23 | ; enter here to just return into terminal mode 24 | term_mainloop: 25 | ; turn on 80 col mode again (if requested) 26 | bit col80_active 27 | bmi :+ ; screen model already enabled 28 | jsr col80_resume 29 | : 30 | 31 | lda supercpu 32 | beq @loop1 33 | cmp #2 ; already printed once 34 | beq :+ 35 | lda #txt_supercpu_enabled 37 | jsr outstr 38 | lda #2 39 | sta supercpu 40 | : ; supercpu = turn on 20mhz mode - for after all file transfer situations. 41 | ; already on? turn on again. no biggie. save code. 42 | jsr supercpu_on 43 | 44 | @loop1: 45 | ; print tempbuf unless empty (see phonebook.s) 46 | lda bustemp 47 | beq @skip 48 | ldy #1 49 | : lda tempbuf,y 50 | jsr chrout 51 | iny 52 | cpy bustemp 53 | bne :- 54 | ldy #0 55 | sty bustemp 56 | @skip: 57 | 58 | ldx #$ff 59 | txs 60 | 61 | ; set keyboard matrix routine 62 | lda #<$eb48 ; [XXX this is the KERNAL default; it is never changed] 63 | sta KEYLOG 64 | lda #>$eb48 65 | sta KEYLOG+1 66 | 67 | jsr clrchn 68 | jsr cursor_show 69 | 70 | ;---------------------------------------------------------------------- 71 | ; modem output 72 | @loop2: 73 | lda buffer_ptr 74 | sta newbuf 75 | lda buffer_ptr+1 76 | sta newbuf+1 77 | 78 | jsr clrchn 79 | jsr getin ; get character from keyboard 80 | cmp #0 81 | jeq @input_loop ; skip output code 82 | 83 | .if 0 ; [XXX I don't think this makes sense any more] 84 | ; cbm-ctrl-f: reset/init user port RS-232 85 | cmp #6 ; ctrl-f 86 | bne @no1 87 | ldx SHFLAG 88 | cpx #SHFLAG_CBM | SHFLAG_CTRL 89 | bne @no1 90 | ; cia2ddrb and cia2pb need to be here 91 | ; for user port modem to function 92 | ldx #16 93 | stx cia2ddrb 94 | ldx #0 95 | stx cia2pb 96 | jmp @loop2 97 | @no1 98 | .endif 99 | 100 | ; cmp #UNDERLINE 101 | ; bne @no2 102 | ; ldx SHFLAG ; shift <- toggles 103 | ; beq @no4 ; n/d cursor 104 | ; cpx #SHFLAG_SHIFT 105 | ; beq :+ 106 | ; lda allcap 107 | ; eor #1 108 | ; sta allcap 109 | ; jmp @loop2 110 | ;: jmp toggle_cursor 111 | ;@no2: 112 | 113 | ; shift-ctrl-[1..4]: swap screen 114 | ldx SHFLAG 115 | cpx #SHFLAG_SHIFT | SHFLAG_CTRL 116 | bcc @no3 117 | ldx #3 118 | : cmp COLTAB,x ; PETSCII codes for ctrl-[1..4] 119 | beq :+ 120 | dex 121 | bpl :- 122 | jmp @input_loop 123 | : bit col80_active; unsupported in 80col mode 124 | bpl :+ ; (screen storage already used by bitmap) 125 | jmp term_mainloop 126 | : jmp swap_screen ; x holds pos 0-3 127 | @no3: 128 | 129 | ; shift-stop: hang up 130 | cmp #$83 131 | bne @no4 132 | ldx SHFLAG 133 | cpx #SHFLAG_CBM 134 | bne :+ ; not C= Stop 135 | jsr cursor_off 136 | lda #txt_disconnecting 138 | jsr outstr 139 | jsr rs232_dropdtr 140 | : jmp term_mainloop 141 | @no4: 142 | 143 | ; f1..f8: functions 144 | cmp #133 ; <= F1 145 | bcc @no5 146 | cmp #140+1 ; > F8 147 | bcs @no5 148 | pha 149 | jsr set_bgcolor_0 150 | jsr cursor_off 151 | pla 152 | sec 153 | sbc #133 ; F1 154 | sta tmp03 155 | asl tmp03 156 | clc 157 | adc tmp03 158 | sta @bbcarg 159 | clc 160 | @bbcarg=*+1 161 | bcc *+2 162 | jmp handle_f1_upload 163 | jmp handle_f3_download 164 | jmp handle_f5_diskcommand 165 | jmp handle_f7_config 166 | jmp handle_f2_send_read 167 | jmp handle_f4_buffer 168 | jmp handle_f6_directory 169 | jmp handle_f8_switch_term 170 | @no5: 171 | 172 | ; ldx allcap 173 | ; beq @upplow 174 | ; ldx $d018 175 | ; cpx #23 176 | ; bne @upplow 177 | ; cmp #$41 178 | ; bcc @upplow 179 | ; cmp #$5b ;'z'+1 180 | ; bcs @upplow 181 | ; ora #$80 182 | ;@upplow: 183 | 184 | ; ASCII conversion 185 | sta tmp03 186 | ldx ascii_mode 187 | beq :+ 188 | jsr petscii_to_ascii 189 | bne :+ 190 | @loop2b: 191 | jmp @loop2 192 | : 193 | 194 | ; send to modem 195 | jsr rs232_put 196 | 197 | ; convert back to PETSCII 198 | ldx ascii_mode 199 | beq :+ 200 | jsr ascii_to_petscii 201 | sta tmp03 202 | jeq @loop2 203 | : 204 | 205 | ; half-duplex 206 | ldx half_duplex 207 | beq @nohd 208 | jsr clrchn 209 | lda tmp03 ; char 210 | ldx ascii_mode 211 | beq :+ 212 | cmp #UNDERLINE ; [XXX no-op] 213 | bne :+ ; [XXX no-op] 214 | lda #UNDERLINE 215 | sta tmp03 ; _ in ascii/half dup 216 | : jmp @bufchk ; skip modem input 217 | @nohd: 218 | 219 | ;---------------------------------------------------------------------- 220 | ; modem input 221 | @input_loop: 222 | jsr clrchn 223 | 224 | ; macro printing 225 | ldx SHFLAG 226 | cpx #SHFLAG_CTRL; ctrl pressed 227 | bne :+ 228 | ldx LSTX ; last keyboard scancode 229 | cpx #3 ; 3-6 are F7/F1/F3/F5 230 | bcc :+ ; [XXX this branches into code that checks X 231 | cpx #7 ; [XXX thinking it's SHFLAG; it works by accident] 232 | bcs :+ 233 | lda #0 234 | sta macro_dry_run_mode 235 | jsr print_macro 236 | jmp @loop1 237 | : 238 | 239 | .if 0 ; charset switching [XXX this has no effect ever] 240 | cpx #SHFLAG_SHIFT | SHFLAG_CBM 241 | bne :+ 242 | ldx MODE ; charset switching allowed? 243 | bpl :+ ; no 244 | ldx #$17 245 | stx $d018 ; set lowercase charset 246 | : 247 | .endif 248 | 249 | ; modem input 250 | jsr rs232_get 251 | cmp #0 252 | beq @loop2b ; = @loop2 253 | ldx status 254 | bne @loop2b ; = @loop2 255 | 256 | .if AUTOMATION ; only enabled for automated tests 257 | cmp #3 ; code 3 (STOP) 258 | bne @nauto 259 | ldy #0 260 | : jsr rs232_get 261 | ldx status 262 | bne :- 263 | sta KEYD,y ; keyboard buffer 264 | iny 265 | cmp #3 ; code 3 (STOP) 266 | bne :- 267 | sty NDX ; buffer count 268 | jmp @loop2 269 | @nauto: 270 | .endif 271 | 272 | ; ASCII conversion 273 | ldx ascii_mode 274 | beq :+ 275 | jsr ascii_to_petscii 276 | beq @input_loop 277 | : cmp #DEL 278 | bne @bufchk ; [XXX no-op] 279 | lda #$14 ; [XXX no-op; was: $5F in Craig Smith source] 280 | @bufchk: 281 | jsr buffer_put 282 | jmp contn 283 | 284 | ; [XXX this code is at a very awkward location, could be integrated better] 285 | ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 286 | ; store modem byte into buffer 287 | buffer_put: 288 | ; skip if closed 289 | ldx buffer_open 290 | beq @4 291 | ; skip if full 292 | ldx buffer_ptr 293 | cpx bufend 294 | bne @1 295 | ldx buffer_ptr+1 296 | cpx bufend+1 297 | beq @4 298 | 299 | @1: ldy reu_enabled 300 | beq @2 301 | jsr reuwrite 302 | jmp @3 303 | 304 | @2: ldy #0 305 | sta (buffer_ptr),y 306 | @3: inc buffer_ptr 307 | bne @4 308 | inc buffer_ptr+1 309 | @4: rts 310 | ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 311 | 312 | contn: 313 | jsr handle_control_codes 314 | bcc contn2 315 | jmp term_mainloop 316 | 317 | ; [XXX this code is at a very awkward location, could be integrated better] 318 | ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 319 | ; handle control codes sent from the BBS 320 | handle_control_codes: 321 | cmp #$0a ; ctrl-j: cursor on 322 | beq @1 323 | cmp #$0b ; ctrl-k: cursor off 324 | bne @2 325 | 326 | @1: 327 | ldx ascii_mode 328 | bne @2 329 | pha 330 | jsr cursor_off 331 | pla 332 | and #1 ; form to ch flag 333 | eor #1 334 | sta cursor_flag 335 | sec 336 | rts 337 | 338 | @2: 339 | cmp #$0e ; ctrl-n: reset background to black 340 | bne @3 341 | 342 | pha 343 | jsr set_bgcolor_0 344 | pla 345 | 346 | @3: 347 | cmp #$07 ; ctrl-g: bell sound from bbs side 348 | bne @4 349 | 350 | jsr bell 351 | 352 | @4: 353 | cmp #$16 ; ctrl-v: end of file transfer or boomy sound 354 | bne @5 355 | 356 | jsr gong 357 | 358 | @5: 359 | ; cmp #$15 ; ctrl-u: uppercase from bbs side 360 | ; bne @6 361 | 362 | ; ldx #$15 363 | ; stx $d018 364 | ; bne ctrlex 365 | 366 | ;@6: 367 | ; cmp #$0c ; ctrl-l: lowercase from bbs side 368 | ; bne @7 369 | 370 | ; ldx #$17 371 | ; stx $d018 372 | ; bne ctrlex 373 | 374 | ;@7: 375 | ; cmp #$5f ; false del 376 | ; bne @8 ; (buff and 1/2 duplx) 377 | 378 | ; lda #DEL 379 | ; bne ctrlex 380 | 381 | ;@8: 382 | ldx prev_char 383 | cpx #$02 ; ctrl-b: set background color 384 | bne @9 385 | 386 | ldx #15 387 | : cmp COLTAB,x ; check ctrl+[1-8], cbm+[1-8] 388 | beq :+ 389 | dex 390 | bpl :- 391 | bmi @9 392 | : txa 393 | jsr set_bgcolor 394 | lda #$10 ; ctrl-p: non printable 395 | @9: 396 | sta prev_char 397 | clc 398 | rts 399 | ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 400 | 401 | contn2: 402 | pha 403 | jsr cursor_off 404 | pla 405 | jsr chrout ; print input byte to screen 406 | jsr quote_insert_off; kill modes the char might have enabled 407 | jmp term_mainloop 408 | 409 | -------------------------------------------------------------------------------- /rs232lib/rs232_up9600.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2022, Craig Smith, alwyz, Michael Steil. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; RS232 UP9600 Driver 7 | ; based on source from "the UP9600 email", Nov 23 1997 by Daniel Dallmann 8 | ; Message-Id: <199711301621.RAA01078@dosbuster.home.dd> 9 | ; 10 | 11 | .include "rs232_kernal.inc" 12 | .include "c64.inc" ; CIA#1/CIA#2 defines 13 | .import ribuf, revtabup ; external 14 | .import rs232_rti 15 | 16 | ; function table for dispatcher 17 | .export up9600_funcs 18 | 19 | oldirq = $ea31 20 | oldnmi = $fe47 21 | 22 | ; zero page 23 | sndtim = $a7 ; reuse range $a7-$ab, 24 | rcvtim = $a9 ; which is used by the 25 | outstat = $ab ; KERNAL RS-232 driver 26 | 27 | RTS_MIN = 50 ; buffer low mark, will enable Request To Send 28 | RTS_MAX = 200 ; buffer high mark, will disable Request To Send 29 | 30 | ; CIA ICR 31 | ICR_TA = %00000001 32 | ICR_TB = %00000010 33 | ICR_SP = %00001000 34 | ICR_FLG = %00010000 35 | ICR_IR = %10000000 36 | ; CIA CR 37 | CR_START= %00000001 38 | CR_PBON = %00000010 39 | CR_LOAD = %00010000 40 | CR_SPOUT= %01000000 41 | CR_TOD = %10000000 42 | 43 | .segment "RS232" 44 | 45 | ;---------------------------------------------------------------------- 46 | up9600_funcs: 47 | .word up9600_setup 48 | .word up9600_enable 49 | .word up9600_disable 50 | .word up9600_getxfer 51 | .word up9600_putxfer 52 | .word up9600_dropdtr 53 | 54 | ;---------------------------------------------------------------------- 55 | up9600_nmi: 56 | bit cia2icr ; NMI caused by CIA#2? 57 | nmi_bmi=*+1 58 | bmi nmi_startbit; yes (pointer to target will be overwritten!) 59 | jmp rs232_rti ; otherwise triggered by RESTORE key -> ignore 60 | 61 | ; NMI triggered by start bit (FLAG transition from 1 to 0) 62 | nmi_startbit: 63 | pha 64 | 65 | ; load and start timer B (which is in continuous mode) and 66 | ; output a pulse to PB7 on every underflow 67 | ; (The UP9600 hardware wires the PB7 output to the CNT2 input, 68 | ; so timer B will clock the SDR!) 69 | lda #CR_LOAD|CR_PBON|CR_START 70 | sta cia2crb 71 | 72 | ; disable timer and FLAG NMIs, leave SDR NMI on 73 | .assert ICR_FLG|ICR_TB|ICR_TA = CR_LOAD|CR_PBON|CR_START, error 74 | sta cia2icr ; (one bitmask used for two purposes!) 75 | 76 | ; switch to other handler on next NMI (triggered by SDR full) 77 | lda #nmi_bytrdy-nmi_bmi-1 78 | sta nmi_bmi 79 | 80 | pla 81 | jmp rs232_rti 82 | 83 | ; NMI triggered by SDR full 84 | nmi_bytrdy: 85 | pha 86 | txa 87 | pha 88 | 89 | ; set up CIA#2 to tigger NMI on next start bit 90 | lda #CR_TOD|CR_LOAD|CR_PBON 91 | sta cia2crb ; stop timer B, signal at PB7 92 | .assert ICR_IR|ICR_FLG|ICR_TB = CR_TOD|CR_LOAD|CR_PBON, error 93 | ; (use one bitmask for two purposes) 94 | sta cia2icr ; enable FLAG interrupt (and unused timer B) 95 | 96 | ; switch to other handler on next NMI (triggered by start bit) 97 | lda #nmi_startbit-nmi_bmi-1 98 | sta nmi_bmi 99 | 100 | ; read data byte and reverse bit order 101 | lda cia2sdr ; read data byte from SDR (bit order is reversed) 102 | cmp #$80 ; move bit 7 into C 103 | and #$7f 104 | tax 105 | lda revtabup,x ; reverse bits 1-7 using lookup table 106 | adc #0 ; move original bit 7 into bit 0 107 | 108 | ; write data byte into receive buffer 109 | ldx rtail 110 | sta ribuf,x 111 | inx 112 | stx rtail 113 | 114 | ; disable Request To Send (RTS) if buffer almost full 115 | sec 116 | txa 117 | sbc rhead 118 | cmp #RTS_MAX 119 | bcc :+ 120 | lda cia2pb 121 | and #<~2 ; disable Request To Send (RTS) 122 | sta cia2pb 123 | : 124 | pla 125 | tax 126 | pla 127 | jmp rs232_rti 128 | 129 | ;---------------------------------------------------------------------- 130 | ; A: modem_type 131 | ; X: baud_rate 132 | ; Y: is_pal_system 133 | up9600_setup: 134 | sty is_pal_system 135 | jsr up9600_setbaud 136 | 137 | ; generate lookup table 138 | ldx #0 139 | @1: stx outstat ; (reuse outstat as temp) 140 | ldy #8 141 | @2: asl outstat 142 | ror 143 | dey 144 | bne @2 145 | sta revtabup,x 146 | inx 147 | bpl @1 148 | 149 | ; run into up9600_enable 150 | 151 | ;---------------------------------------------------------------------- 152 | ; enable serial interface (IRQ+NMI) 153 | up9600_enable: 154 | sei 155 | 156 | ldx #new_irq 158 | stx $0314 159 | sty $0315 160 | 161 | lda #nmi_startbit-nmi_bmi-1 162 | sta nmi_bmi 163 | ldx #up9600_nmi 165 | stx $0318 166 | sty $0319 167 | 168 | ; move KERNAL's 60 Hz timer interrupt to timer B 169 | is_pal_system = *+1 170 | ldx #0 171 | lda ilotab,x 172 | sta cia1tblo 173 | lda ihitab,x 174 | sta cia1tbhi 175 | 176 | ; set CIA#1 timer A start value: 1/(2*baudrate) 177 | lda rcvtim 178 | sta cia1talo 179 | lda rcvtim+1 180 | sta cia1tahi 181 | 182 | ; set CIA#2 timer B start value: 1/baudrate 183 | lda sndtim 184 | sta cia2tblo 185 | lda sndtim+1 186 | sta cia2tbhi 187 | 188 | ; start timer A of CIA#1, SP1 used as output 189 | ; generates the sender's bit clock 190 | lda #CR_SPOUT|CR_START 191 | sta cia1cra 192 | 193 | lda #1 194 | sta outstat 195 | 196 | .assert ICR_TA = 1, error 197 | sta cia1icr ; disable timer A (CIA#1) interrupt 198 | 199 | .assert CR_START = 1, error 200 | sta cia1crb ; start timer B of CIA#1 (generates keyscan IRQ) 201 | 202 | lda #CR_TOD|CR_LOAD|CR_PBON; stop timer B of CIA#2 (enable signal at PB7) 203 | sta cia2crb 204 | 205 | ; CIA#2: enable FLAG (start bit) and SDR (byte received) NMIs 206 | lda #ICR_IR|ICR_FLG|ICR_SP 207 | bit cia2icr ; clear pending NMIs 208 | sta cia2icr 209 | 210 | ; CIA#1: enable timer B (60 Hz) and SDR (8 bits sent) IRQs 211 | lda #%10001010 212 | sta cia1icr 213 | 214 | lda #%11111111 215 | sta cia2pb ; PB0-7 default to 1 216 | sta cia1sdr ; SP1 defaults to 1 217 | 218 | lda #2 ; enable Request To Send (RTS) 219 | sta cia2ddrb ; (the RTS line is the only output) 220 | 221 | cli 222 | rts 223 | 224 | ;---------------------------------------------------------------------- 225 | ; new IRQ handler 226 | new_irq: 227 | lda cia1icr ; read IRQ mask 228 | lsr 229 | lsr ; move bit 1 into C (timer B) 230 | and #2 ; test bit 3 (SDR) 231 | beq @nsdr ; no 232 | 233 | ; SDR IRQ: count down expected SDR IRQ counter 234 | ldx outstat 235 | beq :+ ; skip, if we're not waiting for an empty SDR 236 | dex 237 | stx outstat 238 | : 239 | 240 | bcc @notim ; skip if there was no timer B underflow 241 | 242 | @nsdr: cli ; [XXX allow nested IRQs???] 243 | ; [XXX label should be at bcc OR bcc should be removed] 244 | ; [XXX there is no other source set up, so the bcc] 245 | ; [XXX would never be taken anyway] 246 | jsr $ffea ; update jiffy clock 247 | jsr $ea87 ; scan keyboard 248 | 249 | @notim: jmp $ea81 250 | 251 | ;---------------------------------------------------------------------- 252 | CLOCK_PAL = 4433619 * 4 / 18 ; 985,249 Hz 253 | CLOCK_NTSC = 3579545 * 4 / 14 ; 1,022,727 Hz 254 | TIMER_FREQ = 60 255 | ITIMER_NTSC = (CLOCK_NTSC * 10 / TIMER_FREQ + 5) / 10 ; $4295 256 | ITIMER_PAL = (CLOCK_PAL * 10 / TIMER_FREQ + 5) / 10 ; $4025 257 | 258 | .define itab ITIMER_NTSC, ITIMER_PAL 259 | ilotab: .lobytes itab 260 | ihitab: .hibytes itab 261 | 262 | ;---------------------------------------------------------------------- 263 | MIN_BAUD = 300 264 | TIMER_PAL = CLOCK_PAL / MIN_BAUD 265 | TIMER_NTSC = CLOCK_NTSC / MIN_BAUD 266 | 267 | up9600_setbaud: 268 | ; X: baud_rate 269 | ; Y: is_pal_system 270 | ; [XXX technically, the timer values need to be 1 less] 271 | txa 272 | pha ; baud_rate 273 | 274 | lda #TIMER_NTSC 276 | cpy #0 ; is_pal_system 277 | beq :+ 278 | lda #TIMER_PAL 280 | : sta sndtim 281 | stx sndtim+1 282 | 283 | pla ; baud_rate 284 | tax ; 0=300, 1=1200, 2=2400 etc. 285 | beq :+ 286 | inx ; -> 0=300, 2=1200, 3=2400 etc. 287 | : txa 288 | beq @skip 289 | @loop: lsr sndtim+1 ; divide by 2 repeatedly 290 | ror sndtim 291 | dex 292 | bne @loop 293 | @skip: lda sndtim+1 294 | lsr 295 | sta rcvtim+1 296 | lda sndtim 297 | ror 298 | sta rcvtim 299 | rts 300 | 301 | ;---------------------------------------------------------------------- 302 | ; get byte from serial interface 303 | up9600_getxfer: 304 | ldx rhead 305 | cpx rtail 306 | beq @skip ; empty buffer, return with carry set 307 | lda ribuf,x 308 | inx 309 | stx rhead 310 | 311 | ; if buffer is running low, enable Request To Send (RTS) 312 | pha 313 | txa 314 | sec 315 | sbc rtail 316 | cmp #RTS_MIN 317 | bcc :+ 318 | lda #2 319 | ora cia2pb 320 | sta cia2pb 321 | : clc 322 | pla 323 | 324 | @skip: rts 325 | 326 | ;---------------------------------------------------------------------- 327 | up9600_putxfer: 328 | stx save_x 329 | pha 330 | 331 | ; reverse bit order (part 1) 332 | cmp #$80 ; move bit 7 into C 333 | and #$7f 334 | tax ; (continue later...) 335 | 336 | ; wait for previous transmission to finish (with timeout) 337 | cli 338 | lda #$100-3 ; 50 ms timeout 339 | sta JIFFIES 340 | : lda outstat 341 | beq :+ 342 | bit JIFFIES 343 | bmi :- 344 | : 345 | 346 | ; set TXD to 1 (stop bit) 347 | lda #%00000100 348 | ora cia2pa 349 | sta cia2pa 350 | 351 | ; check Data Terminal Ready (DTR) and Clear To Send (CTS) 352 | : lda cia2pb 353 | and #%01000100 ; CTS and DTR 354 | eor #%00000100 355 | beq :- ; loop while CTR=0 and DTR=1 356 | 357 | ; reverse bit order (part 2) 358 | lda revtabup,x ; reverse bits 1-7 using lookup table 359 | adc #0 ; add bit0 360 | 361 | ; send first byte 362 | lsr ; start bit (0) into MSB, 7 data bits 363 | sta cia1sdr ; send through SDR 364 | 365 | lda #2 ; expect 2 SDR IRQs per data byte sent 366 | sta outstat 367 | 368 | ; send second byte 369 | ror ; bit 0 into MSB 370 | ora #$7f ; fill with 7 stop bits (1) 371 | sta cia1sdr ; send through SDR 372 | 373 | clc 374 | save_x=*+1 375 | ldx #0 376 | pla 377 | rts 378 | 379 | ;---------------------------------------------------------------------- 380 | ; disable serial interface 381 | up9600_disable: 382 | sei 383 | lda #%01111111 384 | sta cia2icr ; disable all CIA#2 NMIs 385 | sta cia1icr ; disable all CIA#1 IRQs 386 | lda #$41 ; quick (and dirty) hack to switch back 387 | sta cia1tahi ; to the default CIA#1 configuration [XXX use real numbers] 388 | lda #ICR_IR|ICR_TA 389 | sta cia1icr ; enable timer A (this is default) 390 | 391 | ; restore original NMI handler 392 | lda #oldnmi 395 | sta $0319 396 | ; restore original IRQ handler 397 | lda #oldirq 400 | sta $0315 401 | cli 402 | rts 403 | 404 | ;---------------------------------------------------------------------- 405 | ; Hang up 406 | up9600_dropdtr: 407 | lda #%00000100 408 | sta cia2ddrb 409 | lda #%00000010 410 | sta cia2pb 411 | ldx #$100-30 ; 1/2 sec 412 | stx JIFFIES 413 | : bit JIFFIES 414 | bmi :- 415 | lda #%00000010 416 | sta cia2ddrb 417 | rts 418 | -------------------------------------------------------------------------------- /src/xfer.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2020, Craig Smith, alwyz. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; File transfer generic code and UI 7 | ; 8 | 9 | ;---------------------------------------------------------------------- 10 | SET_PETSCII 11 | txt_xmodem: 12 | .byte "XMODEM",0 13 | txt_xmodem_crc: 14 | .byte "XMODEM-CRC",0 15 | txt_xmodem_1k: 16 | .byte "XMODEM-1K",0 17 | SET_ASCII 18 | 19 | ;---------------------------------------------------------------------- 20 | ; display "[protocol], enter name" and input string 21 | ; A=0: upload, 1:download 22 | ui_prompt_filename: 23 | pha 24 | lda protoc 25 | beq @2 ; PROTOCOL_PUNTER 26 | lda #CR 27 | jsr chrout 28 | jsr chrout 29 | lda #WHITE 30 | jsr chrout 31 | pla 32 | pha 33 | bne @download 34 | ; upload 35 | lda protoc 36 | cmp #PROTOCOL_XMODEM_1K 37 | beq @upload_1k 38 | ; XMODEM or XMODEM-CRC setting: 39 | ; * we will enforce 128B block sizes, 40 | ; * checksum vs. CRC is up to the receiver 41 | lda #txt_xmodem 43 | jsr outstr 44 | lda #'/' 45 | jsr chrout 46 | lda #txt_xmodem_crc 48 | jsr outstr 49 | jmp @3 50 | @upload_1k: 51 | ; XMODEM-1K setting: 52 | ; * we will enforce 128B block sizes, 53 | ; * checksum vs. CRC is up to the receiver 54 | lda #txt_xmodem_1k 56 | jsr outstr 57 | jmp @3 58 | @download: 59 | lda protoc 60 | cmp #PROTOCOL_XMODEM 61 | beq @download_old 62 | ; XMODEM-CRC or XMODEM-1K setting: 63 | ; * we will enforce CRC 64 | ; * 128 vs. 1K is up to the sender 65 | lda #txt_xmodem_crc 67 | jsr outstr 68 | lda #'/' 69 | jsr chrout 70 | lda #txt_xmodem_1k 72 | jsr outstr 73 | jmp @3 74 | @download_old: 75 | ; XMODEM setting: 76 | ; * we will enforce checkums 77 | ; * 128 vs. 1K is up to the sender 78 | lda #txt_xmodem 80 | jsr outstr 81 | jmp @3 82 | @2: lda #txt_newpunter 84 | jsr outstr 85 | @3: lda #' ' 86 | jsr chrout 87 | pla 88 | bne @4 89 | lda #txt_up 91 | clc 92 | bcc @5 93 | @4: lda #txt_down 95 | @5: jsr outstr 96 | lda #txt_load 98 | jsr outstr 99 | ;---------------------------------------------------------------------- 100 | ui_get_filename: 101 | ldx #0 102 | : lda #0 103 | sta inpbuf,x 104 | inx 105 | cpx #20 106 | bne :- 107 | lda #txt_enter_filename 109 | ldx #16 110 | jsr input 111 | php 112 | lda #CR 113 | jsr chrout 114 | plp 115 | rts 116 | 117 | ;---------------------------------------------------------------------- 118 | ui_abort: 119 | jsr clrchn 120 | lda #txt_aborted 122 | jsr outstr 123 | jsr text_color_restore 124 | jsr rs232_off 125 | lda #LFN_FILE 126 | jsr close 127 | jsr rs232_on 128 | jmp term_mainloop 129 | 130 | ;---------------------------------------------------------------------- 131 | xfermd pha 132 | jmp xferm0 133 | 134 | ;---------------------------------------------------------------------- 135 | ui_setup_xfer_screen: 136 | pha 137 | lda #15 138 | sta textcl ; LT GRAY 139 | sta backgr ; make sure CLS fills will LT GRAY 140 | lda #CLR 141 | jsr chrout 142 | lda #BCOLOR 143 | sta backgr ; restore screen background color 144 | xferm0 lda #13 145 | sta LINE 146 | lda #CR 147 | jsr chrout 148 | lda #6 149 | sta textcl 150 | ldx #40 151 | lda #192 ; "─" 152 | : jsr chrout 153 | dex 154 | bne :- 155 | lda #txt_yellow 157 | jsr outstr 158 | pla 159 | bne @1 160 | lda #txt_up 162 | clc 163 | bcc @2 164 | @1: lda #txt_down 166 | @2: jsr outstr 167 | lda #txt_loading 169 | jsr outstr 170 | ldy #0 171 | : lda inpbuf,y 172 | jsr chrout 173 | iny 174 | cpy max 175 | bne :- 176 | lda inpbuf,y 177 | jsr chrout 178 | lda inpbuf+1,y 179 | jsr chrout 180 | lda #CR 181 | jsr chrout 182 | lda #txt_press_c_to_abort 184 | jmp outstr 185 | margin: 186 | lda #txt_good_bad_blocks 188 | jmp outstr 189 | 190 | ;---------------------------------------------------------------------- 191 | upltyp: 192 | .byte 0,'P','S','U' 193 | 194 | ;---------------------------------------------------------------------- 195 | handle_f1_upload: 196 | jsr col80_pause 197 | jsr supercpu_off 198 | jsr rs232_off 199 | jsr text_color_save 200 | lda #0 201 | sta mulcnt 202 | jsr ui_prompt_filename 203 | jeq ui_abort 204 | jsr ercopn 205 | ldy max 206 | lda #',' 207 | sta inpbuf,y 208 | lda #'P' 209 | sta inpbuf+1,y 210 | jsr filtes 211 | beq uplfil 212 | ldy max 213 | lda #'S' 214 | sta inpbuf+1,y 215 | jsr filtes 216 | beq uplfil 217 | ldy max 218 | lda #'U' 219 | sta inpbuf+1,y 220 | uplmen: 221 | jsr filtes 222 | beq uplfil 223 | pha 224 | ldx #LFN_DISK_CMD 225 | jsr chkin 226 | pla 227 | jmp drver3 228 | uplfil: ldy max 229 | ldx #3 230 | : lda upltyp,x 231 | cmp inpbuf+1,y 232 | beq :+ 233 | dex 234 | bne :- 235 | : stx filetype 236 | jmp uplok 237 | 238 | ;---------------------------------------------------------------------- 239 | filtes: 240 | ldy max 241 | iny 242 | iny 243 | tya 244 | ldx #inpbuf 246 | jsr setnam 247 | lda #LFN_FILE 248 | ldx device_disk 249 | ldy #0 250 | jsr setlfs 251 | filopn: 252 | jsr open 253 | ldx #LFN_DISK_CMD 254 | jsr chkin 255 | jsr getin 256 | cmp #'0' 257 | beq :+ 258 | php 259 | pha 260 | lda #LFN_FILE 261 | jsr close 262 | pla 263 | plp 264 | : rts 265 | 266 | ;---------------------------------------------------------------------- 267 | uplok: 268 | lda #0 269 | jsr ui_setup_xfer_screen 270 | jsr clrchn 271 | lda protoc 272 | beq :+ ; PROTOCOL_PUNTER 273 | ; XMODEM 274 | jsr crctable 275 | jsr margin 276 | jmp xmodem_upload 277 | 278 | : ; PUNTER 279 | jsr rs232_clear 280 | jsr punter_reset 281 | jsr punter_trantype; transmit file type header 282 | lda inpbuf 283 | cmp #1 284 | bne :+ ; not user cancelled 285 | jsr bell 286 | jmp ui_abort 287 | 288 | : jsr margin 289 | jsr punter_reset 290 | lda #$ff 291 | sta maxsize 292 | jsr punter_transmit; transmit file contents 293 | xfrend: 294 | jsr rs232_off 295 | lda #LFN_FILE 296 | jsr close 297 | jsr clrchn 298 | lda #CR 299 | jsr chrout 300 | lda mulcnt 301 | beq :+ 302 | rts 303 | : lda inpbuf 304 | cmp #1 305 | bne xfrdun 306 | jmp ui_abort 307 | xfrdun: 308 | jsr reset ; clear and reenable 309 | jsr gong 310 | jmp term_mainloop 311 | 312 | ;---------------------------------------------------------------------- 313 | handle_f3_download: 314 | jsr col80_pause 315 | jsr rs232_off 316 | lda #0 317 | sta mulcnt 318 | jsr text_color_save 319 | jsr supercpu_off 320 | lda #1 321 | jsr ui_prompt_filename 322 | jeq ui_abort 323 | lda protoc 324 | beq :+ ; PROTOCOL_PUNTER 325 | jsr prompt_file_type 326 | jmp dowmen 327 | : ldy max 328 | lda #160 329 | sta inpbuf,y 330 | sta inpbuf+1,y 331 | dowmen: 332 | lda #1 333 | jsr ui_setup_xfer_screen 334 | ldx protoc 335 | bne @1 ; != PROTOCOL_PUNTER 336 | lda inpbuf 337 | pha 338 | jsr clrchn 339 | jsr punter_reset; enable rs232 to receive;reset 340 | jsr punter_rectype; zero out punter buffers for new download and get file info from sender 341 | ldx inpbuf 342 | pla 343 | sta inpbuf 344 | lda mulcnt 345 | bne @1 346 | cpx #1 347 | bne @1 348 | jsr bell 349 | jmp ui_abort 350 | 351 | @1: ldx #$ff 352 | stx maxsize 353 | jsr rs232_off 354 | jsr ercopn 355 | ldx #LFN_DISK_CMD 356 | jsr chkout 357 | lda #'I' 358 | jsr chrout 359 | lda #'0' 360 | jsr chrout 361 | lda #CR 362 | jsr chrout 363 | jsr clrchn 364 | ldx #LFN_DISK_CMD 365 | jsr chkout 366 | lda #'S' 367 | jsr chrout 368 | lda #'0' 369 | jsr chrout 370 | lda #':' 371 | jsr chrout 372 | ldx #0 373 | : lda inpbuf,x 374 | jsr chrout 375 | inx 376 | cpx max 377 | bne :- 378 | lda #CR 379 | jsr chrout 380 | jsr dowsfn 381 | lda #1 382 | jsr xfermd 383 | jsr margin 384 | jmp dowopn 385 | 386 | ;---------------------------------------------------------------------- 387 | dowsfn: 388 | jsr clrchn 389 | ldx max 390 | lda #',' 391 | sta inpbuf,x 392 | sta inpbuf+2,x 393 | inx 394 | lda #'W' 395 | sta inpbuf+2,x 396 | lda mulcnt 397 | bne :+ 398 | ldy filetype 399 | lda upltyp,y 400 | sta inpbuf,x 401 | : lda max 402 | clc 403 | adc #$04 404 | ldx #inpbuf 406 | jsr setnam 407 | lda #LFN_FILE 408 | ldx device_disk 409 | tay 410 | jmp setlfs 411 | 412 | ;---------------------------------------------------------------------- 413 | dowopn: 414 | jsr filopn 415 | beq :+ 416 | pha 417 | ldx #LFN_DISK_CMD 418 | jsr chkin 419 | pla 420 | jmp drver3 421 | 422 | : lda protoc 423 | beq :+ ; PROTOCOL_PUNTER 424 | jsr crctable ; create crc tables 425 | jmp xmodem_download; pick punter or xmodem here to really start downloading 426 | 427 | : jsr punter_reset; reset 428 | jsr punter_receive; get data 429 | jsr rs232_clear 430 | jmp xfrend ; close file 431 | 432 | ;---------------------------------------------------------------------- 433 | SET_PETSCII 434 | txt_read_or_send: 435 | .byte CR,CR,WHITE,HILITE,"read or",HILITE,"send file? ",0 436 | txt_read_or_send2: 437 | .byte "Space to pause - R/S to abort",CR,CR,0 438 | SET_ASCII 439 | 440 | ;---------------------------------------------------------------------- 441 | handle_f2_send_read: 442 | ldx SHFLAG 443 | cpx #SHFLAG_CBM 444 | bne send 445 | jmp cf1_multi_send 446 | 447 | ;---------------------------------------------------------------------- 448 | ; send text file 449 | send: 450 | jsr col80_pause 451 | jsr rs232_off 452 | jsr text_color_save 453 | lda #txt_read_or_send 455 | jsr outstr 456 | jsr invert_csr_char 457 | @loop: jsr getin 458 | cmp #'S' 459 | bne @1 460 | ldx #$40 ; flags: disk to modem, with delay 461 | bne @3 462 | @1: cmp #'R' 463 | bne @2 464 | ldx #0 ; flags: disk screen, no delay 465 | beq @3 466 | @2: cmp #CR 467 | bne @loop 468 | jsr restore_csr_char 469 | lda #CR 470 | jsr chrout 471 | @abt: jmp ui_abort 472 | 473 | @3: ora #$80 474 | jsr outcap 475 | lda #CR 476 | jsr chrout 477 | stx bufflg ; flags: disk/mem, delay/no delay 478 | stx buffl2 ; flags: send to modem 479 | jsr ui_get_filename 480 | beq @abt 481 | lda #CR 482 | jsr chrout 483 | jsr col80_resume 484 | lda max 485 | ldx #inpbuf 487 | jsr setnam 488 | lda #txt_read_or_send2 490 | jsr outstr 491 | lda #LFN_FILE 492 | ldx device_disk 493 | tay 494 | jsr setlfs 495 | jsr open 496 | jsr dskout 497 | lda #LFN_FILE 498 | jsr close 499 | lda #0 500 | jsr rs232_on 501 | jsr text_color_set 502 | lda #CR 503 | jsr chrout 504 | jmp term_mainloop 505 | 506 | ;---------------------------------------------------------------------- 507 | .byte 0 ; [XXX unused] 508 | 509 | ;---------------------------------------------------------------------- 510 | sleep_50ms: 511 | ldx #0 512 | stx JIFFIES 513 | : ldx JIFFIES 514 | cpx #3 ; delay 1/20 sec 515 | bcc :- 516 | ldx #$ff 517 | : dex ; [XXX this delay is insignificant in comparison] 518 | bne :- 519 | rts 520 | -------------------------------------------------------------------------------- /src/multixfer.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2020, Craig Smith, alwyz. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; Punter Multi-Transfer 7 | ; 8 | 9 | ;---------------------------------------------------------------------- 10 | SET_PETSCII 11 | txt_multixfer: 12 | .byte CR,WHITE,"Multi-transfer - Punter only.",CR,0 13 | SET_ASCII 14 | 15 | ;---------------------------------------------------------------------- 16 | cf1_multi_send: 17 | jsr col80_pause 18 | jsr text_color_save 19 | lda protoc 20 | beq mulsav ; PROTOCOL_PUNTER 21 | mulnop: 22 | lda #txt_multixfer 24 | jsr outstr 25 | jmp ui_abort 26 | 27 | mulsav: 28 | jsr supercpu_off 29 | lda #CLR 30 | jsr chrout 31 | 32 | ; lda buffer_ptr+1; old references comparing buffer area and making sure theres enough 33 | ; cmp #>mulfil ; room for punter files to be stored, but since we're now 34 | ; bcc mulsok ; reserving #$ff space for punter, its not neccessary 35 | ; lda buffer_ptr 36 | ; cmp #mlswrn 40 | ; jsr outstr 41 | ; jmp ui_abort 42 | ;mulsok 43 | 44 | lda #txt_multisend_select 46 | jsr outstr 47 | lda #txt_yesnoquit 49 | jsr outstr 50 | jsr select_files_from_disk 51 | lda mulcnt ; some files to send? 52 | bne mlss1 ; yes 53 | mlss0 jmp mlssab ; nope, we are done 54 | mlss1 55 | lda mulfln 56 | sta mulcnt ; how many files to send. decrement until none left 57 | beq mlss0 58 | lda #0 59 | sta mulfln 60 | lda #mulfil 63 | sta tmpfd+1 64 | mlslop 65 | ldy #19 66 | lda (tmpfd),y 67 | bne mlssen 68 | mlsinc 69 | lda tmpfd 70 | clc 71 | adc #20 72 | sta tmpfd 73 | lda tmpfd+1 74 | adc #0 75 | sta tmpfd+1 76 | lda tmpfd+1 77 | cmp #>endmulfil 78 | bcc mlslop 79 | jmp mulab2 80 | mlssen 81 | ldy #17 82 | mlss2 lda (tmpfd),y 83 | cmp #$a0 84 | bne mlss3 85 | dey 86 | cpy #1 87 | bne mlss2 88 | jmp mulab2 89 | mlss3 dey 90 | sty max 91 | iny 92 | mlss4 lda (tmpfd),y 93 | sta inpbuf-2,y 94 | dey 95 | cpy #1 96 | bne mlss4 97 | ldx max 98 | lda #',' 99 | sta inpbuf,x 100 | ldy #18 101 | lda (tmpfd),y 102 | and #7 103 | cmp #4 104 | bne mlsg 105 | jmp mulabt 106 | mlsg 107 | tay 108 | lda drtype,y 109 | sta inpbuf+1,x 110 | mlsgo 111 | jsr mlshdr 112 | ldy #0 113 | mlsgo1 lda inpbuf,y 114 | jsr rs232_put 115 | iny 116 | cpy max 117 | bne mlsgo1 118 | lda inpbuf,y 119 | jsr rs232_put 120 | lda inpbuf+1,y 121 | jsr rs232_put 122 | lda #CR 123 | jsr rs232_put 124 | jsr clrchn 125 | jsr uplmen ; disk setup 126 | ldx SHFLAG 127 | cpx #SHFLAG_CBM 128 | beq mulab2 129 | lda inpbuf 130 | bne mulab2 131 | inc mulfln 132 | lda mulfln 133 | cmp mulcnt 134 | beq mlss5 135 | ldx #0 136 | stx JIFFIES 137 | mlstim lda JIFFIES 138 | cmp #110 139 | bcc mlstim 140 | jmp mlsinc 141 | mlss5 142 | jsr mlshdr 143 | ldx #16 144 | lda #4 ; ctrl-d 145 | : jsr rs232_put 146 | dex 147 | bne :- 148 | lda #CR 149 | jsr rs232_put 150 | mlssab jsr clrchn 151 | jsr text_color_restore 152 | jsr gong 153 | jmp term_entry 154 | 155 | ;---------------------------------------------------------------------- 156 | ; send 16 TABs 157 | mlshdr: 158 | jsr rs232_clear 159 | jsr rs232_on 160 | ldx #16 161 | lda #9 ; ctrl-i 162 | : jsr rs232_put 163 | dex 164 | bne :- 165 | rts 166 | 167 | ;---------------------------------------------------------------------- 168 | mulabt: 169 | jsr gong 170 | mulab2 171 | jsr clrchn 172 | lda #CR 173 | jsr chrout 174 | lda #LFN_FILE 175 | jsr close 176 | lda modem_type 177 | cmp #MODEM_TYPE_SWIFTLINK_DE 178 | bmi mulab3 179 | mulab3 180 | jsr rs232_on 181 | jmp term_entry 182 | 183 | ;---------------------------------------------------------------------- 184 | cf3_multi_receive: 185 | jsr col80_pause 186 | jsr rs232_off 187 | jsr text_color_save 188 | lda protoc 189 | beq mulrav ; PROTOCOL_PUNTER 190 | jmp mulnop 191 | mulrav 192 | jsr supercpu_off 193 | lda #1 194 | sta mulcnt 195 | lda #CLR 196 | jsr chrout 197 | lda #txt_multirecv 199 | jsr outstr 200 | mrllgc 201 | ldx SHFLAG 202 | bne mrllgc 203 | mlrnew 204 | jsr rs232_on 205 | ldy #0 206 | sty max 207 | mlrwat 208 | ldx SHFLAG 209 | cpx #SHFLAG_CBM 210 | beq mulab2 211 | jsr rs232_get 212 | cmp #9 ; ctrl-i 213 | bne mlrwat 214 | mlrwt2 215 | ldx SHFLAG 216 | cpx #SHFLAG_CBM 217 | beq mulab2 218 | jsr rs232_get 219 | cmp #0 220 | beq mlrwt2 221 | cmp #9 ; ctrl-i 222 | beq mlrwt2 223 | bne mlrfl1 224 | mlrflp 225 | ldx SHFLAG 226 | cpx #SHFLAG_CBM 227 | beq mulab2 228 | jsr rs232_get 229 | cmp #0 230 | beq mlrflp 231 | mlrfl1 232 | cmp #CR 233 | beq mlrfl2 234 | ldy max 235 | sta inpbuf,y 236 | inc max 237 | lda max 238 | cmp #18 239 | bcc mlrflp 240 | mlrfl2 241 | ldy max 242 | cpy #3 243 | bcc mlfext 244 | dey 245 | dey 246 | lda inpbuf,y 247 | cmp #',' 248 | bne mlfext 249 | sty max 250 | lda inpbuf 251 | cmp #4 ; ctrl-d 252 | bne mlffl2 253 | mlfext jmp mulabt 254 | mlffl2 255 | jsr dowmen 256 | lda inpbuf 257 | beq mlrnew 258 | bne mlfext 259 | 260 | ;---------------------------------------------------------------------- 261 | ; count bad blocks 262 | goobad: 263 | sta $0400+20*40+20 264 | cmp #'/' ; duplicate block? 265 | beq @1 ; ignore in statistics 266 | cmp #'*' ; good? 267 | bne @2 ; no 268 | @1: rts 269 | @2: cmp #'9'+1 270 | beq @3 271 | ldx #3 272 | bne @4 273 | @3: ldx #25 274 | @4: inc $0400+20*40+38-25,x 275 | lda $0400+20*40+38-25,x 276 | cmp #'9'+1 277 | bcc @1 278 | lda #'0' 279 | sta $0400+20*40+38-25,x 280 | dex 281 | bpl @4 282 | rts 283 | 284 | ;---------------------------------------------------------------------- 285 | SET_PETSCII 286 | txt_multisend_select: 287 | .byte CR,LOCASE,WHITE,RVSON," Multi-Send ",RVSOFF," - " 288 | .byte "Select files:",CR,CR,0 289 | 290 | txt_yesnoquit: 291 | .byte LTBLUE," Yes/No/Quit/Skip8/Done/All",CR,0 292 | 293 | txt_multirecv: 294 | .byte CR,LOCASE,WHITE,RVSON," Multi-Receive ",CR,CR 295 | .byte CYAN,"Waiting for header...C= aborts.",CR,0 296 | SET_ASCII 297 | 298 | ;---------------------------------------------------------------------- 299 | select_files_from_disk: 300 | jsr rs232_off 301 | lda device_disk 302 | jsr listen 303 | lda #$f0 304 | jsr second 305 | lda #'$' 306 | jsr ciout 307 | lda #'0' 308 | jsr ciout 309 | lda #':' 310 | jsr ciout 311 | lda #'*' 312 | jsr ciout 313 | jsr unlsn 314 | lda #mulfil 317 | sta tmpfd+1 318 | lda device_disk 319 | jsr talk 320 | lda #$60 321 | jsr tksa 322 | ldy #0 323 | sty mulcnt ; count entries 324 | sty mulfln 325 | sty mlsall 326 | sty mulskp 327 | ldy #31 328 | mdrlp0 329 | jsr mgetch 330 | dey 331 | bpl mdrlp0 332 | ldy #1 333 | mdrlp1 jsr mgetch 334 | dey 335 | bpl mdrlp1 336 | ldy #0 337 | jsr mgetch 338 | sta (tmpfd),y 339 | sta tmp07e8,y 340 | iny 341 | jsr mgetch 342 | sta (tmpfd),y 343 | sta tmp07e8,y 344 | lda #0 345 | sta tmp06 346 | mdrlp2 jsr mgetch 347 | inc tmp06 348 | cmp #'"' 349 | bne mdrlp2 350 | mdrlpf 351 | iny 352 | cpy #18 353 | beq drlpfn 354 | jsr mgetch 355 | cmp #'"' 356 | bne drlpnq 357 | lda #$a0 358 | drlpnq 359 | sta (tmpfd),y 360 | sta tmp07e8,y 361 | jmp mdrlpf 362 | drlpfn 363 | dey 364 | cpy #1 365 | beq drlptc 366 | lda tmp07e8,y 367 | cmp #' ' 368 | bne drlptc 369 | lda #$a0 370 | sta (tmpfd),y 371 | sta tmp07e8,y 372 | bne drlpfn 373 | drlptc 374 | jsr mgetch 375 | lda #0 376 | sta tmp05 377 | jsr mgetch 378 | cmp #'*' 379 | bne drlpsp 380 | lda #$80 381 | sta tmp05 382 | drlpsp 383 | jsr mgetch 384 | ldx #4 385 | drlptl 386 | cmp drtype,x 387 | beq drlptp 388 | dex 389 | bne drlptl 390 | drlptp 391 | txa 392 | ora tmp05 393 | sta tmp05 394 | jsr mgetch 395 | jsr mgetch 396 | jsr mgetch 397 | cmp #'<' 398 | bne drlpte 399 | lda tmp05 400 | ora #$40 401 | sta tmp05 402 | drlpte lda tmp05 403 | ldy #18 404 | sta (tmpfd),y 405 | sta tmp07e8,y 406 | lda #0 407 | iny 408 | sta (tmpfd),y 409 | dirgrb 410 | jsr mgetch 411 | bne dirgrb 412 | inc mulcnt 413 | lda mulskp 414 | bne mulpmt 415 | jsr mdrret 416 | bne mulnen 417 | mulpmt dec mulskp 418 | jsr drpol7 419 | mulnen 420 | lda device_disk 421 | jsr talk 422 | lda #$60 423 | jsr tksa 424 | ldy #1 425 | jmp mdrlp1 426 | mgetch jsr acptr 427 | ldx status 428 | bne mdrlp3 429 | cmp #0 430 | rts 431 | mdrlp3 pla 432 | pla 433 | mdrext lda device_disk 434 | jsr listen 435 | lda #$e0 436 | jsr second 437 | jsr untlk 438 | jsr unlsn 439 | jsr clrchn 440 | jsr ercopn ; possible fix for multi upload crash on up9600 - 2018 fix 441 | jmp rs232_on 442 | 443 | ;---------------------------------------------------------------------- 444 | mdrret: 445 | ldy #0 446 | drpol0 447 | sty tmp02 448 | lda directory_format,y 449 | cmp #2 ; ctrl-b 450 | bne @no1 451 | 452 | ; print blocks 453 | ldy #0 454 | lda tmp07e8,y 455 | tax 456 | iny 457 | lda tmp07e8,y 458 | jsr $bdcd ; print 16 bit decimal 459 | ldy tmp06 460 | : lda #' ' 461 | jsr chrout 462 | dey 463 | bne :- 464 | beq drpol4 465 | @no1: 466 | 467 | cmp #$0e ; ctrl-n 468 | bne @no2 469 | 470 | ; print file name 471 | ldy #2 472 | : lda tmp07e8,y 473 | jsr chrout 474 | iny 475 | cpy #18 ; print 16 chars 476 | bne :- 477 | beq drpol4 478 | @no2: 479 | 480 | cmp #$06 ; ctrl-f 481 | bne @no3 482 | 483 | ; print file type 484 | ldy #18 485 | lda tmp07e8,y 486 | tay 487 | and #7 488 | tax 489 | tya 490 | and #$80 491 | bne @1 492 | lda #' ' 493 | bne @2 494 | @1: lda #'*' ; splat 495 | @2: jsr chrout 496 | lda drtype,x ; file type 497 | jsr chrout 498 | lda drtyp2,x 499 | jsr chrout 500 | lda drtyp3,x 501 | jsr chrout 502 | tya 503 | and #$40 504 | bne @3 505 | lda #' ' 506 | bne @4 507 | @3: lda #'<' ; write protect 508 | @4: jsr chrout 509 | bne drpol4 510 | @no3: 511 | 512 | jsr chrout 513 | drpol4 514 | ldy tmp02 515 | iny 516 | cpy #directory_format_end-directory_format 517 | beq :+ 518 | jmp drpol0 ; [XXX drpol0 is reachable] 519 | : 520 | lda mlsall 521 | beq mlsf0 522 | lda #'Y' 523 | jsr chrout 524 | bne mlsyes 525 | 526 | mlsf0 527 | lda #' ' 528 | jsr chrout 529 | lda #CSR_LEFT 530 | jsr chrout 531 | jsr cursor_show 532 | : jsr getin 533 | beq :- 534 | and #$7f 535 | cmp #'A' 536 | bcc :- 537 | cmp #'[' 538 | bcs :- 539 | pha 540 | jsr cursor_off 541 | pla 542 | pha 543 | jsr chrout 544 | lda #CSR_LEFT 545 | jsr chrout 546 | pla 547 | 548 | cmp #'Y' ; YES 549 | bne mlsf1 550 | 551 | ; yes 552 | mlsyes ldy #19 553 | inc mulfln 554 | lda #$80 555 | sta (tmpfd),y 556 | bne mlsnpr2 557 | mlsf1 558 | 559 | cmp #'N' ; NO 560 | beq mlsnpr 561 | 562 | cmp #'A' ; ALL 563 | bne mlsf2 564 | 565 | ; all 566 | lda #1 567 | sta mlsall 568 | bne mlsyes 569 | mlsf2 570 | 571 | cmp #'D' ; DONE 572 | bne mlsf3 573 | 574 | ; done 575 | lda #CR 576 | jsr chrout 577 | jmp mdrlp3 578 | mlsf3 579 | 580 | cmp #'Q' ; QUIT 581 | bne mlsf4 582 | 583 | ; quit 584 | jsr mdrext 585 | pla 586 | pla 587 | pla 588 | pla 589 | jsr clrchn 590 | jmp term_entry 591 | mlsf4 592 | 593 | cmp #'S' ; SKIP8 594 | bne mlsf0 595 | 596 | ; skip8 597 | lda #7 598 | sta mulskp 599 | mlsnpr lda #CR 600 | jsr chrout 601 | drpol7 602 | lda tmpfd 603 | clc 604 | adc #0 ; [XXX ???] 605 | sta tmpfd 606 | lda tmpfd+1 607 | adc #0 608 | sta tmpfd+1 609 | rts 610 | mlsnpr2 lda #CR 611 | jsr chrout 612 | drpol72 613 | lda tmpfd 614 | clc 615 | adc #20 616 | sta tmpfd 617 | lda tmpfd+1 618 | adc #0 619 | sta tmpfd+1 620 | rts 621 | -------------------------------------------------------------------------------- /src/buffer.s: -------------------------------------------------------------------------------- 1 | ; CCGMS Terminal 2 | ; 3 | ; Copyright (c) 2016,2020, Craig Smith, alwyz. All rights reserved. 4 | ; This project is licensed under the BSD 3-Clause License. 5 | ; 6 | ; Buffer manipulation functions 7 | ; 8 | 9 | ;---------------------------------------------------------------------- 10 | SET_PETSCII 11 | txt_buffer: 12 | .byte WHITE,"Buffer ",0 13 | 14 | txt_bufcmds: 15 | .byte " bytes free. " 16 | .byte CR,HILITE 17 | .byte "open " 18 | .byte HILITE 19 | .byte "close " 20 | .byte HILITE 21 | .byte "erase " 22 | .byte HILITE 23 | .byte "transfer" 24 | .byte CR,HILITE 25 | .byte "load " 26 | .byte HILITE 27 | .byte "save " 28 | .byte HILITE 29 | .byte "print " 30 | .byte HILITE 31 | .byte "view: " 32 | .byte 0 33 | 34 | txt_open: 35 | .byte "Open",0 36 | 37 | txt_closed: 38 | .byte "Closed",0 39 | 40 | txt_erase_buffer: 41 | .byte "Erase Buffer! - " 42 | .byte HILITE 43 | .byte "yes or " 44 | .byte HILITE 45 | .byte "no? " 46 | .byte CSR_LEFT,CSR_LEFT,CSR_LEFT,15 47 | .byte CSR_LEFT,CSR_LEFT,CSR_LEFT,0 48 | 49 | txt_sending_buffer: 50 | .byte CR,CR 51 | .byte "Sending buffer..." 52 | .byte CR,CR,00 53 | 54 | txt_done: 55 | .byte CR,CR,WHITE 56 | .byte "Done." 57 | .byte CR,0 58 | 59 | txt_reu: 60 | .byte WHITE,"REU ",0 61 | SET_ASCII 62 | 63 | ;---------------------------------------------------------------------- 64 | print_buffer_info: 65 | lda reu_enabled 66 | beq :+ 67 | lda #txt_reu 69 | jsr outstr 70 | : lda #txt_buffer 72 | jsr outstr 73 | lda buffer_open 74 | beq @1 75 | lda #txt_open 77 | clc 78 | bcc @2 79 | @1: lda #txt_closed 81 | @2: jmp outstr 82 | 83 | ;---------------------------------------------------------------------- 84 | print_buffer_menu: 85 | lda #CR 86 | jsr chrout 87 | jsr print_buffer_info 88 | lda #' ' 89 | jsr chrout 90 | lda #'-' 91 | jsr chrout 92 | lda #' ' 93 | jsr chrout 94 | lda bufend 95 | sec 96 | sbc buffer_ptr 97 | tax 98 | lda bufend+1 99 | sbc buffer_ptr+1 100 | jsr outnum ; # of bytes free 101 | lda #txt_bufcmds 103 | jmp outstr 104 | 105 | ;---------------------------------------------------------------------- 106 | handle_f4_buffer: 107 | ldx SHFLAG 108 | cpx #SHFLAG_CBM 109 | jeq cf3_multi_receive 110 | 111 | jsr col80_pause 112 | jsr text_color_save 113 | bufask 114 | lda #CR 115 | jsr chrout 116 | jsr print_buffer_menu 117 | bufwat 118 | jsr invert_csr_char 119 | : jsr getin 120 | beq :- 121 | and #$7f 122 | pha 123 | jsr restore_csr_char 124 | pla 125 | cmp #CR 126 | bne bufcmd 127 | 128 | return_to_term: 129 | lda #' ' 130 | jsr chrout 131 | lda #CR 132 | jsr chrout 133 | jsr chrout 134 | jsr text_color_restore 135 | jsr rs232_on 136 | jmp term_mainloop 137 | 138 | bufcmd: 139 | ; O: open 140 | cmp #'O' 141 | bne @no1 142 | ldx #1 143 | stx buffer_open 144 | bne bufex1 145 | @no1: 146 | 147 | ; C: close 148 | cmp #'C' 149 | bne no2 150 | ldx #0 151 | stx buffer_open 152 | bufex1 153 | ora #$80 154 | bufexa 155 | jsr outcap 156 | lda #CR 157 | jsr chrout 158 | lda #CSR_UP 159 | ldx #4 160 | : jsr chrout 161 | dex 162 | bpl :- 163 | jmp bufask 164 | no2 165 | 166 | ; E: erase 167 | cmp #'E' 168 | bne @no3 169 | ora #$80 170 | jsr outcap 171 | lda #CR 172 | jsr chrout 173 | lda #CSR_UP 174 | ldx #2 175 | : jsr chrout 176 | dex 177 | bpl :- 178 | lda #txt_erase_buffer 180 | jsr outstr 181 | jsr invert_csr_char 182 | : jsr getin 183 | beq :- 184 | and #$7f 185 | cmp #'N' 186 | beq :+ 187 | cmp #'Y' 188 | bne :- 189 | jsr bufclr 190 | : jsr restore_csr_char 191 | lda #CSR_UP 192 | jsr chrout 193 | jsr chrout 194 | jmp bufask 195 | @no3 196 | 197 | ; P: print 198 | cmp #'P' 199 | bne @no4 200 | ora #$80 201 | jsr outcap 202 | jmp print_buffer 203 | @no4 204 | 205 | ; V: view 206 | cmp #'V' 207 | bne no5 208 | jsr col80_resume 209 | lda #CLR 210 | jsr chrout 211 | lda #$80 212 | sta bufflg 213 | and #0 ; [XXX lda #0] 214 | sta buffl2 215 | jsr prtbuf 216 | jmp term_mainloop 217 | 218 | ;---------------------------------------------------------------------- 219 | ; buf to screen 220 | prtbuf: 221 | lda buffst 222 | pha 223 | lda buffst+1 224 | pha 225 | lda #$2f 226 | sta $00 227 | lda #$36 ; disable BASIC ROM 228 | sta $01 229 | jsr dskout 230 | lda #$37 ; enable BASIC ROM 231 | sta $01 232 | pla 233 | sta buffst+1 234 | pla 235 | sta buffst 236 | rts 237 | 238 | ;---------------------------------------------------------------------- 239 | buffer_get_byte: 240 | ldx buffst 241 | cpx buffer_ptr 242 | bcc memok 243 | ldx buffst+1 244 | cpx buffer_ptr+1 245 | bcc memok 246 | memgab ldx #$40 ; EOI 247 | stx status 248 | rts 249 | 250 | memok ldy reu_enabled 251 | beq memok2 252 | jsr reuread 253 | jmp memok3 254 | memok2 255 | ldy #0 256 | lda (buffst),y 257 | memok3 258 | inc buffst 259 | bne memext 260 | inc buffst+1 261 | memext 262 | ldx #0 263 | stx status 264 | rts 265 | 266 | ;---------------------------------------------------------------------- 267 | buffer_skip_256: 268 | lda buffst+1 269 | cmp buffer_ptr+1 270 | bcs memgab ; EOI 271 | inc buffst+1 272 | skpbf2 273 | lda buffst+1 274 | cmp buffer_ptr+1 275 | bcc memext ; OK 276 | lda buffst 277 | cmp buffer_ptr 278 | bcs memgab ; EOI 279 | bcc memext ; OK 280 | no5 281 | 282 | ; S: save 283 | cmp #'S' 284 | jne no6 285 | jsr solfil 286 | jmp savbuf 287 | solfil 288 | ora #$80 289 | jsr outcap 290 | lda #CR 291 | jsr chrout 292 | jsr chrout 293 | jsr ui_get_filename 294 | bne solfok 295 | jmp ui_abort 296 | solfok rts 297 | savbuf 298 | jsr rs232_off ;to be save 5-13 fix?? worked without it, but this should be here 299 | lda #0 300 | sta mulcnt 301 | lda #2 302 | sta filetype 303 | jsr dowsfn 304 | lda #$36 305 | sta $01 306 | lda buffst;start of buffer 307 | sta $c1;I/O Start Address ($c1 $c2) 308 | lda buffst+1 309 | sta $c2 310 | lda buffer_ptr;end of buffer 311 | clc 312 | adc #1 313 | sta $ae;Tape End Addresses/End of Program ($ae / $af) 314 | lda buffer_ptr+1 315 | adc #0 316 | sta $af 317 | lda #$61 318 | sta $b9 319 | jsr $f3d5;open file on serial bus 320 | jsr $f68f;print saving and filename 321 | lda $ba 322 | jsr $ed0c;send listen to serial bus 323 | lda $b9 324 | jsr $edb9;LSTNSA. Send LISTEN secondary address to serial bus 325 | ldy #0 326 | jsr $fb8e;Move the Tape SAVE/LOAD Address into the Pointer at 172 ($ac) 327 | lda reu_enabled 328 | beq afuckit 329 | jsr af624 330 | lda #0 331 | sta buffst 332 | sta buffst+1 333 | jmp :+ 334 | afuckit jsr $f624 335 | : php 336 | lda #$37 337 | sta $01 338 | plp 339 | bcc bsaved 340 | lda #CR 341 | jsr chrout 342 | jsr bell 343 | lda #0 344 | sta buffst 345 | sta buffst+1 346 | jmp ui_abort 347 | 348 | ;---------------------------------------------------------------------- 349 | ;reu needs a special save routine cause craig decided to be all fancy with this one :) 350 | af624 jsr $fcd1 ; check the tape read/write pointer 351 | bcs @end 352 | ; lda ($ac),y 353 | jsr reuread 354 | jsr $eddd ; send a byte to an i/o device over the serial bus 355 | jsr $ffe1 ; stop. query stop key indicator, at memory address $0091; if pressed, call clrchn and clear keyboard buffer. 356 | bne :+ 357 | jsr $f642 358 | lda #0 359 | sec 360 | rts 361 | : inc buffst 362 | lda buffst 363 | beq :+ 364 | jsr $fcdb 365 | bne af624 366 | : inc buffst+1 367 | jsr $fcdb;advance tape pointer 368 | bne af624 369 | @end: jsr $edfe;UNLSTN. 370 | jmp $f642 371 | ;---------------------------------------------------------------------- 372 | 373 | bsaved 374 | jsr rs232_on 375 | jmp return_to_term 376 | no6 377 | 378 | ; L: load 379 | cmp #'L' 380 | bne bufcm7 381 | jsr solfil 382 | lodbuf 383 | jsr rs232_off ;5-13 put in, didnt seem to need it, need to test with it. might crash with it cause the program does that sometimes.... 384 | lda #2 385 | ldx device_disk 386 | tay 387 | jsr setlfs 388 | lda max 389 | ldx #inpbuf 391 | jsr setnam 392 | jsr open 393 | ldx #LFN_FILE 394 | jsr chkin 395 | lodbfl 396 | jsr getin 397 | ldx status 398 | bne lodbex 399 | ldx buffer_ptr 400 | cpx bufend 401 | bne lodbok 402 | ldx buffer_ptr+1 403 | cpx bufend+1 404 | beq lodbex 405 | lodbok 406 | ldy reu_enabled 407 | beq lodbokram 408 | jsr reuwrite 409 | jmp lodbokreu 410 | lodbokram 411 | ldy #0 412 | sta (buffer_ptr),y 413 | lodbokreu 414 | inc buffer_ptr 415 | bne lodbfl 416 | inc buffer_ptr+1 417 | bne lodbfl 418 | lodbex 419 | jsr clrchn 420 | lda #2 421 | jsr close 422 | jsr rs232_on 423 | jmp return_to_term 424 | bufcm7 425 | 426 | ; T: transfer 427 | cmp #'T' 428 | beq send_buffer 429 | 430 | ; 431 | cmp #'<' 432 | beq :+ 433 | cmp #'>' 434 | bne bufbak 435 | : jsr switch_buffer 436 | jmp bufexa 437 | 438 | bufbak 439 | jmp bufwat 440 | 441 | 442 | send_buffer: 443 | ora #$80 444 | jsr outcap 445 | jsr col80_resume 446 | lda #txt_sending_buffer 448 | jsr outstr 449 | lda #$ff 450 | sta bufflg 451 | sta buffl2 452 | jsr prtbuf 453 | jsr text_color_save 454 | jsr rs232_clear 455 | lda #txt_done 457 | jsr outstr 458 | jsr text_color_restore 459 | jsr rs232_on 460 | jmp term_mainloop 461 | 462 | ;---------------------------------------------------------------------- 463 | switch_buffer: 464 | pha 465 | cmp #'>' 466 | beq @3 467 | lda buffer_ptr+1 468 | cmp #>endprg 469 | bne @1 470 | lda buffer_ptr 471 | cmp #txt_device 508 | ldx #1 509 | jsr inpset 510 | lda #'4' 511 | jsr chrout 512 | jsr inputl 513 | bne @2 514 | @1: lda #CR 515 | jsr chrout 516 | jmp ui_abort 517 | 518 | @2: lda inpbuf 519 | cmp #'3' 520 | bcc @1 521 | cmp #'6' 522 | bcs @1 523 | and #$0f 524 | pha 525 | lda #txt_sec_addr 527 | ldx #1 528 | jsr inpset 529 | lda #'7' 530 | jsr chrout 531 | jsr inputl 532 | beq @1 533 | lda inpbuf 534 | cmp #'0' 535 | bcc @1 536 | cmp #'9'+1 537 | bcs @1 538 | and #$0f 539 | tay 540 | pla 541 | tax 542 | lda #LFN_PRINTER 543 | jsr setlfs 544 | lda #0 545 | jsr setnam 546 | lda #txt_printing 548 | jsr outstr 549 | jsr open 550 | ldx status 551 | bne @3 552 | lda buffst 553 | pha 554 | lda buffst+1 555 | pha 556 | lda #$2f 557 | sta $00 558 | lda #$36 ; disable BASIC ROM 559 | sta $01 560 | jsr print_buffer_bytes 561 | lda #$37 ; enable BASIC ROM 562 | sta $01 563 | pla 564 | sta buffst+1 565 | pla 566 | sta buffst 567 | @3: lda #LFN_PRINTER 568 | jsr close 569 | lda #txt_done 571 | jsr outstr 572 | jsr text_color_restore 573 | jsr rs232_on 574 | jmp term_mainloop 575 | 576 | ;---------------------------------------------------------------------- 577 | print_buffer_bytes: 578 | jsr buffer_get_byte 579 | bne @3 580 | pha 581 | and #$7f 582 | cmp #CR 583 | beq @1 584 | cmp #' ' 585 | bcc @2 586 | @1: ldx #LFN_PRINTER 587 | jsr chkout 588 | pla 589 | jsr chrout 590 | ldx status 591 | bne @3 592 | jmp print_buffer_bytes 593 | @2: pla 594 | jmp print_buffer_bytes 595 | @3: jmp clrchn 596 | -------------------------------------------------------------------------------- /Documentation.md: -------------------------------------------------------------------------------- 1 | # CCGMS Future Documentation 2 | 3 | ## Terminal Mode 4 | 5 | | Shortcut | Description | 6 | |-------------------------|----------------------------------| 7 | | `F1` | [Upload file](#upload-file) | 8 | | `F2` | [Send/Read file](#sendread-file) | 9 | | `F3` | [Download file](#download-file) | 10 | | `F4` | [Buffer commands](#buffer-commands) | 11 | | `F5` | [Disk command](#disk-command) | 12 | | `F6` | [Directory](#directory) | 13 | | `F7` | [Settings/Dialer](#settingsdialer) | 14 | | `F8` | [Cycle terminal mode](#cycle-terminal-mode) | 15 | | `C=` `F1` | [Multi-Upload](#multi-upload)| 16 | | `C=` `F3` | [Multi-Download](#multi-download)| 17 | | `C=` `F5` | [Send directory](#send-directory)| 18 | | `C=` `F7` | [Screen to buffer](#screen-to-buffer)| 19 | | `CTRL` `F1`/`F3` | [Send Macro Text](#macros) | 20 | | `CTRL` `F5`/`F7` | [Send User ID/Password](#send-user-idpassword)| 21 | | `C=` `CTRL` [`1`-`4`] | [Take screen snapshot](#screen-snapshot)| 22 | | `SHFT` `CTRL` [`1`-`4`] | [Recall screen snapshot](#screen-snapshot)| 23 | | `C=` `STOP` | [Disconnect](#disconnect) | 24 | 25 | ## Upload File 26 | 27 | `F1` will upload a single file from current drive to the BBS. It will ask for the source filename. 28 | 29 | ## Send/Read File 30 | 31 | `F2` will ask whether you want to send (`S`) or read (`R`) a file. 32 | 33 | * "Send" reads a file from the current drive and sends it to the BBS, byte by byte, as if it has been typed in. This is meant for text-only data, and does not do any error detection/correction. 34 | * "Read" reads a file from the current drive and prints it to the screen. No data is sent to the BBS. 35 | 36 | ## Download File 37 | 38 | `F3` will download a single file from the BBS to the current drive. First, it will ask for the destination filename. If the [protocol](#protocol) is XMODEM, it will also ask what file type the new file should be: PRG, SEQ or USR. 39 | 40 | ## Buffer Commands 41 | 42 | `F4` will show the buffer menu with following options: 43 | 44 | Open Close Erase Transfer 45 | Load Save Print View 46 | 47 | * **Open**: Open the buffer. If the buffer is open, all text received from the BBS in terminal mode will be appended to the buffer. 48 | * **Close**: Close the buffer. This stops appending text to the buffer. 49 | * **Erase**: Erase the buffer. This clears the buffer. 50 | * **Load**: This loads an SEQ file from the current drive into the buffer. 51 | * **Save**: This saves the buffer into an SEQ file on the current drive. 52 | * **Print**: This sends the buffer to the printer. It will ask for the device number and the secondary address. By convention, secondary address 0 will pick the upper/graphics character set, and 7 will pick the upper/lower character set. 53 | * **View**: This prints the buffer contents to the screen. During printing, STOP cancels, and any other key pauses/unpauses. 54 | 55 | In addition, `<` and `>` will move the buffer pointer. 56 | 57 | The RETURN key will exit the buffer menu. 58 | 59 | ## Disk Command 60 | 61 | `F5` allows sending a command to the current drive, like `S:FOO,S` or `CD/FOO`/`CD:←` (sd2iec). 62 | 63 | * `#8`, `#9` etc. changes the current drive globally. 64 | * An empty command will print the drive status. 65 | 66 | ## Directory 67 | 68 | `F6` will show the directory of the current drive. STOP cancels, and any other key pauses/unpauses. 69 | 70 | ## Settings/Dialer 71 | 72 | `F7` will show the following menu: 73 | 74 | Auto-Dialer/Phonebook 75 | Baud Rate - 2400 76 | Duplex - Full 77 | Modem Type - User Port 300-2400 78 | Firmware - Standard 79 | Protocol - XMODEM 80 | Theme - Classic CCGMS v5.5 81 | Edit Macros 82 | Load/Save Phone Book and Config. 83 | View Instructions 84 | 85 | The first character of each option will invoke it. 86 | 87 | ### Auto-Dialer/Phonebook 88 | 89 | CCGMS can auto-dial phonebook entries. It will send the `ATDT` command and parse the status returned by the modem (e.g. `CONNECT` or `NO ANSWER`). After connecting to the BBS, the key combinations Ctrl+F5 and Ctrl+F7 will send the username and password of the current phonebook entry. 90 | 91 | The phonebook has 30 entries, consisting of 92 | 93 | * **name**: name in the phone book 94 | * **ip**: DNS name or IP address 95 | * **port**: IP port 96 | * **id**: username 97 | * **pw**: password 98 | 99 | Use the cursor keys to navigate the entries. SPACE or RETURN selects/deselects an entry, which allows any subset of the entries to be selected. 100 | 101 | #### Dial Unlisted # (`D`) 102 | 103 | This allows connecting to a BBS that is not listed in the phonebook. CCGMS will ask for the DNS name or IP and the port. 104 | 105 | #### Edit Current # (`E`) 106 | 107 | This allows editing the currently highlighted entry. 108 | 109 | #### Call Current # (`C`) 110 | 111 | This dials the currently highlighted entry. 112 | 113 | #### Dial Selected (`A`) 114 | 115 | This dials the currently selected entries, one by one, until one answers. 116 | 117 | #### Reverse Call (`R`) 118 | 119 | Invert the current selection of entries. 120 | 121 | #### Return To Menu (`X`) 122 | 123 | This will return to the settings menu. 124 | 125 | 126 | ### Baud Rate 127 | 128 | This will cycle through the legal baud rates for the current [modem type](#modem-type). 129 | 130 | | Driver | 300 | 1200 | 2400 | 4800 | 9600 | 19200 | 3400 | 131 | |--------------------|-----|------|------|------|------|-------|------| 132 | | User Port | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | 133 | | UP9600 | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | 134 | | SwiftLink/Turbo232 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | 135 | 136 | ### Duplex 137 | 138 | Switches between half and full duplex. 139 | 140 | ### Modem Type 141 | 142 | Cycles through the RS-232 drivers: 143 | 144 | * User Port: This uses is the original Commodore RS-232 specification for modems on the user port. This can be used with classic modems like the Commodore 1670 (Modem/1200), or when connecting any TTL RS-232 device to the user port's RX and TX pins. 145 | * The [UP9600](https://www.pagetable.com/?p=1656) driver requires an alternate wiring on the user port. It allows higher speeds, and is backwards compatible with the original user port wiring. UP9600 does not work with the C128. 146 | * SwiftLink/Turbo232: This requires cartridge with an external 6551 ACIA, like SwiftLink, Turbo232 or GLINK232T. The cart has to be configured to use NMI (not IRQ) and to be located at either $DE00 (setting `DE`), $DF00 (`DF`) or $D700 (`D7`). 147 | 148 | ### Firmware 149 | 150 | This configures the syntax used by the auto-dialer. The ZiModem firmware requires the address after `ATDT` in quotes, standard firmwares (WiModem, StrikeLink, ...) do not accept quotes. 151 | 152 | ### Protocol 153 | 154 | This configures the protocol to be used for file transmissions. It cycles between Punter and three variants of XMODEM. 155 | 156 | * Punter: This is the "NEW" Punter a.k.a. Punter C1 protocol, which is the standard on many BBSes with a Commodore background. 157 | * XMODEM: This is a family of protocols mostly used on PC BBSes. 158 | * XMODEM: 159 | * Upload: force 128B blocks, accept checksum or CRC 160 | * Download: force checksum, accept 128B or 1K blocks 161 | * XMODEM-CRC: 162 | * Upload: force 128B blocks, accept checksum or CRC 163 | * Download: force CRC, accept 128B or 1K blocks 164 | * XMODEM-1K: 165 | * Upload: force 1K blocks, accept checksum or CRC 166 | * Download: force CRC, accept 128B or 1K blocks 167 | 168 | ### Theme 169 | 170 | This cycles through several color themes in the menus. 171 | 172 | ### Edit Macros 173 | 174 | This allows editing the two macros that can be invoked with Ctrl+F1 and Ctrl+F3. 175 | 176 | ### Load/Save Phone Book and Configuration 177 | 178 | This allows loading or saving the configuration and the phonebook contents. The EasyFlash version saves it in the EasyFlash ROM, the regular version saves it to disk. The file on disk is compatible between CCGMS versions. 179 | 180 | ### View Instructions 181 | 182 | Prints some additional keyboard commands as well as the license of the software. 183 | 184 | ## Cycle Terminal Mode 185 | 186 | `F8` cycles between 80/40 columns mode and PETSCII/ASCII encoding. 187 | 188 | ### Columns 189 | 190 | * 40 columns mode uses the VIC-II hardware text mode and the built-in character set. 191 | * 80 columns mode uses a software library to emulate 80 characters in bitmap mode. A limitation of this mode is that every two adjacent characters have to share a foreground color. In PETSCII mode, the character set is equivalent to the C64 built-in one, and in 80 columns mode, the charset is changed to be identical to ASCII (\^_`{|}~) 192 | 193 | ### Encoding 194 | 195 | * PETSCII (a.k.a "C/G") mode uses the Commodore character encoding and supports all [PETSCII control characters](https://www.pagetable.com/c64ref/charset/). It adds the following control codes, which can be sent by the BBS (or typed in by the user if the BBS has remote echo): 196 | 197 | | Keyboard | Code | Description | 198 | |---------------------|------|--------------------------------------| 199 | | CTRL B | $02 | Change background color | 200 | | CTRL N | $0e | Set background to black | 201 | | CTRL G | $07 | Bell sound | 202 | | CTRL V | $17 | Gong sound | 203 | | CTRL J | $0a | Cursor on | 204 | | CTRL K | $0b | Cursor off | 205 | 206 | * ASCII mode uses the standard-ASCII character encoding and supports *some* ANSI control sequences. 207 | 208 | ## Multi-Upload 209 | 210 | `C=` `F1` uploads one or more file using the Multi-Punter procotol. It will print the directory of the current drive entry by entry and ask for one of the following: 211 | 212 | * **Yes**: Upload this file. 213 | * **No**: Do not upload this file. 214 | * **Quit**: Stop uploading. 215 | * **Skip8**: Do not upload the next 8 files. 216 | * **Done**: Stop uploading. 217 | * **All**: Upload all files from here on. 218 | 219 | Multi-Punter will also send the name and type of each file. 220 | 221 | ## Multi-Download 222 | 223 | `C=` `F3` downloads one or more files. For each file, the BBS will send the name, type and file contents, and CCGMS will write the data to the current drive. 224 | 225 | ## Send directory 226 | 227 | `C=` `F5` will read the current drive's directory listing and send it to the BBS. 228 | 229 | ## Screen to buffer 230 | 231 | `C=` `F7` will convert the contents of the screen to a (minimal) sequence of PETSCII characters and codes and store it in the buffer. 232 | 233 | If the `SHIFT` key is pressed in addition, the contents of the buffer will be cleared first. 234 | 235 | > Note that in 80 columns mode, every two adjacent characters share a foreground color, so having the BBS show PETSCII graphics in 80 columns mode and saving the screen contents is lossy. For this use case, open the buffer before having the graphics printed instead. 236 | 237 | ## Screen Snapshots 238 | 239 | * `C=` `CTRL` and the keys `1`-`4` will copy the current screen contents into one of the four buffers. 240 | * `SHFT` `CTRL` and `1`-`4` will swap the current screen with one of the four buffers. 241 | 242 | Note that this feature is disabled in 80 columns mode, and switching into 80 columns mode will clear all four buffers. 243 | 244 | ## Macros 245 | 246 | `CTRL` `F1` and `CTRL` `F3` will send the contents of one of the two macros. 247 | 248 | ## Send User ID/Password 249 | 250 | `CTRL` `F5` will send the username and `CTRL` `F7` the password of the current phonebook entry, as if it were typed in. 251 | 252 | ## Disconnect 253 | 254 | This will drop the DTR line, which signals the modem that it should disconnect. 255 | --------------------------------------------------------------------------------