Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Delete Key Handler for BASIC.SYSTEM

446 views
Skip to first unread message

Bill Chatfield

unread,
Oct 10, 2017, 12:48:00 AM10/10/17
to
It always frustrated me that the Delete key did not work right. I've written a handler to fix it. It's not perfect yet. It breaks the escape key handling and the arrow keys. I'm still working on it.

https://github.com/gungwald/delhndlr

It assembles with Merlin.

James Davis

unread,
Oct 10, 2017, 1:57:20 AM10/10/17
to
It is not really a DELETE key. It operates like a BACKSPACE key and occupies the same keyboard space as BACKSPACE keys do on more modern keyboards. An easier fix is to make a new label for it!

gid...@sasktel.net

unread,
Oct 10, 2017, 2:46:44 AM10/10/17
to
This simple little routine should work for both Prodos and Dos3.3 but won't work with 80-col cards in a II+.

* FOR PRODOS
LDA #<DELETE
STA $BE32
LDA #>DELETE
STA $BE33
RTS

* FOR DOS 3.3
LDA #<DELETE
STA $38
LDA #>DELETE
STA $39
JMP $3EA

DELETE BIT $C01F
BMI COL80
JSR FD0C
BNE DEL2

COL80 JSR $C305

DEL2 CMP #$FF
BNE RETURN
LDA #$88
JSR $FDED
LDA #$A0
JSR $FDED
LDA #$88
RETURN RTS

I am not totally sure of the Dos 3.3 method, it has been too long and my notes are not handy.

But I use this routine regularly under Prodos. You can also add a routine to make sure THIS routine is re-enabled on RESET.

James Davis

unread,
Oct 10, 2017, 2:47:42 AM10/10/17
to
P.S. It is annoying though! And, it would be nice if it operated like the DELETE key on modern PC systems. But, then you still need a BACKSPACE key that operates like the Apple II DELETE key does.

This is one of those things that would be easy to change in an emulator, to get rid of the annoyance and the backwardness of the Apple II keyboard, but hard to do on real hardware and firmware.

Mark D. Overholser

unread,
Oct 10, 2017, 12:58:14 PM10/10/17
to James Davis
Use the Open Apple or Closed Apple as a Modifier.. The Shift Key could
have been used, if it was Detectable...

For consistency with modern Keyboards, have it Default to the BackSpace
( Ctrl-H ), and when the Open Apple or Close Apple is held Down, have it
"shift" to Delete...


MarkO

Steve Nickolas

unread,
Oct 10, 2017, 12:59:19 PM10/10/17
to
And indeed most emulators I've used map BkSp to <-, putting Delete on Del
if it's actually needed.

-uso.

Mark D. Overholser

unread,
Oct 10, 2017, 12:59:49 PM10/10/17
to gid...@sasktel.net
On 09-Oct-17 23:46, gid...@sasktel.net wrote:
> On Monday, October 9, 2017 at 10:48:00 PM UTC-6, Bill Chatfield
> wrote:
>> It always frustrated me that the Delete key did not work right.
>> I've written a handler to fix it. It's not perfect yet. It breaks
>> the escape key handling and the arrow keys. I'm still working on
>> it.
>>
>> https://github.com/gungwald/delhndlr
>>
>> It assembles with Merlin.
>
> This simple little routine should work for both Prodos and Dos3.3 but
> won't work with 80-col cards in a II+.



Since the Apple ][ and Apple ][+ don't have the DELETE key, that would
be a Moot Point.....



MarkO

Bill Chatfield

unread,
Oct 11, 2017, 12:02:17 AM10/11/17
to
Not on real hardware. In BASIC.SYSTEM or in DOS 3.3 it doesn't operate like a Backspace. It just displays a weird character. Your emulator may be mapping it to a left arrow. But on real hardware it doesn't do that. That's why I wrote this, to make it work like a Backspace. It's in the keyboard position that a Backspace key should be in, so it needs to work like a Backspace.

gid...@sasktel.net

unread,
Oct 11, 2017, 12:02:24 AM10/11/17
to
On Tuesday, October 10, 2017 at 10:59:49 AM UTC-6, Mark D. Overholser wrote:
The routine can be mapped to any key or Ctrl-key, not just the Delete key. For the II or II+, just change the CMP #$FF to the key combination of your choice.

Bill Chatfield

unread,
Oct 11, 2017, 12:21:30 AM10/11/17
to
Well, if I wanted something simple, I wouldn't have written all that code. :-)

Seriously, this looks good. What does is the sub at $C305?

James Davis

unread,
Oct 11, 2017, 3:36:05 AM10/11/17
to
Yeah, I was testing it on my real Enhanced Apple IIe to understand what you were saying about the Delete key, but I was using it from within programs like AppleWorks and ProDOS to change Prefixes. In the Monitor and in BASIC it prints a checkerboard character. In programs' "line input routines" it acts like a Backspace key. That's why I said what I said (e.g., Re-Label it!).

In some programs I have used, you can make it work like a real Delete key by pressing a modifier key with it (e.g., Control, Open-Apple, or Solid-Apple, plus Delete). I suggest that you do something like that too. Then, Re-Label your Delete key: Delete/{Modifier Key Name}-Backspace! [I like Ctrl-Backspace; allows using your two little fingers.]

You could do something similar with the left and right arrow keys to make them function like Backspace (<--) and Delete (-->) keys, too (instead of as cursor movement or "type over" keys).

gid...@sasktel.net

unread,
Oct 11, 2017, 10:56:56 AM10/11/17
to
That is the input routine for the 80-col card, same as $FD0C is input for 40-col. $C307 is the output for 80-col same as $FDED is output for 40-col.

And the BIT $C01F indicates when 80-col mode is turned on.

gid...@sasktel.net

unread,
Oct 11, 2017, 11:02:45 AM10/11/17
to
Change that to $FDF0 being output and $FD1B being input for 40-col. $FD0C and $FDED point to the input and ouput vectors at $36.39.

gid...@sasktel.net

unread,
Oct 11, 2017, 11:15:12 AM10/11/17
to
Here is the corrected version with comments.
Note the change from $FD0C to $FD1B
This not only works for Prodos and Dos 3.3 but also works in both 40-col and 80-col mode

* FOR PRODOS
* setup Basic.system vectors for input
LDA #<DELETE
STA $BE32
LDA #>DELETE
STA $BE33
RTS

* FOR DOS 3.3
* setup Dos vectors to get a keypress
LDA #<DELETE
STA $38
LDA #>DELETE
STA $39
JMP $3EA

DELETE BIT $C01F ; are we in 80-col mode?
BMI COL80 ; branch if yes
JSR $FD1B ; changed from $FD0C
BNE DEL2

COL80 JSR $C305 ; for 80-col input

DEL2 CMP #$FF ; is the Delete key pressed; change to something else for the Apple II or II+
BNE RETURN ; if not then let DOS or Basic.sys handle the keypress
LDA #$88 ; go back one space; same action as the left arrow
JSR $FDED ; print it
LDA #$A0 ; print a space
JSR $FDED
LDA #$88 ; go back over the space
RETURN RTS ; let Dos or BS handle the last character

James Davis

unread,
Oct 11, 2017, 8:50:07 PM10/11/17
to
Would it not be better to use CSW and KSW rather than COUT and KEYIN?

Pertinent Definitions/Equates from my interpretation of the Apple II Monitors:

CSWL EQU $36 ; LOW BYTE OF OUTPUT ADDRESS VECTOR TO ROUTINE
; THAT PROCESSES OUTPUT CHARACTERS; SET WITH
; OUTPORT, & BY PR#S; RESET, "0" + CTRL-P, &
; PR#0, SET THIS LOCATION TO $FDF0 (COUT1: MON-
; ITOR OUTPUT TO SCREEN); "S" + CTRL-P, & PR#S,
; SET THIS LOCATION TO $CS00 (SLOT "S" ROM).
CSWH EQU $37 ; HIGH BYTE OF OUTPUT ADDRESS VECTOR TO ROUTINE
; THAT PROCESSES OUTPUT CHARACTERS; SET WITH
; OUTPORT, & BY PR#S; RESET, "0" + CTRL-P, &
; PR#0, SET THIS LOCATION TO $FDF0 (COUT1: MON-
; ITOR OUTPUT TO SCREEN); "S" + CTRL-P, & PR#S,
; SET THIS LOCATION TO $CS00 (SLOT "S" ROM).
KSWL EQU $38 ; LOW BYTE OF INPUT ADDRESS VECTOR TO ROUTINE
; THAT PROCESSES INPUT CHARACTERS; SET WITH
; INPORT, & BY IN#S; RESET, "0" + CTRL-K, &
; IN#0, SET THIS LOCATION TO $FD1B (KEYIN: MON-
; ITOR KEYBOARD INPUT ROUTINE); "S" + CTRL-K, &
; IN#S, SET THIS LOCN TO $CS00 (SLOT "S" ROM).
KSWH EQU $39 ; HIGH BYTE OF INPUT ADDRESS VECTOR TO ROUTINE
; THAT PROCESSES INPUT CHARACTERS; SET WITH
; INPORT, & BY IN#S; RESET, "0" + CTRL-K, &
; IN#0, SET THIS LOCATION TO $FD1B (KEYIN: MON-
; ITOR KEYBOARD INPUT ROUTINE); "S" + CTRL-K, &
; IN#S, SET THIS LOCN TO $CS00 (SLOT "S" ROM).
RNDL EQU $4E ; LOW BYTE OF NUMBER RANDOMIZED WITH EACH KEY
; ENTRY DONE BY MONITOR KEYIN ROUTINE (& BY
; MANY OTHER ROUTINES SUCH AS SERIAL & PARALLEL
; COMMUNICATIONS CARDS, WHICH ARE USED TO
; REPLACE KEYIN); RANDOMIZATION ACCOMPLISHED BY
; CONTINUOUSLY INCREMENTING WHILE AWAITING
; KEYBOARD INPUT.
RNDH EQU $4F ; HIGH BYTE OF NUMBER RANDOMIZED WITH EACH KEY
; ENTRY DONE BY MONITOR KEYIN ROUTINE (& BY
; MANY OTHER ROUTINES SUCH AS SERIAL & PARALLEL
; COMMUNICATIONS CARDS, WHICH ARE USED TO
; REPLACE KEYIN); RANDOMIZATION ACCOMPLISHED BY
; CONTINUOUSLY INCREMENTING WHILE AWAITING
; KEYBOARD INPUT.
;---------------------------------------------------------------------
KEYIN EQU $FD1B ; INCREMENT RANDOM NUMBER LOW; IF (RNDL)<>(0)
; -741 ; BRANCH TO KEYIN2; ELSE, INCREMENT RANDOM
; NUMBER HIGH (RNDH), IGNORING OVERFLOW.
KEYIN2 EQU $FD21 ; [BRANCH LABEL]; KEY DOWN?; IF NOT, BRANCH TO
; -735 ; KEYIN; REPLACE FLASHING CURSOR; GET KEYCODE;
; CLEAR KEY STROBE; RETURN TO CALLER; THE A-REG
; CONTAINS THE KEYPRESS KEYCODE.
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; KEYIN~KEYIN2 GETS THE NEXT KEY INPUT FROM THE KEYBOARD: FIRST, KEYIN
; INCREMENTS THE RANDOM NUMBER FIELD (IGNORING OVERFLOW); THEN, KEYIN2
; TESTS THAT A KEY HAS BEEN PRESSED & IF NOT, LOOPS BACK TO KEYIN;
; ELSE, THE CHARACTER MODIFIED BY RDKEY IS RESTORED FROM FLASHING TO
; NORMAL/INVERSE/FLASHING [THE CHARACTER IN THE A-REG AT ENTRY IS
; STORED AT (BASL),Y]; NEXT, KEYIN2 LOADS THE A-REG FROM THE KEYBOARD
; WITH THE KEYCODE OF THE KEY PRESSED; THEN CLEARS THE KEYBOARD
; STROBE; & RETURNS TO CALLER; THE A-REG IS ALTERED.
;---------------------------------------------------------------------
COUT EQU $FDED ; VECTOR TO USER OUTPUT ROUTINE; OUTPUTS/PRINTS
; -531 ; THE CHARACTER/BYTE IN A-REG TO OUTPUT DEVICE
; SPECIFIED BY JUMP INDIRECT TO (CSWL~CSWH)--
; (NORMALLY TO COUT1); THE A-REG IS ALTERED.

Well, COUT is OK, rather than CSW, since it uses the vector too.

gid...@sasktel.net

unread,
Oct 11, 2017, 11:42:48 PM10/11/17
to
> Would it not be better to use CSW and KSW rather than COUT and KEYIN?


Basic.system has its own input and output intercepts at $BE30.BE33 in its global page from $BE00.BEFF. And unless you know what BS does with CSW and KSW, it is best to let it be in charge of setting them and handling them while it is in control.

You can find a good description of Basic.systems global page in the "Prodos 8 Technical Reference Manual".

Brian Patrie

unread,
Oct 12, 2017, 1:53:09 AM10/12/17
to
On 2017-10-10 00:57, James Davis wrote:
> It is not really a DELETE key. It operates like a BACKSPACE key and occupies the same keyboard space as BACKSPACE keys do on more modern keyboards. An easier fix is to make a new label for it!

At the risk of being pedantic:

Does it not delete (when properly implemented--as in the likes of
AppleWorks, or ProgramWriter)? You've gotten used to a nomenclature
that descends from typewriters--which, of course, do not delete. A more
properly descriptive name for the intended function of this key is
delete-to-left. The IBMoid PC Delete key is, of course, delete-to-right.

FWIW: The Apple II delete key sends an ASCII rubout character.
And the left-arrow key sends backspace.

Brian Patrie

unread,
Oct 12, 2017, 1:59:46 AM10/12/17
to
On 2017-10-10 11:59, Steve Nickolas wrote:
> And indeed most emulators I've used map BkSp to <-, putting Delete on
> Del if it's actually needed.

AppleWin is one of these. I wish i could disable the feature; it's a
bit annoying in environments where it behaves properly.

James Davis

unread,
Oct 12, 2017, 3:09:23 AM10/12/17
to
OK, that is in your FOR PRODOS routine, but in your DELETE and DEL2 routines you are using KEYIN and COUT. What if the user is using some other I/O devices rather than the standard Apple II keyboard and monitor? They might just have a motherboard hooked up remotely to their I/O devices. That's why there are User Vectors at KSW and CSW, so the user can usurp and not use the standard I/O if necessary. Wouldn't you want to catch the Delete key code for wherever it came in from?

James Davis

unread,
Oct 12, 2017, 3:37:37 AM10/12/17
to
OK, I am going on common usage of IBM-PC 101-key keyboards and not the Apple IIe keyboard for my descriptions of function for the DELETE key and BACKSPACE key. And, yes, the DELETE key does delete when properly implemented, but it is totally backward from what I am currently used to. I don't remember whether the typewriters I learned to type on in high-school (ca. 1967~1968) had a DELETE key or not--I don't think so, that feature came later with the IBM Selectrics--but I am pretty sure those typewriters had a backspace key (somewhere on them, not necessarily where the backspace key is on modern keyboards) that operated like a left-arrow so you could type-over what you backed-up over. On the Selectrics, it would white-out (from the ribbon) what you backed-up over as you did it.

gid...@sasktel.net

unread,
Oct 12, 2017, 10:42:53 AM10/12/17
to
You are doing what I call "Fetching". You are looking for complicated scenarios and trying to understand how this program would work in the event you encounter those scenarios. It is best when programming the Apple to use the KISS (Keep It Simple Stupid) method. Then when "That Scenario" arises you can see how to either program for it or around it.

The direct answer, though, would be "no", you wouldn't want to catch the Delete key from wherever it came from. This routine is meant to be a part of the keyboard driver for this computer. If you have other input or output devices then you will have drivers for those devices and they will not encounter this routine unless you put it into its driver.

gid...@sasktel.net

unread,
Oct 13, 2017, 12:30:44 AM10/13/17
to
On Thursday, October 12, 2017 at 1:09:23 AM UTC-6, James Davis wrote:
Another reason this won't work is that the byte $FF is recognized as the delete key when the keyboard latch at $C000 is read. But the byte $FF can have a totally different meaning when coming from another input device. The device driver then would handle the byte $FF accordingly.

James Davis

unread,
Oct 13, 2017, 1:42:03 AM10/13/17
to
Yes, that's why I'll never program again. I'm always reading too much into it. I forgot that this is just for ProDOS BASIC.SYSTEM.

gid...@sasktel.net

unread,
Oct 13, 2017, 4:14:47 PM10/13/17
to
I thought the same way when I first started programming and I was doing it the hard way using the monitor instead of a source assembler. I was trying to imagine every scenario and tried to write program for every scenario. For a little while I grew to hate programming and left it for a few years.

I got back into it when I came across the Ninja Force Assembler, and with Sweet16, the two became a dream team. I could copy and paste monitor listings of programs I managed to create into TextEdit on the Mac, edit the text then, copy and paste the source back into NFAssembler. Now I had the tools and routines to do a whole new way of programming, and now I have a library of routines that I can copy and paste into any source and pretty much create any program I want.

The nice thing about NFAssembler is that is wasn't a huge learning curve. The source listings are basically the same as monitor listings but without the addresses or bytes. Just the mnemonics and labels.

So, never say "Never". You just need to find your momentum.

Bill Chatfield

unread,
Oct 14, 2017, 1:16:02 AM10/14/17
to
I try to stick to making it work with a finite set of use cases and K.I.S.S. I strive for perfection but also realize that it's OK to fall short because perfection is really unattainable. Having something that is functional is better than trying for perfection and never getting to the point that it just works for one use case. Make one thing work and then add the next. Don't try to solve every possibility at the same time.

Michael Pohoreski

unread,
Oct 14, 2017, 12:58:21 PM10/14/17
to
Exactly this.

Solve _today's_ problem, NOT some hypothetical tomorrow's problem. You can see this with DOS 3.3's shitty File System design.

That isn't to say you don't plan ahead -- but until you _implement_ it you won't _fully_ grok the problem. An "bad" implementation trumps a "perfect" theory every time. As Fred Brooks said over 50 years ago "Plan to throw one away, you will anyways."

Michael J. Mahon

unread,
Oct 14, 2017, 6:17:40 PM10/14/17
to
I'm in complete agreement.

"Libraries" are a common example of code so over-generalized that one can
easily do a much more efficient implementation oneself.

"The perfect is the enemy of the good."

--
-michael - NadaNet 3.1 and AppleCrate II: http://michaeljmahon.com

Michael Pohoreski

unread,
Oct 15, 2017, 1:44:34 AM10/15/17
to
Indeed. At work I'm constantly seeing people pull in every library under the sun because they need 1 function here and there -- they end up with "dependency hell", a bloated executable and they wonder why it takes so long to load their app and/or build.

For one project we just got rid of jQuery. The few functions we were _actually_ using I rewrote them as native JavaScript because it was trivial to implement. Our app is smaller, faster to load, we don't have to worry about a new version of the lib breaking, etc.

Michael J. Mahon

unread,
Oct 15, 2017, 3:04:27 AM10/15/17
to
...the dark side of "code reuse".

Anthony Ortiz

unread,
Oct 15, 2017, 11:22:39 AM10/15/17
to
On Sunday, October 15, 2017 at 1:44:34 AM UTC-4, Michael Pohoreski wrote:
> Indeed. At work I'm constantly seeing people pull in every library under the sun because they need 1 function here and there -- they end up with "dependency hell", a bloated executable and they wonder why it takes so long to load their app and/or build.
>
> For one project we just got rid of jQuery. The few functions we were _actually_ using I rewrote them as native JavaScript because it was trivial to implement. Our app is smaller, faster to load, we don't have to worry about a new version of the lib breaking, etc.

Not to mention the dependencies that the dependencies themselves have. You think you're using one library when in fact it could be dozens. Modern web development epitomizes this.

Michael Pohoreski

unread,
Oct 16, 2017, 12:43:52 PM10/16/17
to
On Sunday, October 15, 2017 at 8:22:39 AM UTC-7, Anthony Ortiz wrote:
> Not to mention the dependencies that the dependencies themselves have.

Yup, AKA "dependency hell" :-/

--
Weinberg's Second Law: If builders built buildings the way programmers wrote programs, then the first woodpecker that came along would destroy civilization. -- collated via Murphy's Computer Laws

gid...@sasktel.net

unread,
Oct 16, 2017, 4:19:02 PM10/16/17
to
Rob's Third Law: A computer is only as smart as the programmer that programmed it.

And,

Too many programmers (libraries) spoil the intended result.

mdj

unread,
Nov 21, 2017, 10:05:52 PM11/21/17
to
On Thursday, 12 October 2017 15:53:09 UTC+10, Brian Patrie wrote:

> At the risk of being pedantic:
>
> Does it not delete (when properly implemented--as in the likes of
> AppleWorks, or ProgramWriter)? You've gotten used to a nomenclature
> that descends from typewriters--which, of course, do not delete. A more
> properly descriptive name for the intended function of this key is
> delete-to-left. The IBMoid PC Delete key is, of course, delete-to-right.

Exactly. The 'delete' key has had the same label and been in the same spot on every Apple machine since the IIe (where it was introduced). Who's right ?

> FWIW: The Apple II delete key sends an ASCII rubout character.
> And the left-arrow key sends backspace.

And it does exactly what a TTY or paper tape printer does. ASCII "Backspace" moves the carriage back one space, and that's exactly what happens on an Apple II when you press the left arrow key.

Even the 'delete' key on the IIe/IIc/IIgs behaves ostensibly correctly from an ASCII point of view - the crosshatch is a visual representation of what ASCII delete does to a punched tape which is punch all the holes :-)

0 new messages