Discussion here:
viewtopic.php?p=76604#p76604
Code: Select all
; When we come here the first time after selection, NEW_KEY_FLAG was
TREATMENT: ; cleared in MENU_CASE_PRELUDE, and MENU_ITEM_STATE was cleared in
MOVF MENU_ITEM_STATE, W ; MENU_TASK case 0. If TREATMENT was already selected, then NEW_KEY_FLAG
CASE ; will remain set if a new keypress was made.
CASE_OF_ 5 ; Case 5 is for running the treatment.
GOTO TREATING ; (CALL, RETURN) I'm separating out this routine. Case 5 is first, to
END_OF_ ; reduce the number of instructions taken each time the task is called up
; after a treatment is actually started.
CASE_OF_ 0 ; Case 0 is for when we first arrive here from the main menu. Display
DISP_ROM_STR CLR, Sel_a_Rx_STR ; "Rx #1 (Use < > )" (but replace < and > with the arrow characters).
INCF MENU_ITEM_STATE, F ; Transition to state 1, offering the choice of Rx #1.
CLRF MENU_ITEM_STATE_L2
GOTO trm1 ; Go about 100 lines down, to test the validity of the Rx.
END_OF_ ; (The _ after the END_OF prevents wasting memory on a GOTO <END_CASE>.)
CASE_OF_ 6 ; Case 6 is for exiting, to time the "Exiting" message.
MOVF MENU_ITEM_STATE_L2, W
IF_ZERO ; This is kind of like a "CASE_OF 0", and, further down, "CASE_OF 1".
DISP_ROM_STR CLR, Exiting_STR ; Display, "Exiting".
CALL _1_SEC_DISP ; Put the current time plus one second in LCD_TARGET_TM.
INCF MENU_ITEM_STATE_L2, F
ELSE_
IF_FLAG_VAR NEW_KEY_FLAG, IS_CLEAR
CALL TM_2_LCD_TARGET_TM? ; How long left to see "Exiting"? Take current time minus LCD_TARGET_TM.
RETURN_IF_ACCb_NEG ; If it's negative, we must still give more time to see msg, so just exit.
END_IF
; If we've reached the target time, or if a key was pressed,
CLRF LCD_TARGET_TM ; make sure nothing else could think LCD_TARGET_TM is in use,
CLRF MENU_STATE ; set _main_ menu state to 0, (MENU_TASK will clear MENU_ITEM_STATE)
END_IF ; and proceed to clear key status and exit.
CLR_FLAG NEW_KEY_FLAG
RETURN
END_OF_ ; The _ at the end of END_OF_ eliminates the jump to END_CASE, since it was
END_CASE ; immediately preceded by an unconditonal RETURN, & END_CASE is next anyway.
; We're waiting for the 1st keypress to select a Rx.
RETURN_IF_FLAG_VAR NEW_KEY_FLAG, IS_CLEAR ; If no key was pressed (which is the usual situation), just exit.
CLR_FLAG NEW_KEY_FLAG ; A key has been pressed.
MOVF NEW_KEY, W ; We only watch for <--, -->, HOME, END, NO, and YES. Other keys ignored.
CASE
CASE_OF_ RAW_LEFT_KEY
DECF MENU_ITEM_STATE, F ; Decrement with left_arrow key, but
BTFSC STATUS, Z ; don't let it get below 1. If it did,
INCF MENU_ITEM_STATE, F ; put it back to 1.
END_OF
CASE_OF_ RAW_RIGHT_KEY
MOVF MENU_ITEM_STATE, W ; Check MENU_ITEM_STATE
SUBLW 4 ; against 4 (the max allowable).
BTFSS STATUS, Z ; If it's not already there,
INCF MENU_ITEM_STATE, F ; you can increment it.
END_OF
CASE_OF_ RAW_HOME_KEY
PUT 1, IN, MENU_ITEM_STATE
END_OF
CASE_OF_ RAW_END_KEY
PUT 4, IN, MENU_ITEM_STATE
END_OF
CASE_OF_ RAW_NO_KEY
PUT 6, IN, MENU_ITEM_STATE ; This gets trapped above, to time the "Exiting" message.
RETURN
END_OF_ ; The _ at the end of END_OF_ eliminates the jump to END_CASE, to save a
; program-memory word since there's an unconditional RETURN right before it.
CASE_OF_ RAW_YES_KEY
IF_FLAG_VAR Rx_VALID_FLAG, IS_SET ; If not valid Rx, YES key gets ignored. For checking, the decryp-
CALL INSTALL_DECRYPT_ARRAY ; tion was already done when the left or right arrow was pressed.
DISP_ROM_STR CLR, Treating_STR ; Display "Treating" briefly before asking for AGL.
CALL _4_SEC_DISP ; Tell it to display for 4 seconds before asking for initial AGL.
; (No delay loops, but it puts current time + 4 sec in LCD_TARGET_TM.)
CALL XFER_HI_TM_2_ACCb ; We'll ask for first AGL right away (but it will wait until the
MOVF ACCbLO, W ; "Treatment begun" message has shown for a few seconds first).
MOVWF NEXT_AGL_TM ; We'll forgo the macro usage here since we're copying the time
MOVWF TREATMENT_BEG_TM ; to two variables, and we can avoid re-loading bytes this way.
MOVF ACCbHI, W
MOVWF NEXT_AGL_TM+1
MOVWF TREATMENT_BEG_TM+1
_8V_UP ; Make the 8V pulse output high for 5 or 10ms. (DELAY's parameter is the
DELAY 1 ; number of ms if interrupts are off, with a 2ms resolution so input is
_8V_DN ; rounded up. Here, interrupts are on though, and I'm seeing about 7ms.)
CLRF AGL_IMG_TO_STORE ; (This will get changed 3 lines down to reflect Rx number.)
CALL SET_TREATMENT_BOUNDARY ; Store a fake AGL with Rx#=0 to mark the beginning of another treatment.
; Only the first byte of the fake AGL is significant; rest are random.
CLRF MENU_ITEM_STATE_L2
COPY MENU_ITEM_STATE, TO, AGL_IMG_TO_STORE ; Before overwriting MENU_ITEM_STATE, store Rx# for STORE_AGL.
PUT 5, IN, MENU_ITEM_STATE ; This will make the rest get handled (or re-routed) above. The "ELSE_"
END_IF ; would be that YES was pressed on an invalid Rx; but that does nothing,
RETURN ; so we don't have to specify. (With an unconditional RETURN right before the
END_OF_ ; END_OF, we can put the _ after END_OF to keep it from assembling GOTO END_CASE.)
RETURN ; All other keys are ignored.
END_CASE ; But if <--, -->, HOME, or END were pressed, we will continue here to display the
; Rx number, followed by either "Rx is invalid", "Rx is blank", or the Rx itself.
; Invalid ones won't be stored here, but a crook may try to store by different way.
< snip >Code: Select all
MIN
LDA 1,X
CMP 0,X
BCC .2
.1 LDA 0,X
.2 INX
RTS
MAX
LDA 1,X
CMP 0,X
BCC MIN.1
INX
RTS
Code: Select all
OUTSPACES.1
.1 JSR OUTSPACE
OUTSPACES
SEC
SBC #1
BCS .1
RTS
Code: Select all
_OUTSPACES
.1 JSR OUTSPACE
.2 SEC
SBC #1
BCS .1
RTS
OUTSPACES = _OUTSPACES.2
Code: Select all
{LDX #$00 : LOOP INX : CPX #$40 : BNE LOOP} // Count to 64Code: Select all
{LDX #$00 LOOP INX CPX #$40 BNE LOOP} // Count to 64Code: Select all
ORG $8000
START:
LDX #$00
.NEXTCHAR:
LDA HELLOTEXT,X
BEQ .DONE,2 ; search within 2 global labels
JSR $FFD2
INX
JMP .NEXTCHAR
HELLOTEXT:
.BYTE 'Hello World',0
.DONE:
RTS
Code: Select all
{LDX #$00 : LOOP INX : CPX #$40 : BNE LOOP} // Count to 64Code: Select all
{LDX #$00 LOOP INX CPX #$40 BNE LOOP} // Count to 64Code: Select all
CLC
LDA FOO ADC BAR STA FOO ; Add the low byte of a pair of 3-byte variables,
LDA FOO+1 ADC BAR+1 STA FOO+1 ; then the mid byte,
LDA FOO+2 ADC BAR+2 STA FOO+2 ; then the high byte.Code: Select all
rrc ! rrc ! rrc ! rrc ; Shift upper nybble to lower