                        **********************************************************************
                        *
                        *  OPTIONAL PROGRAM
                        *
                        **********************************************************************
                        *
                        ******************************************************************************
                        *                                                                            *
                        *       This is the MC146805F2 demo program.  It is a keyless entry system   *
                        *   that scans a matrix of keys for a set of eight numbers that forms a      *
                        *   code to enter or to change the entry code.  If after two wrong entries   *
                        *   an alarm will go off.  If after a peroid of time there is no response    *
                        *   to the system it will shut itself off using the 'F2' stop instruction    *
                        *                                                                            *
                        *                                                                            *
                        *                            BY MICHAEL G. GALLUP  AND VERNON GOLER          *
                        *                               9/09/81                                      *
                        *                                                                            *
                        ******************************************************************************
                        *
                        *
                        *This is the equate section
                        *
                        *
                        *
                        *
0343                                    org     $40
                        *
                        *
0040 00                 ctrl            fcb     0
0041                    code            rmb     8       entry code location
0049                    ncode           rmb     8       entered code location
0051                    veri            rmb     8       verify code location
0059 00                 tempx           fcb     0       temporary reg for x
005a 00                 temp            fcb     0       another temp reg
005b 00                 temp2           fcb     0       time counter (upper)
005c 00                 temp1           fcb     0       time counter (lower)
005d 00                 tempa1          fcb     0       time delay register
005e 00                 tempa           fcb     0
005f 00                 valid1          fcb     0
0060 00                 valid2          fcb     0
0061 00                 temp3           fcb     0
                        *
                        *
0062 00 00              blank           equ     $00     blank charater to lcd
0062 00 20              dash            equ     $20     dash
                        *
0062                                    org     $343
                        *
                        *          initialization goes here
                        *
0343 a6 f0              lock            lda     #$f0
0345 b7 04                              sta     porta+ddr
0347 3f 01                              clr     portb   clear portb
0349 3f 40                              clr     ctrl
034b 4f                                 clra
034c 43                                 coma            get ff
034d b7 05                              sta     portb+ddr       set portb ddr to output
034f cd 04 84           begin           jsr     clear
                        *
                        *
0352 8e                                 stop            stop processor and wait
0353 cd 04 84           bgin1           jsr     clear   clear dispaly
0356 9a                                 cli
                        *
                        *
                        * get number
                        *
0357 ae 49                              ldx     #ncode   get ram sorage spot
0359 ad 76                              bsr     get8    get 8 numbers
                        *
                        *     now that we have the eight digit number compare it to
                        *     the valid entry code and the change code.  If there is
                        *     no match increment alarm counter.
                        *
035b ae 08                              ldx     #$08    get count
035d e6 48              mor2            lda     ncode-1,x  get first/n number
035f e1 d0                              cmp     chg-1,x   is it the change code?
0361 26 05                              bne     morr    if z=0 not equal
0363 5a                                 decx            decrement counter
0364 26 f7                              bne     mor2    do more if no
0366 20 0a                              bra     veri1
                        *
                        *
0368 ae 41              morr            ldx     #code    get first location
036a cd 04 8d                           jsr     blcmp   compare them
036d 4c                                 inca            check for equal
036e 26 37                              bne     open    if not 0 then equal
0370 20 55                              bra     alarm1
                        *
                        *
                        *
                        *        change entry code section with verify
                        *
0372 cd 04 84           veri1           jsr     clear   clear display
0375 ae 49              veri2           ldx     #ncode   get ram location
0377 ad 58                              bsr     get8    get number
                        *
                        *
                        *       send the word verify here
                        *
0379 ae 08                              ldx     #$08    get counter
037b e6 b8              loop            lda     verify-1,x
037d cd 04 6c                           jsr     dsply
0380 5a                                 decx
0381 26 f8                              bne     loop
                        *
                        *
                        *
                        *
0383 ae 51                              ldx     #veri    get ram location
0385 ad 4a                              bsr     get8    get number
                        *
                        *       compare verify
                        *
0387 ae 49                              ldx    #ncode   get first number
0389 cd 04 8d                           jsr     blcmp   compare
038c 4c                                 inca            check for ff
038d 27 0c                              beq     cnt2    if zero then error
                        *
                        *   verify ok
                        *
                        *
                        *
                        *
                        *
                        *
038f ae 08                              ldx     #$08
0391 e6 50              mor6            lda     veri-1,x  get start of code
0393 e7 40                              sta     code-1,x  store it
0395 5a                                 decx
0396 26 f9                              bne     mor6    if not done do mor6
0398 cc 03 4f                           jmp     begin   goto start of program
                        *
                        *   if it gets here there has been a verify error
                        *   send the word error to the lcd
                        *
039b ae 08              cnt2            ldx     #$08    get counter
039d e6 c0              loop2           lda     error-1,x
039f cd 04 6c                           jsr     dsply
03a2 5a                                 decx
03a3 26 f8                              bne     loop2
03a5 20 ce                              bra     veri2
                        *
                        *   this is the open lock part
                        *
03a7 ae 08              open            ldx     #$08    get counter
03a9 e6 c8              loo3            lda     open1-1,x
03ab cd 04 6c                           jsr     dsply
03ae 5a                                 decx
03af 26 f8                              bne     loo3
                        *
03b1 0f 40 04                           brclr   7,ctrl,nxt       alarm bit set?
03b4 1f 40                              bclr    7,ctrl    reset if yes
03b6 15 01                              bclr    2,portb   clear alarm bit to outside
03b8 a6 f8              nxt             lda     #$f8
03ba b7 01                              sta     portb
                        *
                        *
                        *
                        *       loop for approx. 8 seconds
                        *
                        *
03bc ae ff                              ldx     #$ff    get count
03be cd 04 a1                           jsr     tmdly   delay
                        *
                        *
                        *     close lock
                        *
03c1 4f                                 clra
03c2 b7 01                              sta     portb
                        *
                        *
                        *
03c4 cc 03 4f                           jmp begin
                        *
                        *     This is the alarm spot
                        *
03c7 3c 40              alarm1          inc     ctrl    increment alarm counter
03c9 03 40 02                           brclr   1,ctrl,nxt2        check for alarm=2
03cc 14 01                              bset    2,portb   if alarm=2 then set bit
03ce cc 03 4f           nxt2            jmp     begin   goto start
                        *
                        *
                        *
                        * This is the subroutine get8
                        *
03d1 a6 08              get8            lda     #$08    get number count
03d3 b7 5c                              sta     temp1   save counter
03d5 a6 40              scan2           lda     #$40    get upper counter
03d7 b7 5b                              sta     temp2   save counter
03d9 a6 ff              scan1           lda     #$ff    get lower counter
03db b7 5a                              sta     temp    save counter
                        *
                        *
                        *
                        *********************************************************************
                        *       This subroutine scans a 4 x 3 matrix of keys and returns a  *
                        * value of 1-12 in the A accumulator if  it  finds  one  depressed, *
                        * otherwise  it returns a value of $FF if no key is depressed.  The *
                        * only register distroyed is the A accumulator all other  registers *
                        * are left alone.                                                   *
                        *********************************************************************
                        *
                        *
                        *
                        *
                        *
                        *
03dd 03 dd              scan            equ     *
03dd a6 40                              lda     #$40
03df b7 00                              sta     porta   select one column at a time
03e1 bf 59                              stx     tempx   save x register
03e3 ae 03                              ldx     #$03    count the column
                        *
                        *
                        *
03e5 b6 00              loopa           lda     porta   check if key pressed, one col at a time
03e7 a4 0f                              and     #$0f    clear upper nibble
03e9 26 23                              bne     debnce  branch if key pressed
03eb 34 00              nokey           lsr     porta   next column
03ed 5a                                 decx            decrement column count
03ee 26 f5                              bne     loopa   no key pressed
03f0 5a                                 decx            return x with $FF
                        *
                        *
                        *
03f1 9f                 exit            txa
03f2 be 59                              ldx     tempx
03f4 20 4d                              bra     ck
                        *
                        *
                        *
03f6 44                 found           lsra            shift if the row info 1 place
03f7 25 05                              bcs     check
03f9 5c                                 incx            add 3 for every row
03fa 5c                                 incx
03fb 5c                                 incx
03fc 20 f8                              bra     found
                        *
                        *
                        *
03fe a3 0a              check           cpx     #$0a
0400 25 ef                              blo     exit    number returned < 10
0402 a3 0b                              cpx     #$0b
0404 27 04                              beq     fix     input number is zero
0406 ae ff              inval           ldx     #$ff    invalid entry return $FF
0408 20 e7                              bra     exit
040a ae 00              fix             ldx     #$00    return 0 in x
040c 20 e3                              bra     exit
                        *
                        *
                        *
040e b7 5e              debnce          sta     tempa   save a register
0410 3f 5f                              clr     valid1
0412 3f 60                              clr     valid2
0414 44                 debnce1         lsra
0415 25 04                              bcs     onekey  check to make sure only one key pressed
0417 3c 5f                              inc     valid1
0419 20 f9                              bra     debnce1 continue check
041b a1 00              onekey          cmp     #$00    only one key pressed
041d 26 e7                              bne     inval   no, more than one key pressed
                        *
                        *
041f bf 61                              stx     temp3
0421 ae ff                              ldx     #$ff
0423 5a                 mor10           decx
0424 26 fd                              bne     mor10
0426 be 61                              ldx     temp3
                        *
0428 b6 00                              lda     porta   check to make sure orginal key pressed
042a a4 0f                              and     #$0f
042c 44                 rowck1          lsra
042d 25 04                              bcs     onekey1
042f 3c 60                              inc     valid2
0431 20 f9                              bra     rowck1
0433 b6 60              onekey1         lda     valid2
0435 b1 5f                              cmp     valid1  same key pressed
0437 26 cd                              bne     inval   no! same key not pressed
                        *
                        *
                        *
0439 b6 00              upkey           lda     porta   check to make   sure key has been relased
043b a4 0f                              and     #$0f
043d 26 fa                              bne     upkey   released? no
043f b6 5e                              lda     tempa   valid key press
0441 20 b3                              bra     found   calculate key number
                        
                        
                        
                        
                        
                        
                        
                        
                        *
                        *
                        *
0443 4c                 ck              inca            increment a z=1=nokey
0444 26 17                              bne     back    go back if not zero
0446 bf 59                              stx     tempx   save x
0448 ae 01                              ldx     #$01
044a ad 55                              bsr     tmdly   delay for 32ms
044c be 59                              ldx     tempx   get x
044e 3a 5a                              dec     temp    dec lower counter
0450 26 8b                              bne     scan    check for more keys
0452 3a 5b                              dec     temp2   dec upper counter
0454 26 83                              bne     scan1   check for more keys
                        *
                        *     clear disply here
                        *
0456 cd 04 84           bck             jsr     clear
0459 9c                                 rsp
045a cc 03 4f                           jmp     begin
045d 4a                 back            deca            adjust key number
045e f7                                 sta     ,x      save number
045f a6 20                              lda     #dash
0461 ad 09                              bsr     dsply
0463 5c                                 incx            inc pointer
0464 3a 5c                              dec     temp1   dec counter
0466 26 01                              bne     sc1     if not 8 get more
0468 81                                 rts             return
0469 cc 03 d5           sc1             jmp     scan2
                        *
                        *
                        *   This is the display subroutine
                        *
046c bf 59              dsply           stx     tempx   save x
046e ae 08                              ldx     #$08    get counter
0470 98                                 clc             clear carry
0471 48                 mor8            lsla            rotate to get bit
0472 25 04                              blo     one     one or a zero
0474 11 01                              bclr    0,portb send zero
0476 20 02                              bra     strb
0478 10 01              one             bset    0,portb send one
047a 12 01              strb            bset    1,portb send strobe
047c 13 01                              bclr    1,portb to enter data
047e 5a                                 decx            dec counter
047f 26 f0                              bne     mor8
0481 be 59                              ldx     tempx
0483 81                                 rts             return
                        *
0484 4f                 clear           clra
0485 ae 08                              ldx     #$08
0487 ad e3              loo             bsr     dsply
0489 5a                                 decx
048a 26 fb                              bne     loo
048c 81                                 rts
                        *
                        * this is the block compare routine
                        *
                        * x-contains the lower order location
                        * this routine assumes the the to eight
                        * digit numbers are next to each other
                        *
                        *
048d a6 08              blcmp           lda     #$08    get counter
048f b7 5d                              sta     tempa1  save counter
0491 f6                 mor1            lda     ,x      get it
0492 e1 08                              cmp     $08,x   compare
0494 26 08                              bne     rt      if no compare go back
0496 5c                                 incx
0497 3a 5d                              dec     tempa1  dec counter
0499 26 f6                              bne     mor1    if not done do more
049b 4f                                 clra            get all zeros
049c 20 02                              bra     rt1
049e 4f                 rt              clra
049f 43                                 coma            get all ones
04a0 81                 rt1             rts             return 00=equal ff=not equal
                        *
                        *
                        *
                        * this is the time delay routine
                        *
                        *
                        *    x contains the number of time outs that the
                        *    counter will go thru
                        *    one timeout=32 millisec.
                        *
04a1 b7 5d              tmdly           sta     tempa1  save acc.
04a3 a6 47              mor             lda     #$47    get timer control byte
04a5 b7 09                              sta     timer+1  store
04a7 a6 ff                              lda     #$ff    get all ones
04a9 b7 08                              sta     timer   store
04ab 0f 09 fd           here            brclr   7,timer+1,here     poll timer irq bit for timeout
04ae 5a                                 decx            dec counter
04af 26 f2                              bne     mor     if not done do more
04b1 81                                 rts             return
                        *
                        *
                        *
                        * this is the IRQ driver to get the hole thing started
                        *
                        *
                        *
04b2 9c                 int             rsp
04b3 9a                                 cli
04b4 cc 03 53                           jmp     bgin1
                        *
                        *
                        *
                        *
                        *   set up external interrupt vector here
                        *
                        *
                        *
                        *
                        *
                        *
                        **********************************************************************
                        *
                        *  VECTORS
                        *
                        **********************************************************************
04b7                            org    memsiz-10
07f6 03 53                      fdb    bgin1
07f8 03 53                      fdb    bgin1
07fa 04 b2                      fdb    int
07fc 01 79                      fdb    monit    swi
07fe 00 f8                      fdb    reset
                        ******************************************************************************
                        *
                        *       1 4 6 8 0 5 F 2   S E L F C H E C K
                        *
                        ******************************************************************************
                        *
                        *       THIS PROGRAM MODIFIED FROM THE ORIGINAL G2 SELFCHECK
                        *
                        ******************************************************************************
                        *
                        *       Selfcheck performs the following tests:
                        *
                        *         I/O           tests ports a(8 bits) and b(8 bits)
                        *         RAM           walking bit memory test (64 bits)
                        *         ROM           exclusive or with odd 1's parity result
                        *         timer         test prescaler,tcr,timer register
                        *         interrupts    int, and both timer interrupts
                        *         swi           service routine checks portc(4bits)
                        *
                        *       Two of the selfcheck subroutines can be called by a  user
                        *       program.   They  are  the  RAM  and ROM tests.  The timer
                        *       routine may also be called if  the  timer  input  is  the
                        *       internal  clock.   For  specific  calling  sequences  and
                        *       requirements see the header of each subroutine.
                        *
                        *       The instructions used in the selfcheck may at times  seem
                        *       devious. This is in fact true. An attempt was made to use
                        *       as  many  different  opcodes  and  addressing  modes   as
                        *       possible  as well as save bytes in any way possible.  For
                        *       example a 'cmp' where it doesn't matter what  happens  to
                        *       the  'A'  register  might  be replaced with a 'sub'. If a
                        *       substitution  is  especially  devious,   the   equivalent
                        *       instruction   will   be   included   in  the  comment  in
                        *       parentheses.
                        *
                        *                                          modified 9/10/81  MAU
                        *
                        ******************************************************************************
                        *
                        *
                        *            +5v +5v
                        *             |   |                                            +5v
                        *            +-+ +-+                                           |
                        *            |1| |1|                                          +-+
                        *            |0| |0|                                          |1|
                        *            |k| |k|   Selfcheck Pinout Configuration         |0|
                        *            +-+ +-+                                          |k|
                        *             |   |      +--------------------------+         +-+
                        *     +--+----+---|-----1| Reset                VDD |28-- +5V  |
                        *     |  |    +---|-----2| IRQ         M      TIMER |27--------+
                        *   | O _|_   |   +-----3| NUM         C        PC0 |26--+
                        *  [|   ---   | xtal----4| OSC1                 PC1 |25--|-+
                        *   | O  |    | xtal----5| OSC2        1        PC2 |24--|-|-+
                        *     |  |    +-----+---6| PA0         4        PC3 |23--|-|-|-+
                        *     +--+        +-|---7| PA1         6        PB0 |22--+-|-|-|
                        *     |         +-|-|---8| PA2         8        PB1 |21--|-+ | |
                        *   =====     +-+-|-|---9| PA3         0        PB2 |20--|-|-+ |
                        *    ===      | | | +--10| PA4         5        PB3 |19--|-|-|-+
                        *     =       | | +----11| PA5         F        PB4 |18--+-|-|-|---\
                        *             | +------12| PA6         2        PB5 |17----+-|-|--- | TEST STATUS
                        *             +--------13| PA7                  PB6 |16------+-|--- | INDICATION
                        *                  GND 14| VSS                  PB7 |15--------+---/
                        *                        +--------------------------+
                        
                        
                        
                        
                        *
                        ******************************************************************************
                        *
                        *               Approximate cycle times for selfcheck
                        *
                        *       Test             Cycle   Port  (bits 3-0) shows
                        *       ----             -----   ------------
                        *                            0   Tri-state
                        *
                        *       Port A,B,C
                        *
                        *       Timer
                        *
                        *       Ram
                        *
                        *       Rom
                        *
                        *       Interrupts
                        *
                        *       swi
                        *
                        *       swi
                        *
                        *
                        *
                        *                                     (selfcheck finished)
                        *                                     (back to cycle 30 in test)
                        *
                        ******************************************************************************
                        *
                        *       146805G2 I/O register definitions
                        *
                        *       (some are commented out for now, already defined in main program)
                        *
0800 00 40              ram     equ     $040    start of RAM
                        *
0800 00 40              loc     equ     $040  location to shift for interrupt test (setup by ram test)
0800 00 7c              stacka  equ     $07C    A when stacked by interrupt
0800 00 7d              stackx  equ     $07D    X when stacked by interrupt
                        *
0800                            org     $4b7            start of reserved ROM
                        *
                        ******************************************************************************
                        *
                        *       I/O test subroutine
                        *
                        *       Entered with X pointing to the port
                        *       to test. A has the DDR pattern to use.
                        *
                        *       Returns with A=$54 and C=1.
                        *
                        *       This routine should not be called by users since it
                        *       requires that the I/O is in the selfcheck configuration
                        *
                        *       A test of the data direction register has been added
                        *       since the ddr's are readable on CMOS versions of the 6805.
                        *
04b7 e7 04              iosub   sta     ddr,x   setup data direction
04b9 e1 04                      cmp     ddr,x   is it the same?
04bb 26 fe                      bne     *       ddr problem
04bd a6 55                      lda     #$55    alternate 1's and 0's
04bf f7                 again   sta     ,x      save it and see
04c0 f1                 iowait  cmp     ,x      if it stays there
04c1 26 fd                      bne     iowait  wait until values match
04c3 48                         lsla            shift pattern to $AA
04c4 2b f9                      bmi     again   and repeat test
04c6 81                 subout  rts
                        *
                        ******************************************************************************
                        *
                        *       Main selfcheck loop
                        *
                        *       Do not enter as a subroutine. To execute  this  test  the
                        *       6805  must  be  in  selfcheck mode. The selfcheck restart
                        *       vector points to location 'stest'.  If all  is
                        *       okay,  the low 4 bits of portb will cycle. If a failure
                        *       occurs the portd bits will  'stick'  with  a  pattern  in
                        *       them.  The significance of the pattern is:
                        *
                        *               flashing        okay
                        *               xxxx            dead part, port bad, or bad isp
                        *               0000-1001       dead part, port bad, or bad isp
                        *               1010            bad I/O
                        *               1011            bad timer
                        *               1100            bad RAM
                        *               1101            bad ROM
                        *               1110            bad interrupts
                        *
                        ******************************************************************************
                        *
                        *       Here on self check restart vector
                        *
04c7 04 c7              stest   equ     *
04c7 9c                         rsp             avoid self-check stack initialization problem
                        *
                        *       6805 selftest --- I/O ports test
                        *
                        *       test ports b then a.Ports a & b are left with the msn=input
                        *       & the lsn= output.Portb is the output indicator.
                        
                        *
04c8 ae 01                      ldx     #portb  test from portd to porta
04ca a6 f0              iotst2  lda     #$F0    select ddr for hi  nybble output
04cc ad e9                      bsr     iosub   do one test, retuns A=$54, C-bit=1
04ce a9 ba                      adc     #$BA    (lda #$0f) select ddr for lo  nybble output
04d0 ad e5                      bsr     iosub   do it again
04d2 5a                         decx            next do port a
04d3 2a f5                      bpl     iotst2
04d5 4f                         clra            set Z-bit
04d6 83                         swi             inc test counter & test portc
                        *
                        *       Check timer,RAM,ROM and interrupts
                        *
04d7 cd 07 be                   jsr     timtst  do timer test
04da 83                         swi             hang or increment
04db cd 07 8b                   jsr     ramtst  do RAM test
04de 83                         swi             hang or increment
04df cd 07 a4                   jsr     romtst  do ROM test
04e2 83                         swi             hang or increment
04e3 ad 05                      bsr     inttst  do interrupts test
04e5 83                         swi
04e6 83                         swi     inc portc msb to '0'
04e7 83                         swi     .
04e8 20 dd                      bra     stest   do it again
                        *
                        *
                        *       Interrupts test
                        *
                        *       Cause all three interrupts: INT, TIMER and TIMER-WAIT.
                        *       Also tests stop and wait instructions
                        *
                        *       The IRQ interrupt should be pending when the subroutine
                        *       is entered.  This will be true if the port A test ran successfully
                        *       since A0 is connected to the IRQ pin of the processor.  This
                        *       depends on the IRQ input being *EDGE* sensitive since A0 will
                        *       be left high during this test.
                        *
                        *       Also assumes that `loc' contains $01 which it will after the ram
                        *       test runs.
                        *
04ea 04 ea              inttst  equ     *
04ea 8e                         stop                    cause int (Clears I-bit)
04eb a6 88                      lda     #$88            force immediate timer interrupt
04ed b7 09                      sta     tcr
                        *
                        *       timer interrupt occurs here
                        *
04ef 8f                         wait                    enter wait state for next timer interrupt
                        *
                        *       timer interrupt while in wait happens here
                        *
04f0 9b                         sei                     no more interrupts
04f1 1c 09                      bset    6,tcr           disable timer interruts
04f3 0f 40 02                   brclr   7,loc,badint    missed some interrupts
04f6 4f                         clra                    set Z-bit (success status)
04f7 81                         rts
04f8 04 f8              badint  equ     *
04f8 a6 01                      lda     #1              clear Z-bit
04fa 81                         rts
                        ******************************************************************************
                        *
                        *       Software interrupt hangs if z=0; otherwise it
                        *       increments the low 4 bits of port B.
                        *
04fb 26 fe              soft    bne     *       hang if z=0
04fd cc 07 80                   jmp     soft2
                        *
                        ******************************************************************************
                        *
                        * zero fill unimplemented rom
                        *
                        ******************************************************************************
0500 00 00 00 00 00 00          bsz     $780-*
     00 00 00 00 00 00
     00 00 00 00 00 00
     00 00 00 00 00 00
     00 00 00 00 00 00
     00 00 00 00 00 00
     00 00 00 00 00 00
     00 00 00 00 00 00
     00 00 00 00 00 00
     00 00 00 00 00 00
     00 00 00 00
0780                            org     $780            second half of selfcheck area
                        ******************************************************************************
                        *       Software interrupt part 2
                        *       finish the job by incrementing the top 4 bits of port B
                        *
0780 07 80              soft2   equ *
0780 3c 01                      inc     portb
0782 b6 01                      lda     portb
0784 aa f0                      ora     #$f0            set upper nibble
0786 b1 02                      cmp     portc           .
0788 26 fe                      bne     *               fail portc
078a 80                         rti
                        ******************************************************************************
                        *
                        *       RAM Self-Check subroutine
                        *
                        *       Returns with the z-bit clear if any  error  is  detected;
                        *       otherwise the z-bit is set.
                        *
                        *       The RAM test must be called with  the  stack  pointer  at
                        *       $7F.  When run, the test checks every RAM cell except for
                        *       $7F and $7E which  are  assumed  to  contain  the  return
                        *       address.
                        *
                        *       This  test  must  be  entered  with  A=0.   When  running
                        *       selfcheck,  a  successful  timer  test  will leave A with
                        *       zero. Remember,the a reg is stacked during the swi service
                        *       routine.
                        *
                        *       A and X are modified. Obviously, all ram locations except
                        *       the top 2 are modified.
                        *
                        *       Initial ram pattern:
                        *
                        *       C Data  RAM address
                        *       1 00    7d 74 6b 62 59 50 47
                        *       0 80    7c 73 6a 61 58 4f 46
                        *       0 40    7b 72 69 60 57 4e 45
                        *       0 20    7a 71 68 5f 56 4d 44
                        *       0 10    79 70 67 5e 55 4c 43
                        *       0 08    78 6f 66 5d 54 4b 42
                        *       0 04    77 6e 65 5c 53 4a 41
                        *       0 02    76 6d 64 5b 52 49 40
                        *       0 01    75 6c 63 5a 51 48
                        *
                        *       The seed for pass 2 is 0 0000 0001
                        *       The seed for pass 3 is 0 0000 0010
                        *       The seed for pass 4 is 0 0000 0100
                        *       The seed for pass 5 is 0 0000 1000
                        *       The seed for pass 6 is 0 0001 0000
                        *       The seed for pass 7 is 0 0010 0000
                        *       The seed for pass 8 is 0 0100 0000
                        *       The seed for pass 9 is 0 1000 0000
                        *       The seed for test end  1 0000 0000
                        *
                        *
078b 00 3e              NBYTES  equ     62      number of bytes tested
                        *
078b 07 8b              ramtst  equ     *
078b 99                         sec     F2PAT.ASM Downloaded at  5:36 PM using X 48890             en     ldx     #NBYTES
078e e7 3f              gen2    sta     ram-1,x fill memory with walking bit
0790 46                         rora
0791 5a                         decx
0792 26 fa                      bne     gen2
0794 46                         rora            return same seed for verification loop
0795 ae 3e                      ldx     #NBYTES
0797 e8 3f              verf    eor     ram-1,x see if ram is okay
0799 26 08                      bne     quit    return with z-bit clear
079b ea 3f                      ora     ram-1,x (lda) restore seed without changing C-bit
079d 46                         rora
079e 5a                         decx
079f 26 f6                      bne     verf
07a1 24 e9                      bcc     gen     next pattern
07a3 81                 quit    rts
                        *
                        *       ROM checksum subroutine
                        *
                        *       Returns with  z-bit  cleared  if  any  error  was  found;
                        *       otherwise z=1.
                        *
                        *       X=0 on return, and A should be zero if the test passed.
                        *       Memory locations 'romsub' to 'romsub+3' are overwritten.
                        *
07a4 00 41              romsub  equ     $041    free area in on-chip ram (next to `loc')
                        *
                        *
07a4 07 a4              romtst  equ     *
                        *
                        *       first, build a subroutine in ram (at romsub)
                        *
07a4 ae d8                      ldx     #$D8    =EOR 2 byte indexed
07a6 bf 41                      stx     romsub
07a8 3f 42                      clr     romsub+1 set initial offset = 0000
07aa 3f 43                      clr     romsub+2
07ac ae 81                      ldx     #$81    $81=RTS
07ae bf 44                      stx     romsub+3
07b0 5a                         decx            X = $80 = start of rom on page zero
                        *
07b1 4f                         clra            zero out the checksum at start
                        *
07b2 bd 41              sum     jsr     romsub  combine in next byte of rom
07b4 5c                         incx            go to next rom address
07b5 26 fb                      bne     sum
07b7 3c 42                      inc     romsub+1 bump high byte of address
07b9 07 42 f6                   brclr   3,romsub+1,sum  continue till top of rom
07bc 43                         coma            sets z-bit if result was $FF
07bd 81                         rts
                        *
                        ******************************************************************************
                        *
                        *       Timer Test
                        *
                        *       Tests the prescaler and timer register.
                        *
                        *       The algorithm is to setup the  timer  and  prescaler  for
                        *       maximum  count values and start the clock to run from the
                        *       processor clock.  The loop then reads the timer every 128
                        *       cycles and watches it change.
                        *
                        *       Returns with  z-bit  cleared  if  any  error  was  found;
                        *       otherwise z=1.
                        *
                        *       A and X registers are destroyed
                        *
                        *       When successful, timtst will exit with  A=0.   This  side
                        *       effect will be used in the RAM test.
                        *
07be 07 be              timtst  equ     *
07be a6 6f                      lda     #%01101111      stop the clock
07c0 b7 09                      sta     tcr
07c2 ae ff                      ldx     #$FF
07c4 bf 08                      stx     timer           init timer data register
07c6 a6 5f                      lda     #%01011111      no ints,gated clock,div by 128,clear prescaler
07c8 b7 09                      sta     tcr
07ca 07 ca              ttloop  equ     *
07ca b3 08                      cmpx    timer           (3) do values agree?
07cc 26 0f                      bne     timxit          (3) no, quit with an error
07ce 5a                         decx                    (3)
07cf a3 ff                      cmpx    #$FF            (2) done all values?
07d1 27 0a                      beq     timxit          (3) yes, exit with Z=1 (successful)
07d3 a6 11                      lda     #17             (2)
07d5 07 d5              twait   equ     *
07d5 4a                         deca                    (3) 6*17=102 cycles
07d6 26 fd                      bne     twait           (3)
                        *
07d8 3f 0a                      clr     $000A           (5) safe 5 cycle nop
07da 9d                         nop                     (2)
07db 20 ed                      bra     ttloop          (3) try next value
07dd 81                 timxit  rts                     exit with Z indicating result of test
                        *
                        *
                        ******************************************************************************
                        *
                        *       Interrupt Routines
                        *
                        *
                        *       `exit wait' interrupt shifts loc by 4
                        *
07de 07 de              scwait  equ     *       exit from timer wait state
07de 38 40                      asl     loc
07e0 38 40                      asl     loc
                        *
                        *       `timer' interrupt shifts loc by 2
                        *
07e2 07 e2              timint  equ     *
07e2 38 40                      asl     loc     shift loc again
07e4 20 0a                      bra     patch   go around vectors
                        *
                        ******************************************************************************
                        *
                        *       C h e c k s u m   a n d   V e c t o r s
                        *
07e6                            org     $7e6
                        *
07e6 07 de                      fdb     scwait  exit wait via timer
07e8 07 e2                      fdb     timint  timer interrupt (non wait exit)
07ea 07 f2                      fdb     intr    int
07ec 04 fb                      fdb     soft    software int
07ee 04 c7                      fdb     stest   selfcheck start
07f0 1f 09              patch   bclr    7,tcr   acknowledge this interrupt
                        *
                        *       `int' interrupt shifts loc by 1
                        *
07f2 07 f2              intr    equ     *
07f2 38 40                      asl     loc     IRQ cleared by taking the interrupt
07f4 80                         rti
                        *
07f5 37                 chksum  fcb     $37             ROM checksum (odd 1's parity)
                        *
                        *
                        *       End of Selfcheck
                        *
                        ******************************************************************************
07f6                    end
                        
                        *
