!lm12
!rm75
Add Bit-Control to Apple Monitor...........Bob Sander-Cederlof

The other day someone sent me a disk with an article for AAL on it as a binary file.  The codes in the file were all ASCII characters, but they were nevertheless not compatible with any word processors I had around.

All blanks were coded as $A0 (hi-bit on), and all other characters were coded in the range $00-$7F (hi-bit off).  Otherwise, everything was compatible with my favorite word processor (the one I am still in the process of finishing).

I need to have all the hi-bits set to one in the file, or in the memory image after BLOADing the file.  That's the motivation for the following neat enhancement to the Apple monitor.

The enhancement hooks in through the control-Y user command vector.  By merely typing:

     *80FF<2000.3FFF^Y    (^Y means control-Y)

I set all the hi-bits between $2000 and $3FFF.

The "80FF" in the command line above is the magic part of this enhancement.  The last two digits are ANDed with every byte in the specified range, clearing every bit which is zero in those two digits.  By using $FF, no bits are cleared.  Other values for these two digits will clear whatever bits you wish.

The first two digits are ORed into every byte in the specified range, setting every bit which is one in the two digits.  $80 in my example sets the top bit in every byte.

The code is designed to be BRUN from a binary file, and it is completely relocatable.  You can BRUN it anywhere in memory that you have room for 36 bytes.  That is why the SETUP code is longer than the actual control-Y code!

The SETUP routine first discovers where in memory it is running, and then sets up the control-Y vector in page 3 to point at the BITS code.  The discovery is done in the usual way, by JSRing to a guaranteed RTS in the monitor ROM, at $FF58.  This leaves a return address just below the stack pointer.  I pick up that address and add the difference between that and BITS to get the appropriate control-Y vector pointer.

Line 1200 needs a little explanation.  My assembler automatically switches to page zero addressing mode if the address is less than $100.  STACK-1 is less than $100, so "ADC STACK-1,X" would assemble as though I wrote "ADC $FF,X".  Indexed addressing in page zero mode stays in page zero, wrapping around.  If X=3, "ADC $FF,X" would reference location $02 in page zero rather than $102.  Therefore I had to use the ".DA #$7D" to force the assembler to use a full 16-bit address mode.  (Some assemblers have a special way of forcing 16-bit addressing in cases like this; others require special marks to get zero-page modes.)

BITS itself is very straightforward code.  The monitor leaves the starting address of the specified range in A1 ($3C,3D), the ending address in A2 ($3E,3F), and the mask in A4 ($42,43).  The subroutine at $FCBA increments A1 and compares it to A2, leaving carry clear if the range is not yet complete.
