Skip to main content
Home Documents Lisa Lisa Boot ROM RM248.S.TEXT
Lisa Boot ROM RM248.S.TEXT

Lisa Boot ROM RM248.S.TEXT

Lisa · TEXT
FilenameLisa_Boot_ROM_RM248.S.TEXT
Size0.07 MB
Subsection firmware
Downloads2
Enjoying MacTrove? Anonymous downloads are free and unlimited. Create a free account to track favorites, contribute metadata corrections, and join the community chat.
Contents
.PAGE
;----------------------------------------------------------------------------
;  VIDEO CIRCUITRY TEST
;  The following test checks the vertical retrace signal of the
;  video circuitry to verify it is toggling.
;  Register usage:
;       D0 = timeout count      A0 = unused
;       D1 = unused	        A1 = unused
;       D2 = bit pointer        A2 = unused
;       D3 = unused	        A3 = address to disable VTIR
;       D4 = unused	        A4 = address to enable VTIR
;       D5 = unused	        A5 = address of bus status register
;----------------------------------------------------------------------------

VIDTST
        .IF     ROM4K = 0

        .IF  USERINT = 1
        BSR     MAKETEST        ;display test icons
        MOVEA   #CPUSTRT,A1     ;hilite CPU board icon
        BSR     INVICON
        .ENDC
VIDCHK
        MOVEA.L #VTIRDIS,A3     ;ADDRESS FOR DISABLING VTIR
        MOVEA.L #VTIRENB,A4     ;ADDRESS FOR VTIR ENABLE
        MOVEA.L #STATREG,A5     ;STATUS REGISTER LOCATION FOR BYTE OPS

        MOVE    #$0DF4,D0       ;SET TIMEOUT COUNT FOR ABOUT 20 MS
        MOVEQ   #VRBIT,D2       ;VR BIT LOCATION

        TST     (A3)	        ;RESET THEN
        TST     (A4)	        ; ENABLE VTIR
@1      BTST    D2,(A5)	        ;WAIT FOR LOW
        BEQ.S   @2	        ;EXIT IF YES
        DBF     D0,@1	        ;ELSE LOOP (ABOUT 5.6 MS PER LOOP)
        BRA.S   VIDERR	        ;AND SET ERROR IF TIMEOUT

@2      TST     (A3)	        ;RESET VTIR
        TST     (A4)	        ;THEN RENABLE
        BTST    D2,(A5)	        ;SHOULD BE HIGH BY NOW
        BEQ.S   VIDERR	        ;GO TO ERROR EXIT IF NOT
        TST     (A3)	        ;DISABLE VTIR
        BRA.S   VIDXIT	        ;and go to exit

;  Error exit

VIDERR  BSET    #VID,D7	        ;SET ERROR INDICATOR
        TST.L   D7	        ;in loop mode?
        BMI.S   VIDCHK	        ;restart test if yes
        BRA     TSTCHK	        ;else go to error msg routine

;  Normal exit

VIDXIT

;----------------------------------------------------------------------------
;  Now, try reading of system serial number
;----------------------------------------------------------------------------

        MOVEA   #SERNUM,A0      ;ptr for save of serial #
        BSR.S   RDSERN	        ;go do read
        BCC.S   VIDERR	        ;exit if error
        TST     VTIRDIS	        ;else disable vertical retrace
        TST.L   D7	        ;check for loop mode
        BMI.S   VIDCHK	        ;if not, fall thru to next test
        BRA     PARTST	        ;and go on to next test

        .PAGE
;--------------------------------------------------------------------------
;
;  Routine to read system serial # from video prom.
;  Written by Ken Schmal and Ron Hochsprung.
;
;       Register Usage:
;
;       temporary and iterative			 D0
;       temporary and iterative			 D1
;       temporary and iterative			 D2
;       temporary and iterative			 D3
;       boolean FOUND to be returned		 D4
;       pointer to save area for serial #	 A0
;       SN1 & SN2 pointer			 A1
;       STATUS REGISTER pointer			 A2
;       SCRACH array pointer			 A3
;       SCRACH END pointer			 A4
;       Tag const				 A5
;       static link and stack frame
;	  base pointer register			 A6
;
;  Returns with carry bit set if all OK.
;  All registers except D7 and A0 trashed.
;
;--------------------------------------------------------------------------

RDSERN

        MOVEM.L	        D7/A0,-(SP)	        ;save regs

;       turn off all interrupts

        move	        SR, -(sp)	        ;save the present status register
        ori.w	        #$0700, SR	        ;set interrupt to level 7

;--------------------------------------------------------------------------
;       now set up registers for the algorithm
;--------------------------------------------------------------------------

        move.l	        #Snum, a1	        ;location in MMU of SN1 & SN2
        move.l	        #Statreg,a2	        ;Status Register pointer
        link	        a6, #dStack	        ;make room for SCRACH
        lea	        dScrach(a6), a3	        ;get pointer for SCRACH
        lea	        Tag,a4
        move.l	        a0,dSavArry(a6)

;--------------------------------------------------------------------------
;       first we get the block out of the vertical half
;--------------------------------------------------------------------------
;
;       sync up to the vertical retrace bit
;

GetBits1:

        moveq	        #2, d1		        ;vertical retrace is bit #2
        move.l	        #BytesPerRead,dLcnt(a6) ;read this many bytes
        clr	        VTIRDIS		        ;clear vertical retrace bit
        clr	        VTIRENB		        ;set vertical retrace interrupt
@1:     btst	        d1, (a2)	        ;wait until it's true
        bne.s	        @1

;
;------ read the first block ------
;

@3:     movem	        (a1), d0-d7
        movem	        d0-d7, (a3)
        addq.l	        #8, a3
        addq.l	        #8, a3
        nop
        moveq	        #dlycnst-1, d0
        subq.l	        #1, dLcnt(a6)
@4:     dble	        d0, @4
        bgt.s	        @3

;--------------------------------------------------------------------------
;       then we get the block out of the horizontal half
;--------------------------------------------------------------------------
;
;       kill time until we're near the last vertical retrace line
;

GetBits2:

        move.l	        #BytesPerRead, dLcnt(a6);get the last few bytes
        move.w	        #TKiller-1, d0	        ;time killer constant
@1:     dbra	        d0, @1		        ;loop

;
;------ read the second or last block ------
;

@2:     movem	        (a1), d0-d7
        movem	        d0-d7, (a3)
        addq.l	        #8, a3
        addq.l	        #8, a3
        nop
        moveq	        #dlycnst-1, d0
        subq.l	        #1, dLcnt(a6)
@3:     dble	        d0, @3
        bgt.s	        @2

;--------------------------------------------------------------------------
;       now we have to find sync bytes and extract the bit stream
;--------------------------------------------------------------------------

        clr	        VTIRDIS		        ;turn off vertical retrace
        moveq	        #1, d4		        ;initialize FOUND to true

GetBytes:
        lea	        dScrach(a6), a3	        ;pointer to 1/2 Scrach Array pointer
        move.l	        a3, a4
        adda	        #HalfSize, a4	        ;pointer to end of 1/2 Scrach Array     RM000
;
;       find the first sync byte
;
        bsr	        FindSync
        tst.w	        d4
        beq.s	        Exit		        ;exit if no sync byte found
;
;       now pull out the first block from the bit stream
;
        bsr	        GetNibbles
;
;       here we look for the second sync byte.
;
        lea	        dScrach(a6), a3
        adda	        #HalfSize, a3	        ;pointer to 2/2 Scrach Array pointer    RM000
        move.l	        a3,a4
        adda	        #HalfSize,a4	        ;pointer to end of 2/2 Scrach Array     RM000
;
        bsr	        FindSync
        tst.w	        d4
        beq.s	        Exit		        ;again, exit if no sync byte found
;
;       now pull out second block from the bit stream
;
        bsr	        GetNibbles

;----------------------------------------------------------------------
;       Check the checksum of the read data
;----------------------------------------------------------------------

CheckSum:
        move.l	        dSavArry(a6),a0
        clr.w	        d0

        move.b	        24(a0),d0
        move.w	        #100,d2
        mulu	        d2,d0

        move.b	        25(a0),d1
        move.w	        #10,d2
        mulu	        d2,d1
        add.w	        d1,d0

        move.b	        26(a0),d1
        add.w	        d1,d0

        clr.w	        d1
        clr.w	        d2
        clr.w	        d3
@2:     move.b	        0(a0,d1),d3
        add.w	        d3,d2
        addq.w	        #1,d1
        cmpi.w	        #24,d1
        bne.s	        @2

        move.b	        27(a0), d3
        add.w	        d3,d2
        subi.w	        #4 * $F, d2
        cmp.w	        d0,d2
        beq.s	        @3
        clr.w	        d4
@3:

;---------------------------------------------------------------------------
;       job well done, lets go home
;---------------------------------------------------------------------------

Exit:
        unlk	        a6
        move	        (sp)+, SR	        ;restore status reg
        MOVEM.L	        (SP)+,D7/A0	        ;and regs
        clr	        VTIRENB		        ;re-enable interrupts
        LSR	        #1,D4		        ;shift to set/reset error indicator
@1      RTS				        ; and exit

        .PAGE
;---------------------------------------------------------------------------
;       subroutine to find a sync byte
;---------------------------------------------------------------------------

FindSync:
        clr.l	        d0
        moveq	        #2, d1		        ;two passes to find the sync byte
@1:     move.w	        (a3)+, d2	        ;
        lsl.w	        #1, d2		        ;
        roxl.b	        #1, d0		        ;get SN1
        cmpa.l	        a3, a4		        ;assure the buffer's circular
        bne.s	        @2		        ;
        adda.l	        #-HalfSize, a3	        ;if it's at the end then
        subq	        #1, d1		        ; check if it's the second try
        beq.s	        @3		        ; and exit if so
@2:     cmpi.b	        #$0ff, d0	        ;test here if it's a sync byte
        bne.s	        @1		        ;no: loop again
        lsl.w	        #4, d0		        ;yes: adjust the byte
        lsr.b	        #4, d0		        ;
        move.w	        d0, (a0)+	        ;save it
        rts				        ;and return

@3:     clr.w	        d4		        ;uh, oh. No sync byte.
        rts				        ;clear FOUND and return

;--------------------------------------------------------------------------
;       subroutine to pull out a 14 nibble block from the bit stream
;--------------------------------------------------------------------------

GetNibbles:
        moveq	        #BytesPerRead-1, d2     ;
@1:     moveq	        #8, d1		        ;8 bits/byte
        clr.l	        d0		        ;
@2:     lsl	        (a3)+		        ;get SN1 in the next scrach word
        roxl.b	        #1, d0		        ;shift it into the save buffer
        cmpa.l	        a3, a4		        ;assure a circular bufer
        bne.s	        @3		        ;
        adda.l	        #-HalfSize, a3	        ;
@3      subq	        #1, d1		        ;decrement bit/byte counter
        bne.s	        @2		        ;loop again if still in byte
        lsl.w	        #4, d0		        ;separate the nibbles
        lsr.b	        #4, d0		        ;
        move	        d0, (a0)+	        ;save these nibbles
        subq	        #1, d2		        ;decrement byte/SN counter
        bne.s	        @1		        ;loop again if still more to go
        rts

Tag     .word	        $4b41,$5300


        .PAGE
;----------------------------------------------------------------------------
;  PARITY CIRCUITRY TEST
;  The purpose of this test is to verify the operation of the parity checking
;  logic by forcing a parity error and ensuring it is caught.
;  Register usage:
;       D0 = pattern written	        A0 = logical address used for test
;       D1 = read results	        A1 = corresponding physical address
;       D2 = NMI indicator	        A2 = save for NMI vector
;       D3 = save of memory contents    A3 = scratch
;       D4 = save of error addr latch   A4 = unused
;       D5 = unused		        A5 = address of bus status register
;       D6 = unused		        A6 = unused
;----------------------------------------------------------------------------

PARTST
        .ENDC
        .IF  ROM16K = 1

        MOVE.L  NMIVCT,A2       ;SAVE STANDARD NMI VECTOR
        LEA     WWPERR,A3       ;THEN SET UP NEW PARITY ERROR (NMI) VECTOR
        MOVE.L  A3,NMIVCT
        MOVEA.L #STATREG,A5     ;setup status reg ptr for byte ops
        TST.B   PAROFF	        ;disable parity initially
        CLR.L   D2	        ;clear regs for result use
        CLR.L   D4
        MOVE    #$01FF,D0       ;SET UP PATTERN FOR WRITE
        MOVEA   #$300,A0        ;SET UP ADDRESS FOR USE (in already verified mem)       RM000
        MOVE    (A0),D3	        ;SAVE ITS CONTENTS
        MOVEA.L A0,A1	        ;COMPUTE CORRESPONDING
        ADDA.L  MINMEM,A1       ; PHYSICAL ADDRESS

        TST.B   DG2ON	        ;ENABLE WRITE WRONG PARITY FUNCTION
        MOVE    D0,(A0)	        ;DO WRITE TO CREATE BAD PARITY
        TST.B   DG2OFF	        ;DISABLE WWP

        TST.B   PARON	        ;ENABLE PARITY ERROR DETECTION
        TST     D2	        ;SHOULDN'T HAVE INTERRUPT YET
        BNE.S   PARERR	        ;EXIT IF ERROR

        MOVE    (A0),D1	        ;DO READ - PARITY ERROR SHOULD OCCUR
        NOP		        ;GIVE A LITTLE EXTRA TIME
        TST     D2	        ;NMI RECEIVED?
        BEQ.S   PARERR	        ;ERROR IF NO

;  Check that parity error and failing address correctly caught

        BTST    #PBIT,(A5)      ;PARITY ERROR BIT SET?
        BNE.S   PARERR	        ;EXIT IF NOT
        MOVE    MEALTCH,D4      ;GET ERROR ADDRESS
        TST.B   PAROFF	        ;disable parity to clear error bit
        LSL.L   #5,D4	        ;NORMALIZE THE ADDRESS
        CMPA.L  D4,A1	        ;SAME ADDRESS AS WRITTEN TO?
        BNE.S   PARERR	        ;EXIT IF ERROR
        MOVE.L  A2,NMIVCT       ;ELSE RESTORE NMI VECTOR
        CLR     D0
        NOT     D0
        MOVE    D0,(A0)	        ;"clear" bad parity
        TST.B   PARON	        ;reenable parity
        BRA.S   PARXIT	        ;and skip to exit

;  Error exit

PARERR  BSET    #PAR,D7	        ;SET INDICATOR
        TST.L   D7	        ;in loop mode?
        BMI.S   PARTST	        ;restart if yes
        TST.B   PAROFF	        ;else ensure parity disabled
        MOVE.L  A2,NMIVCT       ;RESTORE NMI VECTOR
        BRA     TSTCHK	        ;AND ABORT FURTHER TESTING

;  Normal exit

PARXIT  TST.L   D7	        ;check for loop mode
        BMI.S   PARTST	        ;restart test if yes
        BSR     CHKCPU	        ;place check over CPU (all tests OK)
        BRA.S   MEMTST2	        ;else go do memory test

;  NMI routine for parity error checking

WWPERR  MOVEQ   #1,D2	        ;SET INDICATOR
        RTE		        ;AND RETURN

;------------------------------------------------------------------------
;  Bus error handler for VIA #1 use
;------------------------------------------------------------------------

VIA1VCT MOVEQ   #EVIA1,D0       ;SET ERROR CODE
        BSET    #VIA1,D7        ;set indicator
        BRA     IOVCT	        ;AND GO HANDLE I/O EXCEPTION

        .ENDC		        ;(ROM16K)
        .PAGE
;-------------------------------------------------------------------------
;  Now do full memory test with and without parity enabled.  If parameter
;  memory bit set for extended memory testing, memory tests executed in
;  twice.  If warm-start, execute only one pass with parity enabled.
;  Uses registers:
;       A0 = starting address to test   D0 = used to consolidate test results
;       A1 = ending address to test     D1 = scratch
;       A2 = unused		        D2 = address increment
;       A3 = save address for results   D3 = test results for each 128K
;       A4 = return address	        D4 = max test address
;       A5 = unused		        D5 = pass count
;-------------------------------------------------------------------------

MEMTST2
        .IF  ROM4K = 0

        .IF  USERINT = 1
        MOVEA   #MEMSTRT,A1     ;hilite memory board test icon
        BSR     INVICON
        .ENDC

        BSR     SETBUSVCT       ;restore normal bus error vector	        RM000
MEMLOOP
        LEA     PRTYINT1,A1     ;setup up vector for parity intrpt	        CHG015
        MOVE.L  A1,NMIVCT       ;					        CHG015

        .IF  ROM16K = 1
;  First check if this is a warm-start					        CHG006

        BTST    #WRMSTRT,D7     ;warm-start?				        CHG006
        BEQ.S   @0	        ;skip if not				        CHG015
        MOVEQ   #1,D5	        ;else set count for one pass		        CHG015
        BRA.S   @3	        ;skip to do it				        CHG015

;  Next check parameter memory to see if extended testing desired

@0      BSR     CHKPM	        ;go check parameter memory
        BCS.S   @1	        ;skip if not valid to do only one pass
        BTST    #6,MEMCODE      ;else check extended memory test indicator
        BEQ.S   @1	        ;exit if not set

        MOVEQ   #2,D5	        ;run two passes for extended mode	        CHG015
        BRA.S   @2	        ;go do it				        CHG015
@1      MOVEQ   #1,D5	        ;run one pass for normal mode		        CHG015

;  Run the memory tests

@2      TST.B   PAROFF	        ;first run with parity off		        CHG015
        BSR.S   RUNTESTS        ;run test pass				        CHG015
        BNE.S   TSTDONE	        ;skip if error				        CHG015
@3      TST.B   PARON	        ;then run pass with parity on		        CHG015
        BSR.S   RUNTESTS        ;run test pass				        CHG015
        BNE.S   TSTDONE	        ;exit if error				        CHG015
        SUBQ    #1,D5	        ;decr pass count			        CHG015
        BNE.S   @2	        ;continue testing until done		        CHG015

TSTDONE TST.L   D7	        ;in loop mode?
        BMI.S   MEMLOOP	        ;restart if yes
        BTST    #MEM,D7	        ;memory error?
        BNE     TSTCHK	        ;abort if yes
        BSR     CHKMBRD	        ;else signal memory OK
        LEA     NMI,A3	        ;restore NMI vector			        CHG015
        MOVE.L  A3,NMIVCT       ;					        CHG015
        BRA     IOTST	        ;go on to next test


;-----------------------------------------------------------------------
;  Subroutine to run the memory tests - saves results as test proceeds
;  Zero condition code bit set if no errors.
;-----------------------------------------------------------------------

RUNTESTS

;  Do the basic test

BASICTST
        BSR.S   TSTINIT	        ;init for new test
CALL3
        BSR4    RAMTEST
        BEQ.S   @1	        ;skip if no errors
        BSET    #MEM,D7	        ;else set error indicator
@1      BSR.S   SAVRSLT	        ;save results
        BNE.S   CALL3	        ;loop until done			        CHG021
        BTST    #MEM,D7	        ;set condition code			        CHG015
        RTS		        ;and exit

        .ELSE

        TST.B   PARON	        ;enable parity...

;  Do the basic test

BASICTST
        BSR.S   TSTINIT	        ;init for new test
CALL3
        BSR4    RAMTEST
        BEQ.S   @1	        ;skip if no errors
        BSET    #MEM,D7	        ;else set error indicator
@1      BSR.S   SAVRSLT	        ;save results
        BCC.S   CALL3	        ;and loop until done

TSTDONE LEA     NMI,A3	        ;restore normal NMI vector
        MOVE.L  A3,NMIVCT
        TST.L   D7	        ;in loop mode?
        BMI.S   MEMLOOP	        ;restart if yes
        BTST    #MEM,D7	        ;memory error?
        BNE     TSTCHK	        ;abort if yes
        BRA     IOTST	        ;else go on to next test

        .ENDC		        ;{ROM16K}

        .PAGE
;----------------------------------------------------------------------
;  Subroutine to do initialization for memory tests
;----------------------------------------------------------------------

TSTINIT
        MOVEQ   #2,D2	        ;test in 128K increments		        RM000
        SWAP    D2	        ; (sets D2 = $20000)			        RM000
        MOVE.L  SCRNBASE,D4     ;get max test address (base of screen)
        MOVEA   #LOMEM,A0       ;set initial start
        MOVE.L  D2,A1	        ; and ending address
        MOVEA   #MEMRSLT,A3     ;set address of result area		        RM000
        RTS

;----------------------------------------------------------------------
;  Subroutine to save results and update ptrs.
;----------------------------------------------------------------------

SAVRSLT MOVE    D3,D0	        ;get low results
        SWAP    D3	        ;get high results
   …

Showing first 20,000 characters of 74,710 total. Open the full document →

mp.ls