Metropoli BBS
VIEWER: falseclr.s MODE: TEXT (ASCII)
*	TITLE [ON]-[A]-[F] Trap Loop, Version 2.0
** begin BACKGRND.S *********************************************
*****************************************************************
**
** NAME: BACKGRND.S
**
** CATEGORY: Memory
**
** ENTRY: -
**
** EXIT: -
**                    
** ABSTRACT: Runs 48's keys in [ON]-[A]-[F] protected shell.
**
** MODULE HISTORY:
**
** Written			09/08/93	Rick Grevelle
** Completely Re-written        09/20/93        Jeoff Krontz
**
**
** Changes made:
**      
** 1. May now use [ON] like normal
** 2. May now use [OFF] like normal
** 3. Keys aren't missed if typed quickly
** 4. If [A] or [F] is pressed before [ON], no memory is lost
** 5. May use key combinations now, like [ALPHA]-[LSHIFT]-[G].  You
**    are no longer forced to do one key at a time.
** 6. Once memory is (falsely) cleared, the home directory now appears
**    empty, so that determined people who hit [VAR] after the clear
**    will think it worked.  (Uses a Null directory)
** 7. [ON]-[B] will restore the directory instantly.
**
**
*****************************************************************
*****************************************************************

ASSEMBLE
sSX		EQU 0
sFKEY		EQU 1
Putkey		EQU #00D9F
ClearDisplay	EQU #01BFF
CONTRAST	EQU #00101
NULLID		EQU #15777
XeqInPlace	EQU #026BF
ANNUNCIATORS	EQU #706C3
DoingRecRam	EQU #71B29
RecoverRam?	EQU #71B91
G_XeqInPlace	EQU #7008B
G_ANNUNCIATORS	EQU #80841
G_DoingRecRam	EQU #81CBC
G_RecoverRam?	EQU #81D24

RPL
::
  BEGIN
  AtUserStack
  SysMenuCheck
  SysDisplay

CODE
	GOSBVL 	=SAVPTR

**check to determine if GX or SX
	D0=(5)  (=INHARDROM?)+14
	C=DAT0	B			
	?CBIT=0	3			
	GOYES	sx1
gx1	ST=0	sSX
	LC(5)	G_ANNUNCIATORS
	GOTO	busyoff
sx1     ST=1	sSX
	LC(5)	ANNUNCIATORS

** turn off the busy annunciator
busyoff CD0EX
	C=DAT0	B
	CBIT=0	7
	DAT0=C	B
	D0=(5)	=ANNCTRL
	C=DAT0	B		C[B]: [AON XTRA A6 A5 A4 A3 A2 A1]
	CBIT=0	4		C[B]: [ *    *   *  0  *  *  *  *]
	DAT0=C	B		turn off busy annunciator

	GOSUB	anykeys?	keys in buffer?  Yes -> quit
	INTOFF                  interrupts off
	ST=0	15		i
	GOSUB	wait4nokeys	trap if someone keeps key pressed	

waitkey	SHUTDN                  Shut Down until key pressed  <----------
	GOSBVL	=OnKeyDown?	is [ON] down?				|
	GONC	skip	        ** GOC On-A-F? out of range		|
	GOTO  	ON-A-F?		yes, check for [ON]-[A]-[F]		|
skip	LC(3) 	=allkeys	load entire keyboard			|
	GOSUB 	setkeys							|
	?C=0  	A		are no keys down?			|
	GOYES 	waitkey       	no keys down, ------------------------->

** see if the key down is [A] or [F]
doublecheck
	A=0   	A
	LA(2) 	#10		load [A] mask
	LC(3) 	#2		activate OR1
	ST=0  	sFKEY		set looking at [A] key
	GOSUB 	setkeys
	?A=C  	A		is [A] down?
	GOYES 	trapA_F		yes, trap that key
	
	ASR   	B 		load [F] mask (#01)
	LC(3) 	#100		activate OR8
	ST=1  	sFKEY		set looking at [F] key
	GOSUB 	setkeys
	?A=C  	A		is [F] down?
	GOYES 	trapA_F		yes, trap that key
	GOTO 	exitwkeys	no,  exit & let key get passed to buffer

** trap keys: wait until no keys down or [ON] is pressed
trapA_F	GOSBVL =OnKeyDown?	<---------------------------------------
	GOC ON-A-F?							|
*									|
	LC(3) 	=allkeys	load entire keyboard			|
	GOSUB 	setkeys							|
	?C#0  	A		is a key down?				|
	GOYES 	trapA_F		yes, ---------------------------------->
	C=0 	W
	LC(1) 	1		C[B]: keycode for [A]
	?ST=0  	sFKEY		was it is [A] key pressed?
	GOYES 	Pushkey		yes, ---------------------------------->
	LC(1)	6		no, C[B]: keycode for [F]		|
Pushkey GOSBVL 	Putkey          <---------------------------------------
 	GOTO 	exitwkeys

ON-A-F?	LA(5) 	#8010		load [ON]-[B] & [ON]-[A] mask  <-----------
 	LC(3) 	#100   		activate OR8 (looking for [ON]-[B] first)  |
 	GOSUB 	setkeys							   |
 	?A=C 	A		is [ON]-[B] down?			   |
 	GOYES 	ON-B							   |
*									   |
 	?C#0 	A        	are keys down?   		 	   |
 	GOYES 	checkON-A-F	yes, ---------------------------------->   |
 	GOTO 	exit_after_on	leave with [ON] treated as [ATTN]	|  |
*									|  |
checkON-A-F                    *<---------------------------------------   |
 	LC(3) 	#2     		activate OR1 (looking for [ON]-[A] now)    |
 	GOSUB	setkeys							   |
 	?A#C 	A		is [ON]-[A] down?			   |
 	GOYES 	ON-A-F?		no, -------------------------------------->
*								|
 	ASR   	B       	load [ON]-[F] mask (#8001)	|
 	LC(3) 	#100    	activate OR8			|
 	GOSUB 	setkeys						|
 	?A=C 	A		is [ON]-[F] down?		|
 	GOYES 	FALSECLR	yes, ---------------------------------->
 	GOTO 	ON-A-F?		--------------------------------/	|
*									|
*									|
ON-B 	ST=1   	15		turn interrupts back on			|
 	LA(5)  	=FALSE							|
 	GOSBVL 	=GETPTR							|
 	PC=(A)			return to sys-rpl shell			|
*									|
** the FalseClear routine was written by Rick Grevelle			|
** with modifications by myself to change some things so		|
** that they would more closely emulate the a "true" clear 		|
FALSECLR                       *<---------------------------------------
 	GOSUB 	wait4nokeys	wait until they let go of the keys
 	D0=(5) 	CONTRAST	change contrast to HP default
 	C=0    	A
	?ST=1	sSX
	GOYES	sxcon
gxcon	LC(2)	#E
	GOTO	docon
sxcon 	LC(2)  	#B
docon 	DAT0=C 	B
 	?ST=1  	sSX
 	GOYES  	sx2		jump to GX or SX routine

** display "Try to Recover Memory?" screen
gx2 	LC(5)  	G_RecoverRam?
 	GOSBVL 	G_XeqInPlace
 	GOTO 	wait4yes/no
sx2
 	LC(5)  	RecoverRam?
 	GOSBVL 	XeqInPlace

wait4yes/no                    *<---------------------------------------
 	LC(3) 	=allkeys	load entire keyboard			|
 	OUT=C								|
 	SHUTDN			Shut Down until key pressed		|
 	A=0   A								|
 	C=0   A								|
 	LA(2) #10		load [A] mask				|
 	LC(1) #2		activate OR1				|
 	GOSUB setkeys							|
 	?C=A  A			is [A] down?				|
 	GOYES yesdown							|
 	ASR   B			load [F] mask (#01)			|
 	LC(3) #100		activate OR8				|
 	GOSUB setkeys							|
 	?C=A  A			is [F] down?				|
 	GOYES nodown							|
 	LC(2) #C6							|
 	GOSBVL =RCKBp		do bad key beep				|
 	GOSUB wait4nokeys						|
 	GOTO wait4yes/no	--------------------------------------->

yesdown ?ST=1 sSX
 	GOYES sx3
 
** Display "Trying to Recover Ram" message
gx3	LC(5)  G_DoingRecRam
 	GOSBVL G_XeqInPlace
 	GOTO	skip2
sx3 	LC(5)  DoingRecRam
 	GOSBVL XeqInPlace

skip2 	LC(5) 8192*3		three second delay
 	GOSUB timing
 	LA(5) =TRUEFALSE
 	GOTO LEAVE

nodown 	GOSBVL ClearDisplay	clear display like "true" clear
 	LC(5)  8192		one second delay
 	GOSUB timing
 	LA(5) =FalseFalse
 	GOTO LEAVE

exitwkeys
 	LC(3) =allkeys		load entire keyboard
 	OUT=C			enable keys to enter buffer upon exit
 	LA(5)  =TrueTrue
 	GOTO LEAVE		exit

exit_after_on
 	LA(5)  =FALSETRUE
LEAVE 	ST=1   15		turn interrupts back on
 	GOSBVL =GPPushA
 	LA(5)  =TRUE
 	PC=(A)			return to sys-rpl shell

wait4nokeys                    *<---------------------------------------
 	LC(5) =allkeys		load entire keyboard			|
 	GOSUB setkeys							|
 	?C#0 A			any keys pressed?			|
 	GOYES wait4nokeys	yes, ---------------------------------->
 	RTN

** check if keys if buffer. if so, exit
anykeys?
 	GOSBVL =KeyInBuff?	check if key in buffer (carry will get set)
 	GOC    exitwkeys	yes, then exit
 	C=0    A
 	RTN

setkeys	OUT=C
 	GOSBVL =CINRTN
 	RTN

** timing routine that yields equal times on GX & SX
timing 	R1=C
 	GOSBVL =GetTimChk
 	R2=C
delay 	GOSBVL =GetTimChk
 	A=R2
 	P=     12
 	C=C-A  WP
 	A=R1
 	?A>=C  WP
 	GOYES  delay
 	P=     0
 	RTN
ENDCODE

* when the above code object exits, there will either be a 'FALSE' or
* a 'TRUE along with two other flags'.
  ITE					
  ::					(routine for normal keys)
    EVAL ITE 				(this splits the FLAGFLAG object)
    ::
      ITE 				(any key but [ON])
      ::
        GetKeyOb
        ERRSET	DoKeyOb
        ERRTRAP	SysErrorTrap
      ;
      ::				([ON] routine)
* the following code objects returns a flag with the state of the
* right-shift annunciator, to determine between [ATTN] and [OFF]
CODE					
	AD0EX
	D0=(5)	(=INHARDROM?)+14
	C=DAT0	B
	?CBIT=0	3
	GOYES	sx4
gx4	D0=(5)	G_ANNUNCIATORS
	GOTO	skip4
sx4	D0=(5)	ANNUNCIATORS
skip4	C=DAT0	B
	AD0EX
	?CBIT=1	5
	GOYES	annexit
annexit	GOVLNG	=PushT/FLoop
ENDCODE

          case	::  SetKeysNS  TurnOffKey ;	(routine to shut [OFF])
          InitEd&Modes 				(routine to do [ATTN])
          FLUSHKEYS
        ;
      ;
      ::				
        FLUSHKEYS			(take care of false-clear)
        %3  InitMenu%			(set MTH menu)
        FIFTYSIX  ClrSysFlag		(enable beeps)
        HOMEDIR				(set home directory)
        ' SetHiddenRes			(hide the home directory)
        Ob>Seco
        NULLID
        DUPDUP
        @ DROP
        TYPERRP?
        ITE_DROP
        PURGE
        CREATE
        InitEd&Modes			(do an ATTN)
        FLUSHKEYS		
        NOT IT				(do MEMORY CLEAR?)
        ::
          FIVE  JstGETTHEMSG  DISPROW1	(display MEMORY CLEAR message)
          BINT_91d  #578  setbeep	(do clear BEEP)
          SetDA1Temp
        ;
        DEPTH NDROP			(clear stack)
      ;
    ;
    ::					([ON]-[B] routine)
      NULLID				(restore home directory)
      SAFE@_HERE 
      NOT?SEMI
      TYPERRP?
      ?SEMI
      NULLID
      PURGE 
    ;
  AGAIN
;

[ RETURN TO DIRECTORY ]