*************************************************************************
*************************************************************************
**                                                                     **
**      SOUND SYSTEM                                                   **
**                                                                     **
*************************************************************************
*************************************************************************

-------------------------------------------------------------------------
|                                                                       |
|       OSWORD  07 - Make a sound                                       |
|                                                                       |
-------------------------------------------------------------------------
; On entry, control block pointed to by &F0/1
;           Y=0 on entry
; XY +0  Channel - &hsfc for Hold, Sync, Flush, Channel
;     2  Amplitude/Envelope
;     4  Pitch
;     6  Duration

E82D	INY
E82E	LDA (&F0),Y ; Get channel high byte byte
E830	CMP #&FF
E832	BEQ &E88D   ; Channel &FFxx, speech command
E834	CMP #&20    ; Is channel>=&20 ?
E836	LDX #&08    ; Prepare X=8 for unrecognised OSWORD call
E838	BCS &E7CA   ; Pass to sideways ROMs for channel &2000+
E83A	DEY         ; Point back to channel low byte
E83B	JSR &E8C9   ; Get Channel 0-3, and Cy if >=&10 for Flush
E83E	ORA #&04    ; Convert to buffer number 4-7
E840	TAX
E841	BCC &E848   ; If no Flush, skip past
E843	JSR &E1AE   ; Flush buffer
E846	LDY #&01    ; Point back to channel high byte

E848	JSR &E8C9   ; Get Sync 0-3, and Cy if >=&10 for Hold
E84B	STA &FA     ; Save Sync in &FA
E84D	PHP         ; Stack flags
E84E	LDY #&06
E850	LDA (&F0),Y ; Get Duration byte
E852	PHA         ;  and stack it
E853	LDY #&04
E855	LDA (&F0),Y ; Get pitch byte
E857	PHA         ;  and stack it
E858	LDY #&02    ;
E85A	LDA (&F0),Y ; Get amplitude/envelope byte
E85C	ROL         ; Move Hold into bit 0
E85D	SEC         ;set carry
E85E	SBC #&02    ;subract 2
E860	ASL         ;multiply by 4
E861	ASL         ;
E862	ORA &FA     ;add S byte (0-3)

    	            ; At this point,
		    ; b7,   0=envelope, 1=volume
		    ; b6-3, envelope-1 or volume+15
		    ; b2,   Hold
		    ; b1-0, Sync

E864	JSR &E1F8   ; Insert into buffer
E867	BCC &E887   ; Buffer not full, jump to insert the rest
E869	PLA         ; Drop stacked pitch
E86A	PLA         ; Drop stacked duration
E86B	PLP         ; Restore flags
		    ; And exit

-------------------------------------------------------------------------
|                                                                       |
|       OSBYTE  117 - Read VDU status                                   |
|                                                                       |
-------------------------------------------------------------------------

E86C	LDX &D0     ;get VDU status byte in X
E86E	RTS         ;and return


************* set up sound data for Bell ********************************


E86F	PHP         ;push P
E870	SEI         ;bar interrupts
E871	LDA &0263   ;get bell channel number in A
E874	AND #&07    ; (bits 0-3 only set)
E876	ORA #&04    ;set bit 2
E878	TAX         ;X=A = bell channel number +4=buffer number
E879	LDA &0264   ;get bell amplitude/envelope number
E87C	JSR &E4B0   ;store it in buffer pointed to by X
E87F	LDA &0266   ;get bell duration
E882	PHA         ;save it
E883	LDA &0265   ;get bell frequency
E886	PHA         ;save it

; Insert sound pitch and duration into sound buffer
;
E887	SEC         ; Set carry
E888	ROR &0800,X ; Set bit 7 of channel flags to indicate it's active
E88B	BMI &E8A4   ; Jump forward to insert pitch and duration


-------------------------------------------------------------------------
|                                                                       |
|       SOUND &FFxx - Speech System                                     |
|                                                                       |
-------------------------------------------------------------------------
; On entry, control block pointed to by &F0/1
;           Y=1 on entry
; XY +0  Channel - &FFxx - xx=Speech command
;     2  Word number/Address
;     4  Ignored
;     6  Ignored

E88D	PHP         ; Save flags
E88E	INY         ; Y=2
E88F	LDA (&F0),Y ; Get word number low byte
E891	PHA         ;  and stack it
E892	INY         ; Y=3
E893	LDA (&F0),Y ; Get word number high byte
E895	PHA         ;  and stack it
E896	LDY #&00    ; Y=0
E898	LDA (&F0),Y ; Get speech command
E89A	LDX #&08    ; X=8 for Speech buffer
E89C	JSR &E1F8   ; Insert speech command into speech buffer
E89F	BCS &E869   ; Buffer full, drop stack and abandon
E8A1	ROR &02D7   ; Clear bit 7 of speech buffer busy flag

; Insert two bytes into buffer
;
E8A4	PLA         ; Get word number high byte or pitch back
E8A5	JSR &E4B0   ; Insert into speech buffer
E8A8	PLA         ; Get word number low byte or duration back
E8A9	JSR &E4B0   ; Insert into speech buffer
E8AC	PLP         ; Restore flags
E8AD	RTS         ;  and return


*************************************************************************
*                                                                       *
*       OSWORD  08 - Define Envelope                                    *
*                                                                       *
*************************************************************************
; On entry, control block pointed to by &F0/1
;           Y=0 on entry
;           A=envelope number from (&F0),0
;XY +0  Envelope number, also in A
;    1  bits 0-6 length of each step in centi-secsonds bit 7=0 auto repeat
;    2  change of Pitch per step (-128-+127) in section 1
;    3  change of Pitch per step (-128-+127) in section 2
;    4  change of Pitch per step (-128-+127) in section 3
;    5  number of steps in section 1 (0-255)
;    6  number of steps in section 2 (0-255)
;    7  number of steps in section 3 (0-255)
;    8  change of amplitude per step during attack  phase (-127 to +127)
;    9  change of amplitude per step during decay   phase (-127 to +127)
;   10  change of amplitude per step during sustain phase (-127 to +127)
;   11  change of amplitude per step during release phase (-127 to +127)
;   12  target level at end of attack phase   (0-126)
;   13  target level at end of decay  phase   (0-126)

E8AE	SBC #&01    ;set up appropriate displacement to storage area
E8B0	ASL         ;A=(A-1)*16 or 15
E8B1	ASL         ;
E8B2	ASL         ;
E8B3	ASL         ;
E8B4	ORA #&0F    ;
E8B6	TAX         ;X=A
E8B7	LDA #&00    ;A=0

E8B9	LDY #&10    ;Y=&10

E8BB	CPY #&0E    ;is Y>=14??
E8BD	BCS &E8C1   ;yes then E8C1
E8BF	LDA (&F0),Y ;else get byte from parameter block
E8C1	STA &08C0,X ;and store it in appropriate area
E8C4	DEX         ;decrement X
E8C5	DEY         ;Decrement Y
E8C6	BNE &E8BB   ;if not 0 then do it again
E8C8	RTS         ;else exit
    	            ;note that envelope number is NOT transferred
;
E8C9	LDA (&F0),Y ;get byte
E8CB	CMP #&10    ;is it greater than 15, if so set carry
E8CD	AND #&03    ;and 3 to clear bits 2-7
E8CF	INY         ;increment Y
E8D0	RTS         ;and exit


*************************************************************************
*                                                                       *
*       OSWORD  03   ENTRY POINT                                        *
*                                                                       *
*       read interval timer                                             *
*                                                                       *
*************************************************************************
F0/1 points to block to store data

E8D1	LDX #&0F    ;X=&F displacement from clock to timer
E8D3	BNE &E8D8   ;jump to E8D8


*************************************************************************
*                                                                       *
*       OSWORD  01   ENTRY POINT                                        *
*                                                                       *
*       read system clock                                               *
*                                                                       *
*************************************************************************
F0/1 points to block to store data


E8D5	LDX &0283   ;X=current system clock store pointer

E8D8	LDY #&04    ;Y=4
E8DA	LDA &028D,X ;read byte
E8DD	STA (&F0),Y ;store it in parameter block
E8DF	INX         ;X=x+1
E8E0	DEY         ;Y=Y-1
E8E1	BPL &E8DA   ;if Y>0 then do it again
E8E3	RTS         ;else exit




*************************************************************************
*                                                                       *
*       OSWORD  04   ENTRY POINT                                        *
*                                                                       *
*       write interval timer                                            *
*                                                                       *
*************************************************************************
F0/1 points to block to store data


E8E4	LDA #&0F    ;offset between clock and timer
E8E6	BNE &E8EE   ;jump to E8EE ALWAYS!!


*************************************************************************
*                                                                       *
*       OSWORD  02   ENTRY POINT                                        *
*                                                                       *
*       write system clock                                              *
*                                                                       *
*************************************************************************
F0/1 points to block to store data

E8E8	LDA &0283   ;get current clock store pointer
E8EB	EOR #&0F    ;and invert to get inactive timer
E8ED	CLC         ;clear carry

E8EE	PHA         ;store A
E8EF	TAX         ;X=A
E8F0	LDY #&04    ;Y=4
E8F2	LDA (&F0),Y ;and transfer all 5 bytes
E8F4	STA &028D,X ;to the clock or timer
E8F7	INX         ;
E8F8	DEY         ;
E8F9	BPL &E8F2   ;if Y>0 then E8F2
E8FB	PLA         ;get back stack
E8FC	BCS &E8E3   ;if set (write to timer) E8E3 exit
E8FE	STA &0283   ;write back current clock store
E901	RTS         ;and exit


*************************************************************************
*                                                                       *
*       OSWORD  00   ENTRY POINT                                        *
*                                                                       *
*       read line from current input to memory                          *
*                                                                       *
*************************************************************************
;F0/1 points to parameter block
;   	+0/1    buffer address for input
;   	+2  Maximum line length
;   	+3  minimum acceptable ASCII value
;   	+4  maximum acceptable ASCII value

E902	LDY #&04    ;Y=4

E904	LDA (&F0),Y ;transfer bytes 4,3,2 to 2B3-2B5
E906	STA &02B1,Y ;
E909	DEY         ;decrement Y
E90A	CPY #&02    ;until Y=1
E90C	BCS &E904   ;

E90E	LDA (&F0),Y ;get address of input buffer
E910	STA &E9     ;store it in &E9 as temporary buffer
E912	DEY         ;decrement Y
E913	STY &0269   ;Y=0 store in print line counter for paged mode
E916	LDA (&F0),Y ;get lo byte of address
E918	STA &E8     ;and store in &E8
E91A	CLI         ;allow interrupts
E91B	BCC &E924   ;Jump to E924

E91D	LDA #&07    ;A=7
E91F	DEY         ;decrement Y
E920	INY         ;increment Y
E921	JSR OSWRCH  ;and call OSWRCH

E924	JSR OSRDCH  ;else read character  from input stream
E927	BCS &E972   ;if carry set then illegal character or other error
    	            ;exit via E972
E929	TAX         ;X=A
E92A	LDA &027C   ;A=&27C get character destination status
E92D	ROR         ;put VDU driver bit in carry
E92E	ROR         ;if this is 1 VDU driver is disabled
E92F	TXA         ;X=A
E930	BCS &E937   ;if Carry set E937
E932	LDX &026A   ;get number of items in VDU queque
E935	BNE &E921   ;if not 0 output character and loop round again

E937	CMP #&7F    ;if character is not delete
E939	BNE &E942   ;goto E942
E93B	CPY #&00    ;else is Y=0
E93D	BEQ &E924   ;and goto E924
E93F	DEY         ;decrement Y
E940	BCS &E921   ;and if carry set E921 to output it
E942	CMP #&15    ;is it delete line &21
E944	BNE &E953   ;if not E953
E946	TYA         ;else Y=A, if its 0 we are still reading first
    	            ;character
E947	BEQ &E924   ;so E924
E949	LDA #&7F    ;else output DELETES

E94B	JSR OSWRCH  ;until Y=0
E94E	DEY         ;
E94F	BNE &E94B   ;

E951	BEQ &E924   ;then read character again

E953	STA (&E8),Y ;store character in designated buffer
E955	CMP #&0D    ;is it CR?
E957	BEQ &E96C   ;if so E96C
E959	CPY &02B3   ;else check the line length
E95C	BCS &E91D   ;if = or greater loop to ring bell
E95E	CMP &02B4   ;check minimum character
E961	BCC &E91F   ;if less than minimum backspace
E963	CMP &02B5   ;check maximum character
E966	BEQ &E920   ;if equal E920
E968	BCC &E920   ;or less E920
E96A	BCS &E91F   ;then JUMP E91F

E96C	JSR OSNEWL  ;output CR/LF
E96F	JSR &E57E   ;call Econet vector

E972	LDA &FF     ;A=ESCAPE FLAG
E974	ROL         ;put bit 7 into carry
E975	RTS         ;and exit routine


*************************************************************************
*                                                                       *
*       OSBYTE  05   ENTRY POINT                                        *
*                                                                       *
*       SELECT PRINTER TYPE                                             *
*                                                                       *
*************************************************************************

E976	CLI         ;allow interrupts briefly
E977	SEI         ;bar interrupts
E978	BIT &FF     ;check if ESCAPE is pending
E97A	BMI &E9AC   ;if it is E9AC
E97C	BIT &02D2   ;else check bit 7 buffer 3 (printer)
E97F	BPL &E976   ;if not empty bit 7=0 E976

E981	JSR &E1A4   ;check for user defined routine
E984	LDY #&00    ;Y=0
E986	STY &F1     ;F1=0


*************************************************************************
*                                                                       *
*       OSBYTE  01   ENTRY POINT                                        *
*                                                                       *
*       READ/WRITE USER FLAG (&281)                                     *
*                                                                       *
*          AND                                                          *
*                                                                       *
*       OSBYTE  06   ENTRY POINT                                        *
*                                                                       *
*       SET PRINTER IGNORE CHARACTER                                    *
*                                                                       *
*************************************************************************
; A contains osbyte number


E988	ORA #&F0    ;A=osbyte +&F0
E98A	BNE &E99A   ;JUMP to E99A


*************************************************************************
*                                                                       *
*       OSBYTE  0C   ENTRY POINT                                        *
*                                                                       *
*       SET  KEYBOARD AUTOREPEAT RATE                                   *
*                                                                       *
*************************************************************************

E98C	BNE &E995   ;if &F0<>0 goto E995
E98E	LDX #&32    ;if X=0 in original call then X=32
E990	STX &0254   ;to set keyboard autorepeat delay ram copy
E993	LDX #&08    ;X=8


*************************************************************************
*                                                                       *
*       OSBYTE  0B   ENTRY POINT                                        *
*                                                                       *
*       SET  KEYBOARD AUTOREPEAT DELAY                                  *
*                                                                       *
*************************************************************************

E995	ADC #&CF    ;A=A+&D0 (carry set)


*************************************************************************
*                                                                       *
*       OSBYTE  03   ENTRY POINT                                        *
*                                                                       *
*       SELECT OUTPUT STREAM                                            *
*                                                                       *
*               AND                                                     *
*                                                                       *
*                                                                       *
*       OSBYTE  04   ENTRY POINT                                        *
*                                                                       *
*       ENABLE/DISABLE CURSOR EDITING                                   *
*                                                                       *
*************************************************************************

E997	CLC         ;c,ear carry
E998	ADC #&E9    ;A=A+&E9

E99A	STX &F0     ;store X


*************************************************************************
*                                                                       *
*       OSBYTE  A6-FF   ENTRY POINT                                     *
*                                                                       *
*       READ/ WRITE SYSTEM VARIABLE OSBYTE NO. +&190                    *
*                                                                       *
*************************************************************************


E99C	TAY         ;Y=A
E99D	LDA &0190,Y ;i.e. A=&190 +osbyte call!
E9A0	TAX         ;preserve this
E9A1	AND &F1     ;new value = OLD value AND Y EOR X!
E9A3	EOR &F0     ;
E9A5	STA &0190,Y ;store it
E9A8	LDA &0191,Y ;get value of next byte into A
E9AB	TAY         ;Y=A
E9AC	RTS         ;and exit


******* SERIAL BAUD RATE LOOK UP TABLE ************************************

E9AD	DB  &64     ; % 01100100      75
E9AE	DB  &7F     ; % 01111111     150
E9AF	DB  &5B     ; % 01011011     300
E9B0	DB  &6D     ; % 01101101    1200
E9B1	DB  &C9     ; % 11001001    2400
E9B2	DB  &F6     ; % 11110110    4800
E9B3	DB  &D2     ; % 11010010    9600
E9B4	DB  &E4     ; % 11100100   19200
E9B5	DB  &40     ; % 01000000



*************************************************************************
*                                                                       *
*       OSBYTE  &13   ENTRY POINT                                       *
*                                                                       *
*       Wait for VSync                                                  *
*                                                                       *
*************************************************************************

E9B6	LDA &0240   ;read vertical sync counter
E9B9	CLI         ;allow interrupts briefly
E9BA	SEI         ;bar interrupts
E9BB	CMP &0240   ;has it changed?
E9BE	BEQ &E9B9   ;no then E9B9
; falls through and reads VDU variable X

*************************************************************************
*                                                                       *
*       OSBYTE  160   ENTRY POINT                                       *
*                                                                       *
*       READ VDU VARIABLE                                               *
*                                                                       *
*************************************************************************
;X contains the variable number
;0 =lefthand column in pixels current graphics window
;2 =Bottom row in pixels current graphics window
;4 =Right hand column in pixels current graphics window
;6 =Top row in pixels current graphics window
;8 =lefthand column in absolute characters current text window
;9 =Bottom row in absolute characters current text window
;10 =Right hand column in absolute characters current text window
;11 =Top row in absolute characters current text window
;12-15 current graphics origin in external coordinates
;16-19 current graphics cursor in external coordina4es
;20-23 old graphics cursor in internal coordinates
;24 current text cursor in X and Y

E9C0	LDY &0301,X ;get VDU variable hi
E9C3	LDA &0300,X ;low
E9C6	TAX         ;X=low byte
E9C7	RTS         ;and exit


*************************************************************************
*                                                                       *
*       OSBYTE  18   ENTRY POINT                                        *
*                                                                       *
*       RESET SOFT KEYS                                                 *
*                                                                       *
*************************************************************************

E9C8	LDA #&10    ;set consistency flag
E9CA	STA &0284   ;

E9CD	LDX #&00    ;X=0

E9CF	STA &0B00,X ;and wipe clean
E9D2	INX         ;soft key buffer
E9D3	BNE &E9CF   ;until X=0 again

E9D5	STX &0284   ;zero consistency flag
E9D8	RTS         ;and exit


*************************************************************************
*                                                                       *
*        OSBYTE &76 (118) SET LEDs to Keyboard Status                   *
*                                                                       *
*************************************************************************

    	            ;osbyte entry with carry set
    	            ;called from &CB0E, &CAE3, &DB8B
    	
E9D9	PHP         ;PUSH P
E9DA	SEI         ;DISABLE INTERUPTS
E9DB	LDA #&40    ;switch on CAPS and SHIFT lock lights
E9DD	JSR &E9EA   ;via subroutine
E9E0	BMI &E9E7   ;if ESCAPE exists (M set) E9E7
E9E2	CLC         ;else clear V and C
E9E3	CLV         ;before calling main keyboard routine to
E9E4	JSR &F068   ;switch on lights as required
E9E7	PLP         ;get back flags
E9E8	ROL         ;and rotate carry into bit 0
E9E9	RTS         ;Return to calling routine
    	            ;
***************** Turn on keyboard lights and Test Escape flag ************
    	            ;called from &E1FE, &E9DD
    	            ;
E9EA	BCC &E9F5   ;if carry clear
E9EC	LDY #&07    ;switch on shift lock light
E9EE	STY &FE40   ;
E9F1	DEY         ;Y=6
E9F2	STY &FE40   ;switch on Caps lock light
E9F5	BIT &FF     ;set minus flag if bit 7 of &00FF is set indicating
E9F7	RTS         ;that ESCAPE condition exists, then return
    	            ;
****************** Write A to SYSTEM VIA register B *************************
    	            ;called from &CB6D, &CB73
E9F8	PHP         ;push flags
E9F9	SEI         ;disable interupts
E9FA	STA &FE40   ;write register B from Accumulator
E9FD	PLP         ;get back flags
E9FE	RTS         ;and exit
    	            ;


*************************************************************************
*                                                                       *
*       OSBYTE 154 (&9A) SET VIDEO ULA                                  *
*                                                                       *
*************************************************************************

E9FF	TXA         ;osbyte entry! X transferred to A thence to

*******Set Video ULA control register **entry from VDU routines **************
    	            ;called from &CBA6, &DD37

EA00	PHP         ;save flags
EA01	SEI         ;disable interupts
EA02	STA &0248   ;save RAM copy of new parameter
EA05	STA &FE20   ;write to control register
EA08	LDA &0253   ;read  space count
EA0B	STA &0251   ;set flash counter to this value
EA0E	PLP         ;get back status
EA0F	RTS         ;and return


*************************************************************************
*                                                                       *
*        OSBYTE &9B (155) write to palette register                     *
*                                                                       *
*************************************************************************

    	    ;entry X contains value to write
EA10	TXA         ;A=X
EA11	EOR #&07    ;convert to palette format
EA13	PHP         ;
EA14	SEI         ;prevent interrupts
EA15	STA &0249   ;store as current palette setting
EA18	STA &FE21   ;store actual colour in register
EA1B	PLP         ;get back flags
EA1C	RTS         ;and exit
    	            ;


*************************************************************************
*       GSINIT  string initialisation                                   *
*       F2/3 points to string offset by Y                               *
*                                                                       *
*       ON EXIT                                                         *
*       Z flag set indicates null string,                               *
*       Y points to first non blank character                           *
*       A contains first non blank character                            *
*************************************************************************

EA1D	CLC         ;clear carry

EA1E	ROR &E4     ;Rotate moves carry to &E4
EA20	JSR &E03A   ;get character from text
EA23	INY         ;increment Y to point at next character
EA24	CMP #&22    ;check to see if its '"'
EA26	BEQ &EA2A   ;if so EA2A (carry set)
EA28	DEY         ;decrement Y
EA29	CLC         ;clear carry
EA2A	ROR &E4     ;move bit 7 to bit 6 and put carry in bit 7
EA2C	CMP #&0D    ;check to see if its CR to set Z
EA2E	RTS         ;and return


*************************************************************************
*       GSREAD  string read routine                                     *
*       F2/3 points to string offset by Y                               *
*                                                                       *
*************************************************************************
    	            ;
EA2F	LDA #&00    ;A=0
EA31	STA &E5     ;store A
EA33	LDA (&F2),Y ;read first character
EA35	CMP #&0D    ;is it CR
EA37	BNE &EA3F   ;if not goto EA3F
EA39	BIT &E4     ;if bit 7=1 no 2nd '"' found
EA3B	BMI &EA8F   ;goto EA8F
EA3D	BPL &EA5A   ;if not EA5A

EA3F	CMP #&20    ;is less than a space?
EA41	BCC &EA8F   ;goto EA8F
EA43	BNE &EA4B   ;if its not a space EA4B
EA45	BIT &E4     ;is bit 7 of &E4 =1
EA47	BMI &EA89   ;if so goto EA89
EA49	BVC &EA5A   ;if bit 6 = 0 EA5A
EA4B	CMP #&22    ;is it '"'
EA4D	BNE &EA5F   ;if not EA5F
EA4F	BIT &E4     ;if so and Bit 7 of &E4 =0 (no previous ")
EA51	BPL &EA89   ;then EA89
EA53	INY         ;else point at next character
EA54	LDA (&F2),Y ;get it
EA56	CMP #&22    ;is it '"'
EA58	BEQ &EA89   ;if so then EA89

EA5A	JSR &E03A   ;read a byte from text
EA5D	SEC         ;and return with
EA5E	RTS         ;carry set
    	            ;
EA5F	CMP #&7C    ;is it '|'
EA61	BNE &EA89   ;if not EA89
EA63	INY         ;if so increase Y to point to next character
EA64	LDA (&F2),Y ;get it
EA66	CMP #&7C    ;and compare it with '|' again
EA68	BEQ &EA89   ;if its '|' then EA89
EA6A	CMP #&22    ;else is it '"'
EA6C	BEQ &EA89   ;if so then EA89
EA6E	CMP #&21    ;is it !
EA70	BNE &EA77   ;if not then EA77
EA72	INY         ;increment Y again
EA73	LDA #&80    ;set bit 7
EA75	BNE &EA31   ;loop back to EA31 to set bit 7 in next CHR
EA77	CMP #&20    ;is it a space
EA79	BCC &EA8F   ;if less than EA8F Bad String Error
EA7B	CMP #&3F    ;is it '?'
EA7D	BEQ &EA87   ;if so EA87
EA7F	JSR &EABF   ;else modify code as if CTRL had been pressed
EA82	BIT &D9B7   ;if bit 6 set
EA85	BVS &EA8A   ;then EA8A
EA87	LDA #&7F    ;else set bits 0 to 6 in A

EA89	CLV         ;clear V
EA8A	INY         ;increment Y
EA8B	ORA &E5     ;
EA8D	CLC         ;clear carry
EA8E	RTS         ;Return
    	            ;
EA8F	BRK         ;
EA90	DB  &FD     ;error number
EA93	DB 'Bad String' ; message
EA9B	BRK         ;


************ Modify code as if SHIFT pressed *****************************

EA9C	CMP #&30    ;if A='0' skip routine
EA9E	BEQ &EABE   ;
EAA0	CMP #&40    ;if A='@' skip routine
EAA2	BEQ &EABE   ;
EAA4	BCC &EAB8   ;if A<'@' then EAB8
EAA6	CMP #&7F    ;else is it DELETE

EAA8	BEQ &EABE   ;if so skip routine
EAAA	BCS &EABC   ;if greater than &7F then toggle bit 4
EAAC	EOR #&30    ;reverse bits 4 and 5
EAAE	CMP #&6F    ;is it &6F (previously ' _' (&5F))
EAB0	BEQ &EAB6   ;goto EAB6
EAB2	CMP #&50    ;is it &50 (previously '`' (&60))
EAB4	BNE &EAB8   ;if not EAB8
EAB6	EOR #&1F    ;else continue to convert ` _
EAB8	CMP #&21    ;compare &21 '!'
EABA	BCC &EABE   ;if less than return
EABC	EOR #&10    ;else finish conversion by toggling bit 4
EABE	RTS         ;exit
    	            ;
    	            ;ASCII codes &00 &20 no change
    	            ;21-3F have bit 4 reverses (31-3F)
    	            ;41-5E A-Z have bit 5 reversed a-z
    	            ;5F & 60 are reversed
    	            ;61-7E bit 5 reversed a-z becomes A-Z
    	            ;DELETE unchanged
    	            ;&80+ has bit 4 changed


************** Implement CTRL codes *************************************


EABF	CMP #&7F    ;is it DEL
EAC1	BEQ &EAD1   ;if so ignore routine
EAC3	BCS &EAAC   ;if greater than &7F go to EAAC
EAC5	CMP #&60    ;if A<>'`'
EAC7	BNE &EACB   ;goto EACB
EAC9	LDA #&5F    ;if A=&60, A=&5F

EACB	CMP #&40    ;if A<&40
EACD	BCC &EAD1   ;goto EAD1  and return unchanged
EACF	AND #&1F    ;else zero bits 5 to 7
EAD1	RTS         ;return
    	            ;
EAD2	DB  '/!BOOT',&0D