aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorB. Watson <urchlay@slackware.uk>2026-03-25 03:08:11 -0400
committerB. Watson <urchlay@slackware.uk>2026-03-25 03:08:11 -0400
commitb74d292847b22cf282ff8ae7d1b51df34176ce4d (patch)
tree4717814a5390d1672840c2c417ebb4d9606480d8 /src
parent8f19c016edd9f258c1b39eb44647c685b245f2fc (diff)
downloadfujinet-chat-b74d292847b22cf282ff8ae7d1b51df34176ce4d.tar.gz
Banish cgetc(), and all its annoyances. Much more flexible and precise keyboard control, see keytab.[ch] and kgetc.[ch]
Diffstat (limited to 'src')
-rw-r--r--src/cgetc.s24
-rw-r--r--src/edbox.c198
-rw-r--r--src/edbox.h4
-rw-r--r--src/irc.c64
-rw-r--r--src/keyclick.c8
-rw-r--r--src/keyclick.h1
-rw-r--r--src/keytab.c274
-rw-r--r--src/keytab.h34
-rw-r--r--src/kgetc.h2
-rw-r--r--src/kgetc.s125
-rw-r--r--src/main.c10
11 files changed, 538 insertions, 206 deletions
diff --git a/src/cgetc.s b/src/cgetc.s
deleted file mode 100644
index dd9fe26..0000000
--- a/src/cgetc.s
+++ /dev/null
@@ -1,24 +0,0 @@
-;
-; Christian Groessler, November-2002
-;
-; get a char from the keyboard
-; char cgetc(void)
-;
-
-; Modified version for FujiNetChat.
- .include "atari.inc"
- .export _cgetc
-
-_cgetc:
-;;; jsr setcursor ; this is unneeded and causes a hole in screen 7
- lda #12
- sta ICAX1Z ; fix problems with direct call to KEYBDV
- jsr @1
- ldx #0
- rts
-
-@1: lda KEYBDV+5
- pha
- lda KEYBDV+4
- pha
- rts
diff --git a/src/edbox.c b/src/edbox.c
index 2eaaf78..4adba8d 100644
--- a/src/edbox.c
+++ b/src/edbox.c
@@ -4,10 +4,10 @@
#include "addrs.h"
#include "screen.h"
#include "edbox.h"
-#include "keyclick.h"
#include "complete.h"
+#include "keytab.h"
-/* TODO: tab completion */
+extern void __fastcall__ bell(void);
char *old_edbox[EDBOX_SIZE];
static u16 old_len;
@@ -61,8 +61,6 @@ void edbox_hide(void) {
etc). not sure if this is more or less annoying than just
refusing to accept more input until Return is pressed. */
void edbox_putc(char c) {
- extern void __fastcall__ bell(void);
-
if(!c)
return; /* no inserting nulls */
@@ -92,12 +90,6 @@ static void restore_old(void) {
edbox_pos = edbox_len = old_len;
}
-static void fake_keystroke(char c) {
- keyclick();
- OS.ch = 0xff;
- edbox_putc(c);
-}
-
static void del_char(void) {
if(!edbox_len) return;
memmove(edit_box + edbox_pos, edit_box + edbox_pos + 1, EDBOX_SIZE - edbox_pos - 1);
@@ -167,174 +159,108 @@ static void del_to_start(void) {
while(edbox_pos) backspace();
}
-static void normal_keystroke(void) {
- char c;
+void left(void) {
+ if(edbox_pos) edbox_pos--;
+}
- c = cgetc();
+void right(void) {
+ if(edbox_pos < edbox_len) edbox_pos++;
+}
- if(c != CH_TAB)
+void edbox_keystroke(char c) {
+ extern char start_latch;
+ extern void start_keystroke(char);
+
+ if(c == CH_ESC) {
+ start_latch = 1;
+ return;
+ }
+
+ if(c != XCH_TAB)
comp_complete_done();
+ if(c >= XCH_SCR1 && c <= XCH_SCR7) {
+ start_keystroke(c & 0x7f);
+ return;
+ } else if(c == XCH_ACTIVE) {
+ start_keystroke('a');
+ return;
+ }
+
+ edbox_show();
+ hide_cursor();
+
switch(c) {
case CH_EOL:
- // hide_cursor(); // already done by the caller
copy_to_old();
edbox_hide();
if(edbox_callback)
(*edbox_callback)();
edbox_clear();
break;
- case CH_CLR:
+ case XCH_TAB:
+ comp_complete();
+ break;
+ case XCH_UP:
+ up();
+ break;
+ case XCH_DOWN:
+ down();
+ break;
+ case XCH_LEFT:
+ left();
+ break;
+ case XCH_RIGHT:
+ right();
+ break;
+ case XCH_LWORD:
+ back_word();
+ break;
+ case XCH_RWORD:
+ forward_word();
+ break;
+ case XCH_CLS:
+ edbox_clear();
edbox_hide();
- /* fall thru */
+ return;
+ case CH_DELCHR:
+ case 0x18: /* ^X */
+ del_char();
+ break;
case CH_DELLINE:
edbox_clear();
break;
+ case XCH_INSCHR:
+ typeover = !typeover;
+ break;
case 0x15: /* ^U */
del_to_start();
break;
case 0x0b: /* ^K */
del_to_end();
break;
- case CH_DEL:
- case 0x18: /* ^X */
+ case XCH_BS:
if(!edbox_len)
edbox_hide();
else
backspace();
break;
- case 0x02: /* ^B */
- back_word();
- break;
- case 0x06: /* ^F */
- forward_word();
- break;
case 0x17: /* ^W */
del_word();
break;
- case CH_CURS_LEFT:
- if(edbox_pos) edbox_pos--;
- break;
- case CH_CURS_RIGHT:
- if(edbox_pos < edbox_len) edbox_pos++;
- break;
- case CH_CURS_UP:
- up();
- break;
- case CH_CURS_DOWN:
- down();
- break;
- case CH_DELCHR:
- del_char();
- break;
case 0x01: /* ^A */
edbox_pos = 0;
break;
case 0x05: /* ^E */
edbox_pos = edbox_len;
break;
- case CH_TAB:
- comp_complete();
- break;
- case 0xff: /* ctrl-insert */
- typeover = !typeover;
- break;
default:
edbox_putc(c);
break;
}
-}
-
-void edbox_keystroke(void) {
- extern char start_latch;
- extern void start_keystroke(void);
- char c;
-
- if(OS.ssflag) OS.ch = 0x9f;
- while(OS.ch == 0xff)
- ;
-
- /* filter out all ctrl-shift key combos except the ones
- we actually support */
- if(OS.ch == 0xce) {
- /* ctrl-shift-up, same as ^B = back 1 word */
- OS.ch = 0x95;
- } else if(OS.ch == 0xcf) {
- /* ctrl-shift-down, same as ^F = forward 1 word */
- OS.ch = 0xb8;
- } else if(OS.ch > 0xbf) {
- OS.ch = 0xff;
- return;
- }
-
- /* keys we want to ignore or act on without showing the edbox */
- switch(OS.ch) {
- case 0x1c: /* key: ESC */
- keyclick();
- start_latch = 1;
- return;
- case 0x9f: /* ctrl-1 (XXX: the OS traps this, we never see it!) */
- case 0x9e: /* ctrl-2 */
- case 0x9a: /* ctrl-3 (crash if cgetc() reads it!) */
- case 0x98: /* ctrl-4 */
- case 0x9d: /* ctrl-5 */
- case 0x9b: /* ctrl-6 */
- case 0xb3: /* ctrl-7 */
- OS.ch &= 0x7f;
- start_latch = 1;
- start_keystroke();
- return;
- case 0x6c: /* shift-tab */
- case 0xac: /* ctrl-tab */
- OS.ch = 0xff; /* ignore it! */
- return;
- break;
- }
- edbox_show();
-
- /* keys we want to act on, and show the edbox after */
- c = 0;
- switch(OS.ch) {
- case 0xa0: /* key: ctrl [ */
- c = 0x7b; /* ascii: { */
- break;
- case 0xa2: /* key: ctrl ] */
- c = 0x7d; /* ascii: } */
- break;
- break;
- case 0x5c: /* key: shift ESC */
- c = 0x60; /* ascii: ` */
- break;
- case 0x9c: /* key: ctrl ESC */
- c = 0x7e; /* ascii: ~ */
- break;
- case 0x3c: /* caps */
- case 0x7c: /* shift-caps */
- case 0xbc: /* ctrl-caps */
- OS.shflok ^= 0x40;
- keyclick();
- return;
- break;
- case 0x27: /* atari key */
- case 0x67: /* ...w/shift */
- case 0xa7: /* ...w/ctrl */
- c = 0x02; /* ^B = IRC bold formatting char */
- break;
- default:
- break;
- }
-
- hide_cursor();
-
- if(c) {
- fake_keystroke(c);
- } else {
- normal_keystroke();
- }
-
- if(edbox_visible) edbox_show();
show_cursor();
+ if(edbox_visible) edbox_show();
}
void edbox_addchr(char c) {
diff --git a/src/edbox.h b/src/edbox.h
index 14dad03..35ce406 100644
--- a/src/edbox.h
+++ b/src/edbox.h
@@ -19,9 +19,9 @@ void edbox_hide(void);
/* put one character into the edit box. */
void edbox_putc(char c);
-/* wait for a keystroke, insert its character into the edit box. if Return
+/* pass a keystroke, insert its character into the edit box. if Return
is pressed, edbox_callback gets called (if it's set!) */
-void edbox_keystroke(void);
+void edbox_keystroke(char c);
/* called when the user presses Return */
extern void (*edbox_callback)(void);
diff --git a/src/irc.c b/src/irc.c
index fb3b979..71026c0 100644
--- a/src/irc.c
+++ b/src/irc.c
@@ -7,7 +7,6 @@
#include "screen.h"
#include "edbox.h"
#include "numerics.h"
-#include "keyclick.h"
#include <atari.h>
#include <conio.h>
@@ -15,6 +14,8 @@
#include "config.h"
#include "indic8.h"
#include "complete.h"
+#include "keytab.h"
+#include "kgetc.h"
#ifndef VERSION
#define VERSION "?????"
@@ -811,12 +812,10 @@ void irc_register(void) {
}
static void scrollback() {
- OS.ch = 0xff;
scr_scrollback();
- while(OS.ch == 0xff)
+ while(!keypress())
irc_read();
- keyclick();
- OS.ch = 0xff;
+ kgetc();
scr_end_scrollback();
}
@@ -949,18 +948,14 @@ static void toggle_edbox_only(void) {
OS.sdlst = edbox_only_dlist;
}
-void start_keystroke(void) {
- char i, s;
+void start_keystroke(char c) {
+ char s;
- i = cgetc();
+ start_latch = 0;
+ if(c == CH_ESC) return;
- start_latch = OS.escflg = OS.invflg = 0;
- if(i == CH_ESC) {
- return;
- }
-
- if(i >= '1' && i <= '7') {
- s = i - '1';
+ if(c >= '1' && c <= '7') {
+ s = c - '1';
if(s != scr_current) {
if(scr_status[s] != SCR_UNUSED) {
scr_prev = scr_current;
@@ -970,8 +965,8 @@ void start_keystroke(void) {
return;
}
- switch(tolower(i)) {
- case CH_CURS_UP:
+ switch(tolower(c)) {
+ case XCH_UP:
case '-':
scrollback();
return;
@@ -982,20 +977,20 @@ void start_keystroke(void) {
scr_prev = SCR_PRIV;
scr_destroy(scr_current);
return;
- case CH_CURS_LEFT:
+ case XCH_LEFT:
case '+':
scr_prev = scr_current;
hunt_screen(-1);
return;
- case CH_CURS_RIGHT:
+ case XCH_RIGHT:
case '*':
scr_prev = scr_current;
hunt_screen(1);
return;
- case CH_TAB:
- i = scr_current;
+ case XCH_TAB:
+ c = scr_current;
scr_display(scr_prev);
- scr_prev = i;
+ scr_prev = c;
return;
case 'q':
if(scr_current == SCR_PRIV && *last_pm_nick) {
@@ -1043,16 +1038,29 @@ void start_keystroke(void) {
}
}
-static void keystroke(void) {
- if(OS.ch == 0xff) return;
+static void poll_keyboard(void) {
+ char c, s;
+
+ s = GTIA_READ.consol;
+
+ if(!keypress()) return;
+
+ c = kgetc();
+ if(!c) return;
+
+ if(s == 6) start_latch = 1;
+
+ /* maybe this shouldn't happen until user presses Enter in the edbox?
+ would let lurkers lurk and read scrollback... */
if(irc_away) {
txbuf_send_str("AWAY");
irc_away = 0;
}
- if(GTIA_READ.consol == 6 || start_latch) { /* start pressed */
- start_keystroke();
+
+ if(start_latch) { /* start pressed */
+ start_keystroke(c);
} else {
- edbox_keystroke();
+ edbox_keystroke(c);
OS.cdtmv3 = hz / 2;
}
}
@@ -1078,7 +1086,7 @@ void irc_loop(void) {
}
OS.cdtmv3 = 0;
do {
- keystroke();
+ poll_keyboard();
} while(OS.cdtmv3);
}
}
diff --git a/src/keyclick.c b/src/keyclick.c
deleted file mode 100644
index d1e7505..0000000
--- a/src/keyclick.c
+++ /dev/null
@@ -1,8 +0,0 @@
-#include <atari.h>
-#include <conio.h>
-
-/* sound the keyclick. obeys the NOCLIK flag on XL/XE. */
-void keyclick(void) {
- OS.ch = 0;
- cgetc();
-}
diff --git a/src/keyclick.h b/src/keyclick.h
deleted file mode 100644
index b73a212..0000000
--- a/src/keyclick.h
+++ /dev/null
@@ -1 +0,0 @@
-extern void keyclick(void);
diff --git a/src/keytab.c b/src/keytab.c
new file mode 100644
index 0000000..5fd8963
--- /dev/null
+++ b/src/keytab.c
@@ -0,0 +1,274 @@
+#include "keytab.h"
+
+/*
+This table is a modified version of the one from the XL OS ROM.
+Atari uses $80 to mean "unused". Here, I use 0 to mean unused.
+Also, Atari's table is only 192 bytes. This is 256 bytes because
+it includes ctrl-shift combos.
+*/
+
+char keytab[256] = {
+// no modifier
+ 0x6c, // 0 = l
+ 0x6a, // 1 = j
+ 0x3b, // 2 = ;
+ XCH_SCR1, // 3 = 1200XL F1
+ XCH_SCR2, // 4 = 1200XL F2
+ 0x6b, // 5 = k
+ 0x2b, // 6 = +
+ 0x2a, // 7 = *
+ 0x6f, // 8 = o
+ 0x00, // 9 = (unused)
+ 0x70, // 10 = p
+ 0x75, // 11 = u
+ 0x9b, // 12 = EOL
+ 0x69, // 13 = i
+ 0x2d, // 14 = -
+ 0x3d, // 15 = =
+ 0x76, // 16 = v
+ 0x00, // 17 = (unused)
+ 0x63, // 18 = c
+ XCH_SCR3, // 19 = 1200XL F3
+ XCH_SCR4, // 20 = 1200XL F4
+ 0x62, // 21 = b
+ 0x78, // 22 = x
+ 0x7a, // 23 = z
+ 0x34, // 24 = 4
+ 0x00, // 25 = (unused)
+ 0x33, // 26 = 3
+ 0x36, // 27 = 6
+ 0x1b, // 28 = esc
+ 0x35, // 29 = 5
+ 0x32, // 30 = 2
+ 0x31, // 31 = 1
+ 0x2c, // 32 = ,
+ 0x20, // 33 = space
+ 0x2e, // 34 = .
+ 0x6e, // 35 = n
+ 0x00, // 36 = (unused)
+ 0x6d, // 37 = m
+ 0x2f, // 38 = /
+ 0x02, // 39 = inverse (toggle bold)
+ 0x72, // 40 = r
+ 0x00, // 41 = (unused)
+ 0x65, // 42 = e
+ 0x79, // 43 = y
+ XCH_TAB, // 44 = tab
+ 0x74, // 45 = t
+ 0x77, // 46 = w
+ 0x71, // 47 = q
+ 0x39, // 48 = 9
+ 0x00, // 49 = (unused)
+ 0x30, // 50 = 0
+ 0x37, // 51 = 7
+ XCH_BS, // 52 = ~
+ 0x38, // 53 = 8
+ 0x3c, // 54 = <
+ 0x3e, // 55 = >
+ 0x66, // 56 = f
+ 0x68, // 57 = h
+ 0x64, // 58 = d
+ 0x00, // 59 = (unused)
+ XCH_CAPS, // 60 = caps toggle
+ 0x67, // 61 = g
+ 0x73, // 62 = s
+ 0x61, // 63 = a
+
+// shift
+ 0x4c, // 64 = L
+ 0x4a, // 65 = J
+ 0x3a, // 66 = :
+ XCH_SCR5, // 67 = 1200XL Shift-F1
+ XCH_SCR6, // 68 = 1200XL Shift-F2
+ 0x4b, // 69 = K
+ 0x5c, // 70 = "\"
+ 0x5e, // 71 = ^
+ 0x4f, // 72 = O
+ 0x00, // 73 = (unused)
+ 0x50, // 74 = P
+ 0x55, // 75 = U
+ 0x9b, // 76 = EOL
+ 0x49, // 77 = I
+ 0x5f, // 78 = _
+ 0x7c, // 79 = |
+ 0x56, // 80 = V
+ 0x00, // 81 = (unused)
+ 0x43, // 82 = C
+ XCH_SCR7, // 83 = 1200XL Shift-F3
+ XCH_ACTIVE, // 84 = 1200XL Shift-F4
+ 0x42, // 85 = B
+ 0x58, // 86 = X
+ 0x5a, // 87 = Z
+ 0x24, // 88 = $
+ 0x00, // 89 = (unused)
+ 0x23, // 90 = #
+ 0x26, // 91 = &
+ 0x60, // 92 = ` (atari shift-esc)
+ 0x25, // 93 = %
+ 0x22, // 94 = "
+ 0x21, // 95 = !
+ 0x5b, // 96 = [
+ 0x20, // 97 = space
+ 0x5d, // 98 = ]
+ 0x4e, // 99 = N
+ 0x00, // 100 = (unused)
+ 0x4d, // 101 = M
+ 0x3f, // 102 = ?
+ 0x00, // 103 = inverse
+ 0x52, // 104 = R
+ 0x00, // 105 = (unused)
+ 0x45, // 106 = E
+ 0x59, // 107 = Y
+ 0x00, // 108 = shift-tab
+ 0x54, // 109 = T
+ 0x57, // 110 = W
+ 0x51, // 111 = Q
+ 0x28, // 112 = (
+ 0x00, // 113 = (unused)
+ 0x29, // 114 = )
+ 0x27, // 115 = '
+ 0x9c, // 116 = del line
+ 0x40, // 117 = @
+ XCH_CLS, // 118 = }
+ 0x9d, // 119 = ins line
+ 0x46, // 120 = F
+ 0x48, // 121 = H
+ 0x44, // 122 = D
+ 0x00, // 123 = (unused)
+ XCH_CAPS, // 124 = caps lock
+ 0x47, // 125 = G
+ 0x53, // 126 = S
+ 0x41, // 127 = A
+
+// ctrl
+ 0x0c, // 128 = ^L
+ 0x00, // 129 = ^J
+ 0x00, // 130 = ^:, unused
+ 0x00, // 131 = (unused)
+ 0x00, // 132 = (unused)
+ 0x0b, // 133 = ^K
+ XCH_LEFT, // 134 = atari left arrow
+ XCH_RIGHT, // 135 = atari right arrow
+ 0x0f, // 136 = ^O
+ 0x00, // 137 = (unused)
+ 0x10, // 138 = ^P
+ 0x15, // 139 = ^U
+ 0x9b, // 140 = EOL
+ XCH_ITAL, // 141 = ^I: IRC italics format
+ XCH_UP, // 142 = atari up arrow
+ XCH_DOWN, // 143 = atari down arrow
+ 0x16, // 144 = ^V
+ 0x00, // 145 = (unused)
+ 0x03, // 146 = ^C
+ 0x00, // 147 = 1200XL ctrl-F3 (?)
+ 0x00, // 148 = (unused)
+ XCH_LWORD, // 149 = ^B
+ 0x18, // 150 = ^X
+ 0x1a, // 151 = ^Z
+ XCH_SCR4, // 152 = inverse 4 (switch to screen 4)
+ 0x00, // 153 = (unused)
+ XCH_SCR3, // 154 = inverse 3 (switch to screen 3)
+ XCH_SCR6, // 155 = inverse 6 (switch to screen 6)
+ 0x7e, // 156 = ~ (tilde, aka atari ctrl-esc)
+ XCH_SCR5, // 157 = inverse 5 (switch to screen 5)
+ XCH_SCR2, // 158 = inverse 2 (switch to screen 2)
+ XCH_SCR1, // 159 = inverse 1 (switch to screen 1)
+ 0x7b, // 160 = {
+ 0x20, // 161 = space
+ 0x7d, // 162 = }
+ 0x0e, // 163 = ^N
+ 0x00, // 164 = (unused)
+ 0x00, // 165 = ^M
+ 0x00, // 166 = (unused)
+ 0x00, // 167 = inverse
+ 0x12, // 168 = ^R
+ 0x00, // 169 = (unused)
+ 0x05, // 170 = ^E
+ 0x19, // 171 = ^Y
+ 0x00, // 172 = ctrl-tab
+ 0x14, // 173 = ^T
+ 0x17, // 174 = ^W
+ 0x11, // 175 = ^Q
+ 0x00, // 176 = inverse 9 (if we ever support 9 screens)
+ 0x00, // 177 unused? not XCH_SCR1?
+ 0x00, // 178 = inverse 0 (if we ever support 10 screens)
+ XCH_SCR7, // 179 = inverse 7 (switch to screen 7)
+ 0xfe, // 180 = del chr
+ 0x00, // 181 = inverse 8 (if we ever support 8 screens)
+ XCH_CLS, // 182 = }
+ 0xff, // 183 = ins chr
+ XCH_RWORD, // 184 = ^F
+ 0x08, // 185 = ^H
+ 0x04, // 186 = ^D
+ 0x00, // 187 = (unused)
+ 0x00, // 188 = ctrl-caps (unused)
+ 0x07, // 189 = ^G
+ 0x13, // 190 = ^S
+ 0x01, // 191 = ^A
+
+// ctrl+shift
+ 0x00, // 192
+ 0x00, // 193
+ 0x00, // 194
+ 0x00, // 195
+ 0x00, // 196
+ 0x00, // 197
+ 0x00, // 198
+ 0x00, // 199
+ 0x00, // 200
+ 0x00, // 201
+ 0x00, // 202
+ XCH_UNDER, // 203
+ 0x00, // 204
+ 0x00, // 205
+ XCH_LWORD, // 206, ctrl+shift+up
+ XCH_RWORD, // 207, ctrl+shift+down
+ 0x00, // 208
+ 0x00, // 209
+ 0x00, // 210
+ 0x00, // 211
+ 0x00, // 212
+ 0x00, // 213
+ 0x00, // 214
+ 0x00, // 215
+ 0x00, // 216
+ 0x00, // 217
+ 0x00, // 218
+ 0x00, // 219
+ 0x00, // 220
+ 0x00, // 221
+ 0x00, // 222
+ 0x00, // 223
+ 0x00, // 224
+ 0x00, // 225
+ 0x00, // 226
+ 0x00, // 227
+ 0x00, // 228
+ 0x00, // 229
+ 0x00, // 230
+ 0x00, // 231
+ 0x00, // 232
+ 0x00, // 233
+ 0x00, // 234
+ 0x00, // 235
+ 0x00, // 236
+ 0x00, // 237
+ 0x00, // 238
+ 0x00, // 239
+ 0x00, // 240
+ 0x00, // 241
+ 0x00, // 242
+ 0x00, // 243
+ 0x00, // 244
+ 0x00, // 245
+ 0x00, // 246
+ 0x00, // 247
+ 0x00, // 248
+ 0x00, // 249
+ 0x00, // 250
+ 0x00, // 251
+ 0x00, // 252
+ 0x00, // 253
+ 0x00, // 254
+ 0x00, // 255
+};
diff --git a/src/keytab.h b/src/keytab.h
new file mode 100644
index 0000000..04d3df9
--- /dev/null
+++ b/src/keytab.h
@@ -0,0 +1,34 @@
+
+#define XCH_SCR1 0xb1
+#define XCH_SCR2 0xb2
+#define XCH_SCR3 0xb3
+#define XCH_SCR4 0xb4
+#define XCH_SCR5 0xb5
+#define XCH_SCR6 0xb6
+#define XCH_SCR7 0xb7
+/* when/if we have more screens:
+#define XCH_SCR8 0xb8
+#define XCH_SCR9 0xb9
+#define XCH_SCR0 0xb0
+*/
+
+#define XCH_TAB 0x80
+#define XCH_UP 0x81
+#define XCH_DOWN 0x82
+#define XCH_LEFT 0x83
+#define XCH_RIGHT 0x84
+#define XCH_LWORD 0x85
+#define XCH_RWORD 0x86
+#define XCH_CLS 0x87
+#define XCH_BS 0x88
+#define XCH_ACTIVE 0x89
+#define XCH_CAPS 0x8a
+
+/* these are just control characters */
+#define XCH_ITAL 0x1d
+#define XCH_UNDER 0x1f
+
+/* cc65's atari.h should define this but doesn't */
+#define XCH_INSCHR 0xff
+
+extern char keytab[256];
diff --git a/src/kgetc.h b/src/kgetc.h
new file mode 100644
index 0000000..3f96810
--- /dev/null
+++ b/src/kgetc.h
@@ -0,0 +1,2 @@
+char __fastcall__ kgetc(void);
+char __fastcall__ keypress(void);
diff --git a/src/kgetc.s b/src/kgetc.s
new file mode 100644
index 0000000..c11cb6d
--- /dev/null
+++ b/src/kgetc.s
@@ -0,0 +1,125 @@
+; kgetc() is a replacement for cc65's cgetc(). It does *not* call the
+; OS's K: "get one byte" routine to decode keycodes into (AT)ASCII. It
+; *does* support all 255 keycodes, meaning ctrl+shift combos work.
+
+; kgetc() actually does call the OS K: handler to produce a keyclick, but
+; it does so with a fixed keycode (12, the Return key) and throws away
+; the result. This means we can turn off the keyclick even on an 800.
+; The OS NOCLIK location is used on the 800, too.
+
+; There is no blocking for another keystroke, if a key like Escape or
+; Inverse is pressed. The ctrl-1 keystroke is detected, even though
+; the OS "pre-empts" it (we never see $b1 in CH).
+
+; There is no inverse video mode! INVFLG is never set, and is ignored.
+; There is no Control-lock either, although Caps-lock exists.
+
+; Unlike cgetc(), kgetc() doesn't need to be able to return 0 as a valid
+; character. So instead, 0 is used to mean "ignore keystroke".
+
+; Since inverse numbers can't be returned, I've reused their ATASCII codes
+; for 'switch window' with ctrl-1 through 7.
+
+; kgetc() blocks if no key has been pressed when it's called. to do
+; non-blocking reads:
+; if(keypress())
+; c = kgetc();
+; /* c is 0 if either no key or a non-ATASCII keystroke was pressed,
+; e.g. caps lock or an unused ctrl-shift-letter. */
+
+ .include "atari.inc"
+ .export _kgetc, _keypress
+ .import _keytab
+
+ XCH_CAPS = $8a ; must agree with keytab.h
+
+_keypress:
+ ldx CH
+ cpx #$ff
+ bne ret1 ; if CH != $ff, a key is pressed...
+ ldx SSFLAG
+ bne ret1 ; if SSFLAG != 0, a key is pressed...
+ ldx HELPFG
+ bne ret1 ; if HELPFG != 0, a key (Help) is pressed...
+ txa ; return(0);
+ .byte $2c ; BIT ABS, skip LDA imm below
+ret1:
+ lda #1
+ rts
+
+_kgetc:
+ ldx HELPFG
+ beq read_ch ; Help key pressed?
+ lda #0
+ sta HELPFG ; yes, clear it
+ ldx #$54 ; 1200XL Shift-F4 keycode
+ bne decode
+
+read_ch:
+ ldx CH
+ cpx #$ff
+ bne decode
+ ldx SSFLAG
+ beq read_ch
+ lda #0
+ sta SSFLAG
+ ldx #$9f ; real Ctrl-1 keycode
+
+decode:
+ lda _keytab,x
+ beq done ; 0 in the table means ignore the keystroke (not even a click)
+
+ cmp #XCH_CAPS
+ bne gotkey
+
+ lda SHFLOK ; caps was pressed. we use SHFLOK different from how the OS does.
+ eor #$20
+ sta SHFLOK
+ lda #0
+ beq click_and_done
+
+gotkey: ; ATASCII code in A here, don't overwrite
+ cmp #'z'+1 ; only apply caps lock to a-z
+ bcs noshf
+ cmp #'a'
+ bcc noshf
+ sbc SHFLOK
+noshf:
+ ldx NOCLIK
+ bne done ; obey the XL OS's keyclick disable flag, even on an 800
+
+ ; sound the keyclick (let the OS do it)
+click_and_done:
+ pha
+ jsr keyclick
+ pla
+
+done:
+ ldx #$ff
+ stx CH
+ rts
+
+keyclick:
+ lda NOCLIK
+ bne return ; disabled
+ lda #0
+ sta SSFLAG
+ lda #12 ; EOL (could be any regular key but we need 12 below)
+ sta CH ; fall thru to cgetc...
+
+; ripped from the cc65 lib src, and modified.
+; original code by Christian Groessler, November-2002.
+;_cgetc:
+ ;lda #12 ; already in A
+ sta ICAX1Z ; fix problems with direct call to KEYBDV
+ jsr callit
+return:
+ ;ldx #0
+ rts
+
+callit:
+ lda KEYBDV+5
+ pha
+ lda KEYBDV+4
+ pha
+ rts
diff --git a/src/main.c b/src/main.c
index b5de37b..5535343 100644
--- a/src/main.c
+++ b/src/main.c
@@ -11,13 +11,12 @@
#include <stdio.h>
#include <string.h>
#include <ctype.h>
-#include <conio.h> // for cgetc() only
#include "nio.h"
#include "irc.h"
#include "screen.h"
#include "edbox.h"
#include "config.h"
-#include "keyclick.h"
+#include "kgetc.h"
#include "indic8.h"
unsigned char err; // error code of last operation.
@@ -156,13 +155,10 @@ void reconnect(void) {
}
scr_print_current(" to reconnect.\n");
- while(OS.cdtmf3 == 0xff && OS.ch == 0xff)
+ while(OS.cdtmf3 == 0xff && !keypress())
/* NOP */;
- if(OS.ch != 0xff) {
- keyclick();
- OS.ch = 0xff;
- }
+ if(keypress()) kgetc();
}
void main(void) {