                
                .LSTON
                .FIN
                
                .page
                                 
;=============================================================================
;  scctest routine:
;
; Puts a byte of test data (via store_testdata) from table to lap area in
; Z8 registers, calls tpack with receiver initialized and enabled, calls
; rpack which stores the byte plus crc in lap header area in Z8 regs, then
; compares resulting byte with table data (via comp_testdata) and sets appro-
; priate status and error bits in bus_stat1, 3, and 4.  These bits may also
; be set by tpack or rpack.  Any error will set ab_abort bit in bus_stat3.
;
;  INPUTS:      SCC chip enabled via bank select
;               SCC initialized
;               bus_stat1, 3, and 4 cleared
;
;  OUTPUTS:     sccdiag bit set in bus_stat1 during execution of scctest, 
;               cleared on exit.
;               test byte + crc bytes stored in lap area of Z8 regs.
;               bus_stat1, 3, 4 bits can be set as follows:
;               bus_stat1: 
;                         msg_sent   ($08)
;                         msg_rcvd   ($20)
;               bus_stat3:
;                         no_busidle ($40)
;                         scc_timout ($10)
;                         rorerr     ($08)
;                         ab_abort   ($80)
;               bus_stat4:
;                         bus_busy   ($80)
;                         rcv_timout ($40)
;                         typ_mismatch ($20)
;                         data_mismatch($08)
;                         scc_crcerr ($04)
;
;  Registers used:
;
;       r0      :loop counter and index into test data table
;       r1      :test data table pointer - lo byte
;       r2,r3   :scc chip register address and bank call address
;       r4      :used for temp storage                                  
;       r5      :same as r4
;       r6      :same as r4
;       r7      :not used                                                
;       r8,r9   :pointer to test data table.  r9 is computed from r1 + index
;       rA,rB   :pointer to id buffer in RAM: idbufhi,lo
;       rC      :temp storage
;       rD,rE,rF:lap header storage: their_node, our_node, lap_ctrl            
;
;       note:  r2,r3 defined as scc_chiphi,lo; rE,rF defined as xmtbufhi,lo
;              or rcvbufhi,lo; rC,rD defined as idbufhi,lo.  Also, xmtbufhi =
;              xmtbuf, etc.  
;
;=============================================================================

scctest:
                or       bus_stat1, #sccdiag  ;set diagnostic mode
                clr      !r0             ;set loop counter and index into tables

;set up to transmit byte
                ld      xmtbufhi,#.hibyte. sccxmtbuf ;starting RAM address
                ld      idbufhi,#.hibyte. sccidbuf   ;init idbuf pointer
                ld      !r1,#.lowbyte. scctest_table  ;pointer to test bytes
                ld      !r8,#.hibyte. scctest_table
                
testloop:
                clr     bus_stat3
                clr     bus_stat4
                and     bus_stat1, #$FF - msg_sent      ;clear error status bits

                ld      !r9,!r1         ;pass data pointer to store_testdata
                ld      !r2, #.hibyte. sccbank  ;restore r2 to scc address
                ld      !r3,#sw6adr     ;set up sccadrs for adrs recognition reg
                call    store_testdata     ;store the byte(s)

;set up for tpack and rpack - note bytecnt does not need setting; diag bit
;tells tpack to xmit one byte only

;clear receive status bits and enable receiver
                ld      !r2, #.hibyte. sccbank  ;restore r2 to scc address
                ld      !r3, #sw0cmd            ;point to cmd reg.
                ld      !r4, #erres
                lde     @!!scc_chip, !r4      ;clear rcv status bits in sts reg 1
                ld      !r3,#sw3rcv
                ld      !r4,#rcven
                lde     @!!scc_chip,!r4       ;enable receiver

;note that tpack enables xmtr for diag mode - can't enable it now because flags
;transmitted would clear sync/hunt bit and bus would never look idle to tpack 
;and it would never transmit.
                
                clr     boffhi
                ld      bofflo, #1      ;set backoff count for tpack = 400us
                call    tpack           ;transmit the packet
                tm      bus_stat1, #msg_sent    ;check for good completion sts
                jr      z, scc_fail
                ld      !r3, #sr0sts    ;set pointer since tpack used r3
                lde     !r4, @!!scc_sts0
                tm      !r4, #sync_hunt         ;check state of sync/hunt bit
                jr      z, scc_fail                 ;should be set after tpack
                
 ;receive the packet
                clr     exp_ctrl        ;clr exp value for ctrl byte - crc unk
                clr     rcvto_hi
                ld      rcvto_lo, #1    ;set timeout=200us
                call    rpack

                tm      bus_stat4, #typ_mismatch
                jr      z, scc_fail         ;typ_mismatch should be set:crc=lap_ctrl
                or      bus_stat3, bus_stat3
                jr      nz, scc_fail         ;check for timeout or overrun
                tm      bus_stat4, #rcv_timout + scc_crcerr
                jr      nz, scc_fail        ;check for crc err - rcv_timout should 
                                        ;be clear if typ_mismatch is set
                ld      !r9,!r1         ;pass table data pointer to comp_testdta
                call    comp_testdata      ;check for correct byte(s) received
                tm      bus_stat4, #data_mismatch
                jr      nz, scc_fail         ;check for compare error
                
                inc     !r0             ;bump loop counter and table index
                cp      !r0,#tlcnt      ;done with all passes (all test bytes)?
                jr      lt,testloop
stest_done:
                and     bus_stat1, #$FF-sccdiag  ;clear diagnostic bit
                ret
scc_fail:
                or      bus_stat3, #ab_abort
                jr      stest_done

                .page
                
;==============================================================================
; store_testdata routine
;
; Stores a byte of data at lap header area of Z8 regs and in the scc address
; recognition register.  !r0 is passed as index into a 4-byte table at 
; scctest_table.  r8r9 is a pointer to the table.  The four entries in the
; table are the test bytes and also the scc receive address.
;
;  scctest_table:  testbyt1   testbyt2   testbyt3   testbyt4
;
;  INPUTS:      r0 = loop counter and index into test table
;               r8,r9 = ptr to test table
;               r2,r3 = ptr to scc chip address recognition register
;
;  OUTPUTS:     testbyte stored in xmt buffer and scc address register
;
;  Register usage:
;
;       r0:     same as in scctest              r7:     not used                
;       r1:     lo byte of scctest_table ptr    r8,r9:  pointer to scctest_table
;       r2,r3:  scc chip address                rA,rB:  resrvd for idbufhi,lo     
;       r4   :  temp for testbyt                rC:     pointer to lap header
;       r6:     not used                        rD,rE,rF: lap header                
;
;       note:  r2,r3 defined as scc_chiphi,lo;                             
;              Also, scc_chiphi = scc_chip, etc
;
;==============================================================================

store_testdata:
                add     !r9,!r0         ;add loop index to pointer
                adc     !r8,#0
                ldc     !r4,@!!r8       ;get testbyt
                ld      !rC,#lap_ptr    ;set up pointer
                ld      @!rC, !r4         ;store testbyte in lap buffer
                
                lde     @!!scc_chip,!r4       ;set rcv address byte in scc
                ret
                
scctest_table:  .db     testbyt1,testbyt2,testbyt3,testbyt4

                .page

;============================================================================
;  comp_testdata routine
;
; Gets data just received from scc (in lap buffer), stores it in idbuffer
; for later viewing, and compares it with data from scctest_table.  
; Incorrect data value results in data_mismatch bit set in bus_stat4.

;  INPUTS:      receive data in lap receive buffer
;
;  OUTPUTS:     bus_stat4 bit, data_mismatch, set if incorrect data pattern.
; 
;  Registers:
;       
;       r0:     loop counter and index into tables
;       r1:     not used
;       r2,r3:  not used, reserved for scc chip address used by calling routine
;       r4   :  temp for testbyt
;       r5   :  not used
;       r6:     temp for received data from lap rcv buffer
;       r7:     not used         
;       r8,r9:  pointer to scctest_table
;       rA,rB:  idbufhi,lo
;       rC:     index into idbuf
;       rD,rE,rF: lap header storage
;
;=============================================================================
;
comp_testdata:
                ld      idbuflo,#.lowbyte. sccidbuf ;reset id buff ptr in RAM
                
                add     !r9,!r0         ;add loop index to table pointer
                adc     !r8,#0
                ldc     !r4,@!!r8       ;get current test byte from table
                ld      !r6,our_node   ;get destination byte
                ld      !rC,!r0         ;temp for loop index
                rl      !rC             ;x2 for ptr to idbuf
                add     idbuflo,!rC     ;add the index
                
                lde     @!!idbuf,!r6      ;move to idbuf
                cp      !r6, !r4        ;compare with table entry
                jr      z, gdret    
                or      bus_stat4, #data_mismatch  ;set error bit
gdret:
                ret

                .page

;===========================================================================
; sccmain - mainline code for scc interface
;
; General notes:
; Uses wrk_absys working register set plus bus_stat1, 3, 4 bytes to hold
; state and error information.  Ext_Push and Ext_Pop are used to save caller's
; context in diagnostic routine, so that only one working set is needed for
; the scc diagnostic.  
; 
; Extended timing is necessary to address the scc chip, so this mode is 
; enabled whenever in an scc routine.
;
;============================================================================

sccmain:
                srp     #wrk_absys
                clr     bus_stat1                        
                ld      P01m, #scc_P01m ;set extended timing for ext memory

;initialize scc and do scc self-test:
                ld      !r0, #1
                call    edscc           ;enable scc bank
                call    initscc         ;initialize scc chip registers
                call    scctest         ;do loopback test on scc
                ld      P01m, #wig_adrdata      ;restore non-extended timing
                ret

                .LSTOFF
