Lisa_Boot_ROM_Asm_Listing

0000|                       ;        .NOLIST
0000|                       ;===============================================================================;
0000|                       ;                                                                               ;
0000|                       ;                    LL        II    SSSSSSS       AAA                          ;
0000|                       ;                    LL        II    SS           AA AA                         ;
0000|                       ;                    LL        II    SSSSSSS     AAAAAAA                        ;
0000|                       ;                    LL        II         SS    AA     AA                       ;
0000|                       ;                    LLLLLLL   II    SSSSSSS   AA       AA                      ;
0000|                       ;                                                                               ;
0000|                       ;                                                                               ;
0000|                       ;   BBBBBB     OOOOO     OOOOO    TTTTTTTT      RRRRRR     OOOOO    MMM   MMM   ;
0000|                       ;   BB   BB   OO   OO   OO   OO      TT         RR   RR   OO   OO   MM M M MM   ;
0000|                       ;   BBBBBB    OO   OO   OO   OO      TT         RRRRRR    OO   OO   MM  M  MM   ;
0000|                       ;   BB   BB   OO   OO   OO   OO      TT         RR RR     OO   OO   MM     MM   ;
0000|                       ;   BBBBBB     OOOOO     OOOOO       TT         RR   RR    OOOOO    MM     MM   ;
0000|                       ;                                                                               ;
0000|                       ;                                                                               ;
0000|                       ;       Copyright 1983, 1984 Apple Computer Inc.                                ;
0000|                       ;       Revision 2H                                                             ;
0000|                       ;                                                                               ;
0000|                       ;===============================================================================;
0000|                       ;
0000|                       ; Filename:  RMXXX.Y.TEXT, XXX = ROM VERSION # (e.g., 200 for 2.00)
0000|                       ;                            Y = E (equates)
0000|                       ;                              = K (kernel tests)
0000|                       ;                              = S (secondary tests)
0000|                       ;                              = B (bootstrap code)
0000|                       ;                              = M (monitor code)
0000|                       ;                              = G (graphics, icon and message display)
0000|                       ;
0000|                       ; Function:  Initializes LISA system for use and performs preliminary
0000|                       ;            diagnostic checks.  If all tests pass, the system then
0000|                       ;            does a keyboard scan to check for user input.  If any key
0000|                       ;            is hit other than caps lock or the mouse button,
0000|                       ;            a menu is displayed on the screen showing the available
0000|                       ;            boot devices.  If a valid COMMAND key sequence is detected,
0000|                       ;            a boot from an alternate device is attempted (see below).
0000|                       ;            If no keyboard input is detected, the system first checks
0000|                       ;            parameter memory for a valid boot device and, if none, defaults
0000|                       ;            to booting from a Profile attached to the builtin parallel port
0000|                       ;            for Lisa 1 systems.
0000|                       ;
0000|                       ;            For Lisa 2 systems, a check is first made to verify a disk
0000|                       ;            (internal or external) is connected before defaulting to the
0000|                       ;            hard disk boot.  If no disk is detected, the system defaults
0000|                       ;            to booting from the floppy drive.
0000|                       ;
0000|                       ;
0000|                       ;
0000|                       ; Inputs:    Checks for keyboard input from the user.  Currently, the following
0000|                       ;            key sequences are honored if input after the system "clicks" the
0000|                       ;            speaker (CMD refers to the Apple key on the keyboard):
0000|                       ;
0000|                       ;               CMD/1 - boot from Twiggy drive #1 or integral hard disk
0000|                       ;               CMD/2 - boot from Twiggy drive #2 or SONY drive
0000|                       ;               CMD/3 - boot from Profile attached to parallel port or integral hard disk
0000|                       ;               CMD/4 - boot from I/O slot #1, port 1
0000|                       ;               CMD/5 - boot from I/O slot #1, port 2
0000|                       ;               CMD/6 - boot from I/O slot #2, port 1
0000|                       ;               CMD/7 - boot from I/O slot #2, port 2
0000|                       ;               CMD/8 - boot from I/O slot #3, port 1
0000|                       ;               CMD/9 - boot from I/O slot #3, port 2
0000|                       ;               CMD/ENTER (on key pad) - abort boot, branch to ROM monitor
0000|                       ;               CMD/SHIFT/P - abort boot, do power cycling
0000|                       ;
0000|                       ;  OUTPUTS:  Saves various results and contents of system registers in memory
0000|                       ;            for examination by system programs or with the ROM monitor.
0000|                       ;
0000|                       ;               $180-183 : Power-up status (x0000000 = ok)
0000|                       ;               $184-185 : Memory sizing error results
0000|                       ;               $186-1A5 : Results of memory read/write tests
0000|                       ;               $1A6-1A9 : Parity error memory address (if error during mem test)
0000|                       ;               $1AA-1AB : Memory error address latch
0000|                       ;               $1AC-1AF : D7 save on exception errors
0000|                       ;               $1B0-1B1 : Results of MMU tests (context/data bits)
0000|                       ;               $1B2     : Keyboard ID (00 = no ID received)
0000|                       ;               $1B3     : Boot device ID
0000|                       ;               $1B4-1B9 : Boot failure data
0000|                       ;               $1BA-1BF : Clock setting (Ey,dd,dh,hm,ms,st)
0000|                       ;               $1C0-1DF : Data reg save area (D0 - D7)
0000|                       ;               $1E0-1FF : Address reg save area (A0 - A7, A7 = USP)
0000|                       ;               $240-260 : System serial #
0000|                       ;               $260-267 : Scratch area
0000|                       ;               $268-26B : Suspected (logical) memory error address for parity error
0000|                       ;               $26C-26F : Save of data written to suspected error address
0000|                       ;               $270-273 : Actual (logical) error address found during search
0000|                       ;               $274-277 : Save of data read during parity error search
0000|                       ;               $278-27B : (Physical) error address read from parity error address latch
0000|                       ;               $27C     : Error row for parity chip failure (0 = first row, 7 = last row)
0000|                       ;               $27D     : Error column for parity chip failure (9 or 14)
0000|                       ;               $27E-280 : Reserved
0000|                       ;               $280-293 : Exception data save area
0000|                       ;                           (FC/EXCADR/IR/SR/PC/EXCTYPE/SSP)
0000|                       ;                           44 = NMI or other interrupt
0000|                       ;                           45 = bus error
0000|                       ;                           46 = address error
0000|                       ;                           47 = other exception/interrupt
0000|                       ;                           48 = illegal instruction error
0000|                       ;                           49 = line 1010 or 1111 trap
0000|                       ;                           50 = bus error accessing keyboard VIA
0000|                       ;                           51 = bus error accessing parallel port VIA
0000|                       ;                           57 = bus error accessing disk controller
0000|                       ;               $294-297 : Maximum physical memory address + 1
0000|                       ;               $298-299 : I/O slot 1 card id (0 = no card present)
0000|                       ;               $29A-29B : I/O slot 2 card id
0000|                       ;               $29C-29D : I/O slot 3 card id
0000|                       ;               $29E     : Reserved
0000|                       ;               $29F     : Reserved
0000|                       ;               $2A0     : Reserved
0000|                       ;               $2A1     : Disk ROM id
0000|                       ;               $2A2-2A3 : Reserved
0000|                       ;               $2A4-2A7 : Minimum physical address
0000|                       ;               $2A8-2AB : Total memory (Max-Min)
0000|                       ;               $2AC     : SCC test results
0000|                       ;               $2AD     : Slot # of memory board if memory error
0000|                       ;               $2AE     : Result of disk controller self-test
0000|                       ;               $2AF     : System type (0 = Lisa 1, 1 = Lisa 2, 2 = Lisa 2 with external hard disk,
0000|                       ;                                       3 = Lisa 2 with internal hard disk)
0000|                       ;               $2B0-2BF : Keyboard queue (16 bytes)
0000|                       ;               $2C0-480 : ROM scratchpad/stack area
0000|                       ;               $480-800 : Reserved for ROM local variable usage
0000|                       ;
0000|                       ;            Also saves data in special parameter memory area reserved for boot ROM use if error
0000|                       ;            encountered.  Usage is as follows:
0000|                       ;
0000|                       ;               $FCC161     : Error code
0000|                       ;               $FCC163-165 : Contents of memory error address latch if parity error
0000|                       ;               $FCC167     : Memory board slot # if memory error
0000|                       ;               $FCC169-173 : Last value read from clock
0000|                       ;               $FCC175-17B : Reserved
0000|                       ;               $FCC17D-17F : Checksum
0000|                       ;
0000|                       ; Originator:  Rich Castro  7/30/81 - Version 0.0 released to manufacturing
0000|                       ; Modified by: Rich Castro  7/30 - 11/3/81 - Made the following changes:
0000|                       ;                                      1) Twiggy bootstrap capability
0000|                       ;                                      2) Initial COPS test and keyboard scan
0000|                       ;                                      3) Moved parallel card to slot 2
0000|                       ;                                      4) Changed ROM interrupt/exception vectors,
0000|                       ;                                      5) Created jump table for ROM routines
0000|                       ;
0000|                       ;                           11/3/81  - Version 0.7 released to the world
0000|                       ;
0000|                       ;                           11/4/81 - 1/15/82 - Made the following changes:
0000|                       ;                                      1) Added support for new memory cards
0000|                       ;                                      2) Added warm-start capability and jump
0000|                       ;                                         table for ROM subroutine usage
0000|                       ;                                      3) Modified MMU reset routine to support
0000|                       ;                                         single step board usage
0000|                       ;                                      4) Added full memory initialization
0000|                       ;                                      5) Added 256K memory parity test
0000|                       ;                                      6) Modified COPS initialization so that
0000|                       ;                                         keyboard commands can be sensed more
0000|                       ;                                         reliably
0000|                       ;                                      7) Added error code display routines and
0000|                       ;                                         display of CPU and IO ROM versions
0000|                       ;                                      8) Added preliminary disk controller test
0000|                       ;                                      9) Updated warm-start check
0000|                       ;                                     10) Modified disk interface test
0000|                       ;                                     11) Changed low memory assignments
0000|                       ;                                     12) Made corrections for no I/O board, disk
0000|                       ;                                         interface error and contrast setting
0000|                       ;                                     13) Modified memory sizing routine to
0000|                       ;                                         catch memory errors
0000|                       ;                                     14) Modify MMU test to avoid context 0
0000|                       ;                                         destruction, add contrast setting for
0000|                       ;                                         new machines, correct disk error and
0000|                       ;                                         CPU ROM messages
0000|                       ;                                     15) Move stack so old memory test still runs
0000|                       ;
0000|                       ;                               1/15/82 - Release version 0.16
0000|                       ;                               1/18/82 - Fix stack problem and release vrsn 0.17
0000|                       ;                               1/19/82 - Change stack for call routine and version
0000|                       ;                                         to 0.18
0000|                       ;                               1/27/82 - Change MMU error routine to do address
0000|                       ;                                         and data line toggling
0000|                       ;                               1/28/82 - Add video circuitry test
0000|                       ;                               1/30/82 - Add write wrong parity test
0000|                       ;                               1/31/82 - Move run time stack to $180
0000|                       ;                               2/6/82  - Add Profile bootstrap with upgrade for
0000|                       ;                                         OS use (add jump table entries also)
0000|                       ;                               2/15/82 - Update Twiggy bootstrap and add entry
0000|                       ;                                         for OS use; also add MMU test to
0000|                       ;                                         conditional assembly and add context
0000|                       ;                                         saving to MMUTST2 routine
0000|                       ;                               2/17/82 - Add correction to memory test for
0000|                       ;                                         reboot problem and leave parity on
0000|                       ;                               2/24/82 - Add code for clock test and special
0000|                       ;                                         burn-in cycling
0000|                       ;                               2/25/82 - Add code to simulate soft on switch
0000|                       ;                                         pressed for COPS problem
0000|                       ;                               3/1/82  - Removed all changes since ROM 0.18
0000|                       ;                                         release except for parity enabling,
0000|                       ;                                         no reset feature, memory sizing change
0000|                       ;                                         and Profile booting
0000|                       ;                               3/1/82  - Restore default stack ptr loc to $300
0000|                       ;                               3/1/82  - Move default stack to $0400, restore
0000|                       ;                                         everything except MMU testing
0000|                       ;                               3/4/82  - Add MMU initialization and modify
0000|                       ;                                         Twiggy, Profile boot routines for new
0000|                       ;                                         load point
0000|                       ;                               3/10/82 - Add change for new I/O addresses and
0000|                       ;                                         fix for Twiggy routine
0000|                       ;                               3/10/82 - Change contrast value for new I/O's
0000|                       ;                               3/15/82 - Add correction for Profile and COPS
0000|                       ;                                         routines and display msg when booting
0000|                       ;                               3/17/82 - Restore version # at end of file
0000|                       ;                               3/18/82 - Release version 0.22
0000|                       ;
0000|                       ;                               4/5/82  - Make initial 2732 version (1.00); add
0000|                       ;                                         following changes:
0000|                       ;                                           1) correct MMU error routine bug
0000|                       ;                                           2) change stack for CALL to $0400
0000|                       ;                                           3) add parity disable to WWP routine
0000|                       ;                                           4) change MMU I/O space code to '9'
0000|                       ;                                           5) add invalid boot code message
0000|                       ;                               4/6/82  - Add speaker click after COPS check
0000|                       ;                               4/7/82  - Add jump table entry for speaker
0000|                       ;                                         routine, 1 second delay before "click"
0000|                       ;                                         and alpha lock key check
0000|                       ;
0000|                       ;                               4/8/82  - Release version 1.00
0000|                       ;
0000|                       ;                               5/5/82  - Add I/O slot configuration check and
0000|                       ;                                         I/O slot booting.  Also add change to
0000|                       ;                                         Profile read routine for PCR setting.
0000|                       ;                               5/12/82 - Add burnin power-cycling routine as
0000|                       ;                                         boot option invoked by CMD/P.
0000|                       ;                               5/13/82 - Add changes for COPS command timing,
0000|                       ;                                         Twiggy timeout, Twiggy booting, and
0000|                       ;                                         add power-cycling routine.
0000|                       ;                               5/14/82 - Add fixes for booting via parameter
0000|                       ;                                         memory and COPS timing experiment.
0000|                       ;                               5/17/82 - Add display of loop count and run time,
0000|                       ;                                         and alter parameter memory useage for
0000|                       ;                                         power-cycling option.
0000|                       ;                               5/18/82 - Add display of Twiggy errors, change
0000|                       ;                                         COPS routine for precheck code.
0000|                       ;                               5/20/82 - Add contrast reset for "warm start",
0000|                       ;                                         add cycle value display, restore COPS
0000|                       ;                                         timeout code.
0000|                       ;
0000|                       ;                               5/21/82 - Release version 1.02
0000|                       ;
0000|                       ;                               5/26/82 - Begin addition of ROM monitor; set
0000|                       ;                                         default to Apple if PM = 00.
0000|                       ;                               6/1/82  - Make following changes:
0000|                       ;                                         1) Memory sizing retry count to 64
0000|                       ;                                         2) Save results on memory sizing errors
0000|                       ;                                         3) Update NMI routine to check for parity
0000|                       ;                                            errors.
0000|                       ;                                         4) Restore default NMI vector after
0000|                       ;                                            memory test.
0000|                       ;                                         5) Create read clock subroutine and call
0000|                       ;                                            when doing clock display.
0000|                       ;                                         6) Add boot fix to save device id.
0000|                       ;                               6/1/82  - Change to new sizing algorithm and retry
0000|                       ;                                         count back to 32.
0000|                       ;                               6/3/82  - Convert to version 1.03
0000|                       ;                               6/3/82  - Made following changes:
0000|                       ;                                          1)Localize message display to TSTCHK
0000|                       ;                                          2)Do clear screen only in INITVCT and
0000|                       ;                                            in TSTCHK and second monitor level.
0000|                       ;                                          3)Change default video page to last.
0000|                       ;                                          4)Complete first edition of monitor.
0000|                       ;                               6/7/82  - Modify monitor level2 user interface.
0000|                       ;                               6/10/82 - Made following changes:
0000|                       ;                                          1)Add boot from Apple as CMD/A.
0000|                       ;                                          2)Clear screen and display only in
0000|                       ;                                            routine TSTCHK.
0000|                       ;                                          3)Add ROM checksum error bit.
0000|                       ;                                          4)Add exception error check to TSTCHK.
0000|                       ;                                          5)Add speaker click just before
0000|                       ;                                            keyboard scan.
0000|                       ;                                          6)Reset to first video page for boot
0000|                       ;                                            from Apple.
0000|                       ;                                          7)Merge in changes from 1.03 file.
0000|                       ;                                          8)Add parity error check to TSTCHK
0000|                       ;                                          9)Change power-cycling so that double
0000|                       ;                                            bus fault used to restart diags
0000|                       ;                               6/11/82 - Made following changes:
0000|                       ;                                          1)Increase Twiggy timeout to 2 mins.
0000|                       ;                                          2)Add 5 sec delay in power-cycle mode
0000|                       ;                                            before shutting down.
0000|                       ;
0000|                       ;                               6/14/82 - Release version 1.04
0000|                       ;                               6/22/82 - Add loop after COPS test if error
0000|                       ;                                         since keyboard not accessible.  Also add
0000|                       ;                                         fix for NMI restore after memory test.
0000|                       ;                               6/30/82 - Made following changes:
0000|                       ;                                          1)Add parameter memory and I/O boot
0000|                       ;                                            checksum routines.
0000|                       ;                                          2)Remove boot id save to parameter
0000|                       ;                                            memory, except for power-cycle.
0000|                       ;                                          3)Change to new boot device id's.
0000|                       ;                               7/1/82  -  1)Add changes for new Twiggy firmware.
0000|                       ;                                          2)Add fixes for bugs in 1.04:
0000|                       ;                                           a)Add row setting before error display
0000|                       ;                                             to avoid writing over menu line.
0000|                       ;                                           b)Set device codes for Profile and
0000|                       ;                                             I/O slots to allow display if error.
0000|                       ;                                           c)Enable setting of timeout for Twiggy
0000|                       ;                                             reads.
0000|                       ;                                           d)Save error codes for I/O boot in
0000|                       ;                                             memory.
0000|                       ;                                           e)Add option of clearing memory in
0000|                       ;                                             INITMON routine.
0000|                       ;                               7/7/82  - Made following changes:
0000|                       ;                                          1)Modify checksum routines
0000|                       ;                                          2)Add keyboard/mouse check/reset code
0000|                       ;                               7/13/82 - Add speed parameter for new Twiggy code
0000|                       ;                               7/14/82 - Add check for DSKDIAG in disk test,
0000|                       ;                                         change to new Twiggy error codes
0000|                       ;                               7/15/82 - Made following changes:
0000|                       ;                                          1)Add Profile routine updates.
0000|                       ;                                          2)Restore old boot id codes - new ones
0000|                       ;                                            used only when new Twiggy code
0000|                       ;                                            released.
0000|                       ;                                          3)Upgrade burnin code for new parameter
0000|                       ;                                            memory usage.
0000|                       ;                                          4)Attempt to enable keyboard after MMU
0000|                       ;                                            errors.
0000|                       ;                                          5)Remove I/O boot checksum code until
0000|                       ;                                            conversion to new Twiggy code.
0000|                       ;                                          6)Add video pattern display code..
0000|                       ;                                          7)Remove characters from table and
0000|                       ;                                            make other changes to save bytes.
0000|                       ;                                          8)Upgrade service mode display option
0000|                       ;                                            to handle count up to $FFFF.
0000|                       ;
0000|                       ;                               7/16/82 - Create version 1.05
0000|                       ;                               7/19/82 - Add bug fixes for MMU testing, power-
0000|                       ;                                         cycle memory testing, Profile boot
0000|                       ;                                         and service mode display option.
0000|                       ;
0000|                       ;                               7/19/82 - Create version 1.06
0000|                       ;                               7/20/82 - Add fix for MMU testing to properly
0000|                       ;                                         record context in error
0000|                       ;
0000|                       ;                               7/20/82 - Release version 1.07
0000|                       ;                               7/21/82 - Make keyboard/mouse reset code changes
0000|                       ;                                         and move check to before first "click"
0000|                       ;                               7/23/82 - Add extended memory tests
0000|                       ;                               7/27/82 - Add screen memory test and VIA tests.
0000|                       ;                                         Change default boot for new Twiggy code
0000|                       ;                                         to upper Twiggy.  Add conditionals for
0000|                       ;                                         Apple code.
0000|                       ;                               7/29/82 - Add SCC test, optimize code.
0000|                       ;                               7/30/82 - Add RAM address uniqueness test.
0000|                       ;                               8/4/82  - Added the following:
0000|                       ;                                          1)Twiggy mods for interleave
0000|                       ;                                          2)Monitor options CONTINUE and LOOP
0000|                       ;                                          3)Exception routine for line 1111 and
0000|                       ;                                            line 1010 errors.
0000|                       ;                               8/9/82  - Add Twiggy mod for disk clamp, add mods
0000|                       ;                                         for kernel test failures such as screen
0000|                       ;                                         flash on MMU error.
0000|                       ;                               8/11/82 - Add memory sizing fix, increase delay
0000|                       ;                                         for COPS and change default boot to
0000|                       ;                                         TWIGGY!!
0000|                       ;                               8/12/82 - Begin code changes for new user interface
0000|                       ;                                         and add hooks for icon display.
0000|                       ;                               8/14/82 - Add mods for Twiggy changes to monitor
0000|                       ;                                         DSKDIAG line and add initial timeout.
0000|                       ;                                         Continue user interface changes.
0000|                       ;                               8/18/82 - Add mouse, cursor code and changes for
0000|                       ;                               8/23/82 - Add controls for 2716 version of ROM.
0000|                       ;                                         Add changes for Service mode to use
0000|                       ;                                         pull down menu, eliminate keyboard
0000|                       ;                                         queuing while awaiting input.
0000|                       ;                               8/24/82 - Add dialog box, and window to service
0000|                       ;                                         mode with modified scroll and character
0000|                       ;                                         output routines.
0000|                       ;                               8/25/82 - Add icons along with routines to display
0000|                       ;                                         during test and for errors.
0000|                       ;                               8/27/82 - Add routines for displaying and using
0000|                       ;                                         boot icon menu.
0000|                       ;                               8/30/82 - Add auto boot from Applenet.
0000|                       ;                               8/31/82 - Add minor additions to Service mode
0000|                       ;                                         for Set and Loop options.
0000|                       ;
0000|                       ;                               8/31/82 - Create and do internal release of
0000|                       ;                                         2716 (0.24), 2732 (1.15) and 2764 (2.00)
0000|                       ;                                         ROM versions.
0000|                       ;
0000|                       ;                               9/8/82  - Add fixes for I/O slot icon display
0000|                       ;                                         and Profile icon display.
0000|                       ;                               9/9/82  - Add fix for reboot problem in 2716 ROM.
0000|                       ;                                         Add serial # read routine and test for
0000|                       ;                                         2732 and 2764 ROM versions.  Expand
0000|                       ;                                         stack for serial read routine.
0000|                       ;                               9/10/82 - Add fix for device code display for ROM
0000|                       ;                                         versions 0.24 and 1.15.
0000|                       ;
0000|                       ;                               9/10/82 - Create and do internal release of new
0000|                       ;                                         ROM versions 0.25, 1.16 and 2.01.
0000|                       ;
0000|                       ;                               9/13/82 - Add fixes for memory sizing and I/O
0000|                       ;                                         slot booting.
0000|                       ;
0000|                       ;                               9/14/82 - Create and release ROM versions 0.26,
0000|                       ;                                         1.17 and 2.02.
0000|                       ;                               9/22/82 - Add fixes and code for:
0000|                       ;                                          1)Default video latch setting
0000|                       ;                                          2)Mask for I/O and exception errors
0000|                       ;                                          3)Message display on external calls
0000|                       ;                                             to ROM monitor
0000|                       ;                                          4)Contrast setting before screen test
0000|                       ;                                          5)Disable of NMI key on power-up
0000|                       ;                                          6)Boot failure after first load
0000|                       ;                                          7)Error tones for failures
0000|                       ;                                          8)Loop mode setting of NMI key
0000|                       ;                               9/23/82 - Add
0000|                       ;                                          1)Power cycling
0000|                       ;                                          2)Full service mode menu
0000|                       ;                                          3)Loop mode test choice display
0000|                       ;                               9/24/82 - Add dump memory option to service mode
0000|                       ;                               9/25/82 - Modify display memory option to allow
0000|                       ;                                         count and address data on same line
0000|                       ;                               9/29/82 - Add jump table entry for READMMU
0000|                       ;                               9/30/82 - Add:
0000|                       ;                                          1)"No reset" feature
0000|                       ;                                          2)Verify Disk option for service mode
0000|                       ;                                          3)Optimize cursor routines and
0000|                       ;                                            remove unused CursorShield routine.
0000|                       ;                                          4)Invert rectangles when selected from
0000|                       ;                                            keyboard.
0000|                       ;                                          5)Display boot menu only if down keycode
0000|                       ;                                            detected.
0000|                       ;                               10/5/82 - Add:
0000|                       ;                                          1)Memory error decoding to board level
0000|                       ;                                          2)New size and position for alert box
0000|                       ;                                          3)New test icon display
0000|                       ;                                          4)Diskette # for Twiggy errors
0000|                       ;                               10/6/82 - Add:
0000|                       ;                                          1)Continue keyboard scan after COPS
0000|                       ;                                            errors
0000|                       ;                                          2)Set extended memory test bit for
0000|                       ;                                            loop on memory test option
0000|                       ;                                          3)Display I/O slot card # on errors
0000|                       ;                                          4)Change boot menu to "pull-down" format
0000|                       ;                                          5)Change to new icons
0000|                       ;                               10/7/82 - Add:
0000|                       ;                                          1)SCC test
0000|                       ;                                          2)Error if no serial # (allow continue)
0000|                       ;                                          3)Two passes of memory tests for extended
0000|                       ;                                            mode, one for regular mode
0000|                       ;                               10/9/82 - Create version 2.03
0000|                       ;                               10/10/82 - Add bug fixes and I/O slot ROM check in
0000|                       ;                                          config scan.
0000|                       ;
0000|                       ;                               10/12/82 - Create and release version 2.04.
0000|                       ;
0000|                       ;                               10/13/82 - Make following changes:
0000|                       ;                                           1)Add keyboard reset code
0000|                       ;                                           2)Remove SCC test
0000|                       ;                                           3)Add bug fixes for making alert box
0000|                       ;                                             and displaying bad keyboard
0000|                       ;                               10/14/82 - Add display of check marks for test icons
0000|                       ;                               10/18/82 - Add fixes for Monitor entry, Profile boot,
0000|                       ;                                          looping on diag tests
0000|                       ;                               10/20/82 - Add message translations
0000|                       ;                               10/21/82 - 1)Adjust alert box and button dimensions
0000|                       ;                                          2)Add boot from all ports on I/O slots
0000|                       ;                                          3)Add fix for CMD key detection in monitor
0000|                       ;                                          4)Change powercycle window to alert box
0000|                       ;                                          5)Extend verify timeout to 4 minutes
0000|                       ;                               10/22/82 - 1)Add keyboard reset on external entry to ROM
0000|                       ;                                            monitor
0000|                       ;                                          2)Make Dump Memory routine conditional on
0000|                       ;                                            final LISA ROM
0000|                       ;                               10/25/82 - 1)Change wait for disk error to branch to
0000|                       ;                                            monitor - CONTINUE option then continues
0000|                       ;                                            with the same boot device
0000|                       ;                                          2)Change RETRY phrase to RESTART
0000|                       ;                               10/27/82 - Made following changes:
0000|                       ;                                           1)RESET instruction on startup
0000|                       ;                                           2)Jump table entries for access to memory
0000|                       ;                                             test and display decimal routines
0000|                       ;                                           3)Optimize warm start reset check and
0000|                       ;                                             MMU error loop routines
0000|                       ;                                           4)Change default video page to $2F for
0000|                       ;                                             no memory found.
0000|                       ;                                           5)Rewrite screen memory test. Change main
0000|                       ;                                             memory test to go from low memory
0000|                       ;                                             to base of screen memory.
0000|                       ;                                           6)Move inverse video check to after screen
0000|                       ;                                             test, doing rewrite only of screen page.
0000|                       ;                                           7)Add new boot failure code, with hooks to
0000|                       ;                                             catch booting errors after ROM has
0000|                       ;                                             released control to boot loader for Twiggy
0000|                       ;                                             and Profile booting.
0000|                       ;                               10/29/82 - Add display for uncompressed slot card icons.
0000|                       ;                                          Modify TONE routine to init PCR reg.
0000|                       ;                               11/1/82  - Change external entry to monitor interface
0000|                       ;                                          so that error code displayed on same line as
0000|                       ;                                          message if no icon displayed
0000|                       ;                               11/3/82  - Made following changes:
0000|                       ;                                           1)Move creation of test icon display till
0000|                       ;                                             after keyboard reset so translation can
0000|                       ;                                             be done if necessary
0000|                       ;                                           2)Do cursor, mouse init only once so
0000|                       ;                                             cursor posn not reset
0000|                       ;                                           3)Optimize mouse, cursor routines
0000|                       ;                                           4)Correct COPSCMD routine
0000|                       ;                                           5)Upgrade check for Profile routine and
0000|                       ;                                             optimize Profile read code
0000|                       ;                               11/8/82  - Conditionally add check for keyboard connected
0000|                       ;                                          routine.
0000|                       ;                               11/9/82  - Create version 2.07
0000|                       ;                               11/11/82 - Modify ROM checksum algorithm
0000|                       ;                               11/12/82 - Add diskette eject on power-off
0000|                       ;                               11/13/82 - 1)Remove Dump Memory/Verify Disk from Service
0000|                       ;                                            mode menu
0000|                       ;                                          2)Add speaker beep and specific read/write
0000|                       ;                                            loop for memory sizing and lo mem errors
0000|                       ;                               11/15/82 - 1)Add keyboard/mouse disconnect check
0000|                       ;                                          2)Remove memory "clear" from sizing test - now
0000|                       ;                                            done after memory testing
0000|                       ;                               11/16/82 - 1)Change power-cycle invoking to CMD/SHIFT/P
0000|                       ;                                            key sequence.
0000|                       ;                                          2)Change customer monitor mode invoking to
0000|                       ;                                            CMD/ENTER (on key pad) key sequence.
0000|                       ;                                          3)Add wait for profile loop in boot menu
0000|                       ;                                            display routine
0000|                       ;                                          4)Add timeout to general wait for clock
0000|                       ;                                            input routine
0000|                       ;                                          5)Increase delay for poweroff wait loop
0000|                       ;                                          6)Optimize character display routine
0000|                       ;                               11/18/82 - 1)Add save of error code to special parameter
0000|                       ;                                            memory area for use during burnin.
0000|                       ;                                          2)Add context check for MMU testing
0000|                       ;                                          3)Create version 2.08 for internal release
0000|                       ;                               11/19/82 - 1)Change initial position of cursor to center
0000|                       ;                                            of screen.
0000|                       ;
0000|                       ;                               11/19/82 -  Release versions 2.08 (internal) and
0000|                       ;                                           2.09 (for manufacturing)
0000|                       ;
0000|                       ;                               12/15/82 -  Add:
0000|                       ;                                           1)Setting of VIA PCR reg for later use
0000|                       ;                                           2)Reset of keyboard before boot
0000|                       ;                                           3)Fix for slot 3 card check for boot menu
0000|                       ;                               12/16/82 -  Add:
0000|                       ;                                           1)Move Profile cmd buffer to location $304
0000|                       ;                                           2)Change default boot device to Profile
0000|                       ;                                           3)Remove support for third boot port on
0000|                       ;                                             each slot
0000|                       ;                                           4)Expand id range for test card search
0000|                       ;                                           5)Don't display Restart button after boot
0000|                       ;                                             error
0000|                       ;                                           6)New icons
0000|                       ;                               12/18/82 -  Fix memory test bug
0000|                       ;
0000|                       ;                                1/3/83  -  Fix bug in reporting parity circuitry
0000|                       ;                                           failure.  Change version to 2.10.
0000|                       ;                                1/7/83  -  Make following changes:
0000|                       ;                                           1)Change keyboard sequences for I/O slot
0000|                       ;                                             booting
0000|                       ;                                           2)Extend timeout for inital Profile check
0000|                       ;                                1/11/83 -  Change SCC test to use max baud rate for
0000|                       ;                                           loopback test
0000|                       ;                                1/12/83 -  Add running of expansion card status routines
0000|                       ;                                           when configuration check is done
0000|                       ;                                1/18/83 -  Add fixes for:
0000|                       ;                                           1)Continuing after memory error
0000|                       ;                                           2)Checking for no reset function
0000|                       ;                                           4)Read of I/O slot ROM for icon data -le 2 meg
0000|                       ;                                             ensure odd address for icon count
0000|                       ;                                           5)Default boot setting when loop on memory
0000|                       ;                                             test selected
0000|                       ;                                1/21/83 -  Add save of disk controller self-test status
0000|                       ;
0000|                       ;                                1/28/83 -  Create and release ROM version 2.11
0000|                       ;
0000|                       ;                                3/15/83 -  Extend Profile timeout for case where drive
0000|                       ;                                           may be parking head. (bug RM016)
0000|                       ;                                4/20/83 -  Add fixes for:
0000|                       ;                                            1)Memory sizing (bug RM015).
0000|                       ;                                            2)Garbage sent out serial port (RM014).
0000|                       ;                                            3)Removed 6504 (bug RM013).
0000|                       ;                                            4)Never ready Profile (bug RM011).
0000|                       ;                                           Also do some code optimization in icon
0000|                       ;                                           routines to make room for fixes. (RM000)
0000|                       ;                                4/22/83 -  Do code optimization for setting bus error
0000|                       ;                                           vector (labeled as RM000).
0000|                       ;                                           Add changes for following requests:
0000|                       ;                                            1)Display ROM id's on bootup  (CHG001)
0000|                       ;                                            2)Loop on address 1Meg-2 if sizing error  (CHG002)
0000|                       ;                                            3)Turn off contrast before doing poweroff (CHG003)
0000|                       ;                                            4)Change copyright notice.  (CHG005)
0000|                       ;                                              Also modify alert msg display routine (CHG005).
0000|                       ;                                4/26/83 -  Add loop on CPU diags if no memory or I/O
0000|                       ;                                           board installed.  Also toggle LED. (CHG004)
0000|                       ;                                4/27/83 -  Do only basic memory test on warm-start. (CHG006)
0000|                       ;                                           Add fix for NMI bug (RM010).
0000|                       ;                                5/9/83  -  Made following changes:
0000|                       ;                                            1)Change ROM id display to rev # (D) (CHG001)
0000|                       ;                                            2)Change ROM test failure to loop at fixed address
0000|                       ;                                              $00FE00C8  (end of jump table)  (CHG007)
0000|                       ;                                            3)Make correction for screen not cleared when
0000|                       ;                                              continuing from I/O slot error to boot menu.
0000|                       ;                                              (CHG008)
0000|                       ;                                5/10/83 -  Add change to enable display of uncompressed icons
0000|                       ;                                           upon external entry to ROM Monitor (CHG008).
0000|                       ;
0000|                       ;                                5/12/83 -  Create and release rev D of boot ROM.
0000|                       ;
0000|                       ;                                8/8/83  -  Add changes for Pepsi system:   (CHG009)
0000|                       ;                                           1) New icons.
0000|                       ;                                           2) Display of icons with id #'s.
0000|                       ;                                8/9/83  -  Add save of disk ROM id in low memory. (CHG010)
0000|                       ;                                           Add fixes for:
0000|                       ;                                           1) SCC init for Applebus.  (CHG011)
0000|                       ;                                           2) Test card boot search.  (CHG012)
0000|                       ;                                8/10/83 -  Delete inverse video check. (CHG013)
0000|                       ;                                           Add fix to beep routine.    (CHG014)
0000|                       ;                                8/16/83 -  Delete memory address and ping pong routines,
0000|                       ;                                           add routines to decode parity error to
0000|                       ;                                           chip.       (CHG015)
0000|                       ;                                9/1/83  -  Add retry for hard disk booting.  (CHG016)
0000|                       ;                                           Add jump table entry for write to
0000|                       ;                                           parameter memory routine.   (CHG017)
0000|                       ;                                9/2/83  -  Add new font, modify display routines. (CHG018)
0000|                       ;                                           Add wait for hard disk ready when
0000|                       ;                                           power-cycling.  (CHG019)
0000|                       ;                                9/6/83  -  Add setting of video latch whenever boot
0000|                       ;                                           error causes jump to ROM low memory default
0000|                       ;                                           vectors. (CHG020)
0000|                       ;                                           Add fix for memory test/initialization
0000|                       ;                                           bug. (CHG021)
0000|                       ;                                9/7/83  -  Add read of disk controller ROM self-test
0000|                       ;                                           results.  (CHG022)
0000|                       ;                                           Add skip of disk eject on power-off if any
0000|                       ;                                           disk controller errors occurred.  (CHG023)
0000|                       ;
0000|                       ;                                9/8/83  -  Release for testing (rev 3B) with Pepsi systems.
0000|                       ;
0000|                       ;                                10/10/83 - 1)Make Pepsi icon changes.  (CHG024)
0000|                       ;                                           2)Add fix for proper setting of carry bit
0000|                       ;                                             on floppy or hard disk boots. (CHG025)
0000|                       ;                                           3)Add fix for video reset on boot from not ready
0000|                       ;                                             Profile. (CHG026)
0000|                       ;                                10/12/83 - Add change to reset SCC for Applebus before
0000|                       ;                                           doing memory test.  (CHG027)
0000|                       ;                                10/20/83 - Add fix for service mode bus error problem. (CHG028)
0000|                       ;
0000|                       ;
0000|                       ;                                10/20/83 - Release as rev E for Lisa and Pepsi systems.
0000|                       ;
0000|                       ;                                12/15/83 - 1)Add new code to determine system type. (CHG029)
0000|                       ;                                           2)Change default boot device for Lisa 2
0000|                       ;                                              system if no hard disk connected. (CHG030)
0000|                       ;                                           3)Extend timeout for hard disk ready. (CHG031)
0000|                       ;                                           4)Add bug fix for wrong icon display on Lisa 2.
0000|                       ;                                              (CHG032)
0000|                       ;                                           5)Add bug fix for menu display when mouse or
0000|                       ;                                             keyboard not connected. (CHG033)
0000|                       ;                                           6)Remove save of error code in parameter memory.
0000|                       ;                                             (CHG034)
0000|                       ;                                12/16/83 - Release as rev 'X' for testing
0000|                       ;
0000|                       ;                                12/21/83 - Release as official rev 'F' for all systems
0000|                       ;
0000|                       ;                                1/25/84  - 1)Add code to properly initialize Profile-reset
0000|                       ;                                             and parity-reset lines for Profile booting    (CHG036)
0000|                       ;                                2/7/84   - 1)Extend hard disk default read timeout to 16
0000|                       ;                                             seconds for Widget systems. (CHG037)
0000|                       ;                                           2)Add delay after hard disk reset for Widget
0000|                       ;                                             systems. (CHG038)
0000|                       ;                                2/8/84   - Release as rev G for testing
0000|                       ;
0000|                       ;                                2/24/84  - Release as official rev H
0000|                       ;
0000|                       ;-----------------------------------------------------------------------------------------------------
0000|                               .PAGE
0000|                       ;-----------------------------------------------------------------------------------------------------
0000|                       ;  Macro definitions
0000|                       ;-----------------------------------------------------------------------------------------------------
0000|
0000|                               .MACRO  BSR6
0000|                               LEA     @1,A6
0000|                               BRA     %1
0000|                       @1
0000|                               .ENDM
0000|
0000|                               .MACRO  BSRS6
0000|                               LEA     @1,A6
0000|                               BRA.S   %1
0000|                       @1
0000|                               .ENDM
0000|
0000|                               .MACRO  RTS6
0000|                               JMP     (A6)
0000|                               .ENDM
0000|
0000|                               .MACRO  BSR4
0000|                               LEA     @1,A4
0000|                               BRA     %1
0000|                       @1
0000|                               .ENDM
0000|
0000|                               .MACRO  BSRS4
0000|                               LEA     @1,A4
0000|                               BRA.S   %1
0000|                       @1
0000|                               .ENDM
0000|
0000|                               .MACRO  RTS4
0000|                               JMP     (A4)
0000|                               .ENDM
0000|
0000|                               .MACRO  BSR2
0000|                               LEA     @1,A2
0000|                               BRA     %1
0000|                       @1
0000|                               .ENDM
0000|
0000|                               .MACRO  BSRS2
0000|                               LEA     @1,A2
0000|                               BRA.S   %1
0000|                       @1
0000|                               .ENDM
0000|
0000|                               .MACRO  RTS2
0000|                               JMP     (A2)
0000|                               .ENDM
0000|
0000|                               .MACRO  DISABLE
0000|                               MOVE    SR,-(SP)
0000|                               ORI     #$0700,SR
0000|                               .ENDM
0000|
0000|                               .MACRO  ENABLE
0000|                               MOVE    (SP)+,SR
0000|                               .ENDM
0000|
0000|                               .PAGE
0000|                       ;--------------------------------------------------------------------------
0000|                       ;       Conditionals for assembly
0000|                       ;--------------------------------------------------------------------------
0000|
0000| 0000 0001             DIAGS           .EQU    1               ;controls assembly of selected diags
0000| 0000 0001             NEWLISA         .EQU    1               ;controls extra code for new LISA's
0000| 0000 0001             BURNIN          .EQU    1               ;controls code for burnin cycling
0000| 0000 0001             NORESET         .EQU    1               ;controls code for reset feature
0000| 0000 0000             EXTERNAL        .EQU    0               ;controls listing of externally
0000|                                                               ; callable routines only (w/ EQU's)
0000| 0000 0001             ROM16K          .EQU    1               ;controls code to be added when 16K
0000|                                                               ; ROM's available
0000| 0000 0001             NEWTWIG         .EQU    1               ;controls code for new Twiggy firmware
0000|                                                               ; interface
0000| 0000 0000             FINLISA         .EQU    0               ;controls code for final LISA's
0000| 0000 0001             FINKBD          .EQU    1               ;controls check for final keyboard
0000| 0000 0000             AAPL            .EQU    0               ;controls Apple monitor code
0000| 0000 0001             USERINT         .EQU    1               ;controls code for new user interface
0000| 0000 0000             DEBUG           .EQU    0               ;controls global equate allocation
0000| 0000 0000             ROM4K           .EQU    0               ;controls code for 2716 version
0000| 0000 0000             ROM8K           .EQU    0               ;controls code for 2732 version
0000| 0000 0001             BMENU           .EQU    1               ;controls format of boot menu
0000|                                                               ;  1 = pull down menu
0000| 0000 0001             FULLSCC         .EQU    1               ;controls code for SCC tests
0000| 0000 0000             INVERTCK        .EQU    0               ;controls code for inverse video check          CHG013
0000|
0000|                               .IF     EXTERNAL = 1
0000|                               .ENDC
0000|                               .PAGE
0000|                       ;--------------------------------------------------------------------------
0000|                       ;       GENERAL EQUATES
0000|                       ;--------------------------------------------------------------------------
0000| 00FE 0000             ROMBASE         .EQU    $00FE0000       ;BASE ADDRESS FOR ROM
0000| 0000 00FE             ROMSLCT         .EQU    $00FE           ;MSB'S OF ROM ADDRESS
0000| 00FC 0000             IOSPACE         .EQU    $00FC0000       ;START OF IO SPACE
0000| 00FC E800             VIDLTCH         .EQU    $00FCE800       ;VIDEO ADDRESS LATCH
0000| 0000 002F             DEFVID          .EQU    $2F             ;default setting for video latch
0000|                                                               ; (end of 512K board in slot 1)
0000| 0000 00AF             DEFVID2         .EQU    $AF             ;default video latch setting and LED on
0000|
0000|                               .IF  DEBUG = 0
0000| 0000 0110             SCRNBASE        .EQU    $110            ;ptr to base address for video page
0000|                               .ELSE
0000|                               .ENDC
0000|
0000|                               .IF  USERINT = 0
0000|                               .ELSE
0000| 0000 005A             RBYTES          .EQU    90              ;BYTES FOR EACH DISPLAY ROW
0000|                               .ENDC
0000| 0000 010E             TOPOFFSET       .EQU    270             ;offset for first row from top of screen
0000| 0000 00E1             RLONGS          .EQU    225             ;longs for each row
0000| 0000 0000             R0              .EQU    0               ;ROW 0 OFFSET
0000| 0000 005A             R1              .EQU    R0+90           ;ROW 1 OFFSET, ETC.
0000| 0000 00B4             R2              .EQU    R1+90
0000| 0000 010E             R3              .EQU    R2+90
0000| 0000 0168             R4              .EQU    R3+90
0000| 0000 01C2             R5              .EQU    R4+90
0000| 0000 021C             R6              .EQU    R5+90
0000| 0000 0276             R7              .EQU    R6+90
0000| 0000 0008             BUSVCTR         .EQU    $0008           ;BUS EXCEPTION VECTOR
0000| 0000 000C             ADRVCTR         .EQU    $000C           ;ADDRESS EXCEPTION VECTOR
0000| 0000 0010             ILLVCTR         .EQU    $0010           ;ILLEGAL INSTRUCTION VECTOR
0000| 0000 0028             L10VCTR         .EQU    $0028           ;line 1010 trap
0000| 0000 002C             L11VCTR         .EQU    $002C           ;line 1111 trap
0000| 0000 007C             NMIVCT          .EQU    $007C           ;NMI VECTOR LOCATION
0000| 0000 0080             TRPVCT0         .EQU    $0080           ; TRAP 0 VECTOR LOCATION
0000| 0020 0000             MAXADR          .EQU    $00200000       ; MAX RAM ADDRESS + 1 (2 meg)
0000| 0010 0000             ONEMEG          .EQU    $00100000       ; 1 meg in hex
0000| 0008 0000             HALFMEG         .EQU    $00080000       ; 1/2 meg
0000| 0004 0000             QTRMEG          .EQU    $00040000       ; 256K
0000| 0002 0000             ROW2ADR         .EQU    $00020000       ; 128K - START OF 2ND MEMORY ROW
0000| 0000 0480             STKBASE         .EQU    $0480           ; DEFAULT BASE FOR STACK
0000| 0000 0480             CALLBASE        .EQU    $0480           ; STACK BASE FOR USE BY CALL ROUTINE
0000| 00FC E012             SETUP           .EQU    $00FCE012       ; ADDRESS TO TURN SETUP BIT OFF
0000| 00FC E010             SETUPON         .EQU    $00FCE010       ; ADDRESS TO TURN SETUP ON
0000| AA55 A55A             PATRN           .EQU    $AA55A55A       ; PATTERN FOR MEMORY TESTING
0000| 0000 A55A             PATRN2          .EQU    $A55A           ; PATTERN FOR MMU TEST
0000| 00FC E01E             PARON           .EQU    $00FCE01E       ;PARITY ENABLE
0000| 00FC E01C             PAROFF          .EQU    $00FCE01C       ;PARITY DISABLE
0000| 00FC F000             MEALTCH         .EQU    $00FCF000       ;MEMORY ERROR ADDRESS LATCH
0000| 00FC F801             STATREG         .EQU    $00FCF801       ;ERROR STATUS REGISTER
0000| 0000 0000             SFER            .EQU    0               ; SOFT ERROR BIT
0000| 0000 0001             PBIT            .EQU    1               ; HARD ERROR (PARITY) BIT
0000| 0000 0002             VRBIT           .EQU    2               ; VR BIT LOCATION
0000| 0000 0004             VIDBIT          .EQU    4               ; VID BIT
0000| 0000 0005             CSBIT           .EQU    5               ; CSYNC BIT
0000| 0000 0006             INVIDBIT        .EQU    6               ; INVERSE VIDEO BIT
0000| 0000 0020             RETRYCNT        .EQU    32              ;RETRY COUNT FOR MEMORY SIZING
0000| 00FC E018             VTIRDIS         .EQU    $00FCE018       ;VERTICAL RETRACE DISABLE
0000| 00FC E01A             VTIRENB         .EQU    $00FCE01A       ;VERTICAL RETRACE ENABLE
0000| 0008 0000             HEX512K         .EQU    $80000          ;512K in hex
0000| 0002 0000             HEX128K         .EQU    $20000          ;128K in hex
0000| 0001 8000             HEX96K          .EQU    $18000          ;96K in hex
0000| 0000 8000             HEX32K          .EQU    $8000           ;32K in hex
0000| 0000 2000             HEX8K           .EQU    $2000           ;8K in hex
0000| 0000 0800             HEX2K           .EQU    $0800           ;2K in hex
0000| 0000 0800             LOMEM           .EQU    HEX2K           ;amount of memory initially tested
0000| 00FC E006             DG2ON           .EQU    $00FCE006       ;WRITE WRONG PARITY ENABLE
0000| 00FC E004             DG2OFF          .EQU    $00FCE004       ;WRITE WRONG PARITY DISABLE
0000| 0003 D090             ONESEC          .EQU    $3D090          ;1 second delay constant
0000| 0007 A120             TWOSEC          .EQU    ONESEC*2        ;2 second delay
0000| 0013 12D0             FIVESEC         .EQU    ONESEC*5        ;5 second delay
0000| 0000 F424             QTRSEC          .EQU    ONESEC/4        ;0.25 second delay
0000| 0000 61A8             TNTHSEC         .EQU    ONESEC/10       ;0.1 second delay
0000| 0006 7C28             KBDDLY          .EQU    /10  ;1.7 second delay
0000| 0001 E848             HALFSEC         .EQU    ONESEC/2        ;0.5 second delay
0000|
0000|                       ;  Equates for memory parity error routine
0000|
0000| 0000 0040             MSRCHSZ         .EQU    64              ;main memory error range                CHG015
0000| 0000 8000             VSRCHSZ         .EQU    32768           ;video memory error range               CHG015
0000| FFFF 8000             VMSK            .EQU    $FFFF8000       ;mask for video errors                  CHG015
0000| 0000 0003             ADRMSK          .EQU    $03             ;mask for error byte address            CHG015
0000| 0008 0000             PHYTOLOG        .EQU    $80000          ;physical to logical address offset     CHG015
0000|
0000|                               .IF     EXTERNAL = 1
0000|                               .ENDC
0000|
0000|                       ;  Equates for VIA registers (offsets from $XXD181 or $XXD101)
0000|
0000| 00FC DD81             VIA1BASE        .EQU    $00FCDD81       ;BASE ADDRESS FOR COPS 6522
0000| 0000 0000             ORB1            .EQU    $0              ;PORT B OUTPUT REG
0000| 0000 0002             ORA1            .EQU    $2              ;PORT A OUTPUT REG
0000| 0000 0004             DDRB1           .EQU    $4              ;PORT B DATA DIRECTION REG
0000| 0000 0006             DDRA1           .EQU    $6              ;PORT A DATA DIRECTION REG
0000| 0000 000C             T1LL1           .EQU    $C              ;LOW ORDER T1 LATCH
0000| 0000 000E             T1LH1           .EQU    $E              ;HIGH ORDER T1 LATCH
0000| 0000 0010             T2CL1           .EQU    $10             ;LOW ORDER T2 COUNTER
0000| 0000 0012             T2CH1           .EQU    $12             ;HIGH ORDER T2 COUNTER
0000| 0000 0014             SHR1            .EQU    $14             ;SHIFT REG
0000| 0000 0016             ACR1            .EQU    $16             ;AUXILIARY CONTROL REG
0000| 0000 0018             PCR1            .EQU    $18             ;PERIPHERAL CONTROL REG
0000| 0000 001A             IFR1            .EQU    $1A             ;INTERRUPT FLAG REG
0000| 0000 001C             IER1            .EQU    $1C             ;INTRPT ENABLE REG
0000| 0000 001E             PORTA1          .EQU    $1E             ;PORT A WITH NO HANDSHAKE
0000|
0000| 0000 0004             FDIR            .EQU    4               ;PORT B, BIT 4 HAS FDIR STATE
0000| 00FC D901             VIA2BASE        .EQU    $00FCD901       ;BASE ADDRESS FOR OTHER 6522
0000| 0000 0000             ORB2            .EQU    $0              ;PORT B OUTPUT REG
0000| 0000 0000             IRB2            .EQU    $0              ;PORT B INPUT REG
0000| 0000 0008             ORA2            .EQU    $8              ;PORT A OUTPUT REG
0000| 0000 0008             IRA2            .EQU    $8              ;PORT A INPUT REG
0000| 0000 0010             DDRB2           .EQU    $10             ;PORT B DATA DIRECTION REG
0000| 0000 0018             DDRA2           .EQU    $18             ;PORT A DATA DIRECTION REG
0000| 0000 0030             T1LL2           .EQU    $30             ;LOW ORDER T1 LATCH
0000| 0000 0038             T1LH2           .EQU    $38             ;HIGH ORDER T1 LATCH
0000| 0000 0040             T2CL2           .EQU    $40             ;LOW ORDER T2 COUNTER
0000| 0000 0048             T2CH2           .EQU    $48             ;HIGH ORDER T2 COUNTER
0000| 0000 0060             PCR2            .EQU    $60             ;PERIPHERAL CONTROL REG
0000| 0000 0078             PORTA2          .EQU    $78             ;PORT A WITH NO HANDSHAKE
0000|
0000| 0000 0006             DSKDIAG         .EQU    6               ;port B, bit 6 is disk alive indicator
0000|
0000| 00FC D01C             CSTRB           .EQU    $00FCD01C       ;STROBE FOR CONTRAST LATCH
0000|                       ;  Equates for PIA registers (offsets from $XXA001) (SLOT 2)
0000| 00FC A001             PIABASE         .EQU    $00FCA001       ;BASE ADDRESS FOR PIA CARD IN SLOT 2
0000| 0000 0000             INDATA          .EQU    $0
0000| 0000 0002             OUTDATA         .EQU    $2
0000| 0000 0004             INCSR           .EQU    $4
0000| 0000 0006             OUTCSR          .EQU    $6
0000|
0000|                       ;  Equates for SCC
0000|
0000| 00FC D241             SCCBCTL         .EQU    $FCD241         ;SCC channel B control
0000| 0000 0002             ACTL            .EQU    2               ;offset to SCC channel A control
0000| 0000 0004             SCCDATA         .EQU    4               ;offset to SCC data regs
0000| 0000 0000             RXBF            .EQU    0               ;receive buffer full bit
0000| 0000 0002             TXBE            .EQU    2               ;transmit buffer empty bit
0000|
0000|                               .PAGE
0000|                               .IF  USERINT = 0
0000|                               .ELSE
0000| 0000 0000             MMU             .EQU    0               ;MMU ERROR
0000| 0000 0001             CPUSEL          .EQU    1               ;CPU selection logic error
0000| 0000 0002             VID             .EQU    2               ;CPU VIDEO LOGIC ERROR
0000| 0000 0003             PAR             .EQU    3               ;CPU PARITY LOGIC ERROR
0000| 0000 0004             CPUINTR         .EQU    4               ;UNEXPECTED INTERRUPT OCCURRED
0000| 0000 0005             BUSEXCP         .EQU    5               ;BUS ERROR
0000| 0000 0006             ADREXCP         .EQU    6               ;ADDRESS ERROR
0000| 0000 0007             MISEXCP         .EQU    7               ;MISC EXCEPTION
0000| 0000 0008             ILLEXCP         .EQU    8               ;ILLEGAL INSTRUCTION ERROR
0000| 0000 0009             TRPEXCP         .EQU    9               ;line 1111 or 1010 trap
0000|
0000| 0000 000A             VIA1            .EQU    10              ;COPS VIA ERROR
0000| 0000 000B             VIA2            .EQU    11              ;PARALLEL PORT VIA ERROR
0000| 0000 000C             IOCOPS          .EQU    12              ;IO BOARD COPS ERROR
0000| 0000 000D             KBDCOPS         .EQU    13              ;KEYBOARD COPS ERROR
0000| 0000 000E             CLK             .EQU    14              ;CLOCK ERROR
0000| 0000 000F             RS232A          .EQU    15              ;RS232 PORT A ERROR
0000| 0000 0010             RS232B          .EQU    16              ;RS232 PORT B ERROR
0000| 0000 0011             DISK            .EQU    17              ;DISK ERROR
0000| 0000 0012             IOEXCP          .EQU    18              ;UNEXPECTED IO EXCEPTION OCCURRED
0000| 0000 0013             IOCOPS2         .EQU    19              ;COPS reset code error
0000| 0000 0014             IOKBD           .EQU    20              ;I/O or keyboard failure
0000|
0000| 0000 0015             MEM             .EQU    21              ;MEMORY ERROR
0000| 0000 0016             MPAR            .EQU    22              ;memory parity error
0000|
0000| 0000 0017             KBDOUT          .EQU    23              ;KEYBOARD DISCONNECTED
0000| 0000 0018             MOUSOUT         .EQU    24              ;MOUSE DISCONNECTED
0000| 0000 0019             IO1ERR          .EQU    25              ;I/O slot 1 failure
0000| 0000 001A             IO2ERR          .EQU    26              ;I/O slot 2 failure
0000| 0000 001B             IO3ERR          .EQU    27              ;I/O slot 3 failure
0000| 0000 001C             ALTBOOT         .EQU    28              ;alternate boot key request
0000| 0000 001D             BTMENU          .EQU    29              ;boot menu request
0000| 0000 001E             WRMSTRT         .EQU    30              ;warm-start indicator
0000|
0000| 0000 001F             LOOP            .EQU    31              ;loop on test
0000| 0E7F FFFF             ERRMSK          .EQU    $0E7FFFFF       ;MASK FOR ERROR CHECKING
0000| 0000 000F             CPUMSK          .EQU    $0000000F       ;MASK FOR CPU ERROR CHECKING
0000| 0000 03F0             EXMSK           .EQU    $000003F0       ;mask for exception error checking
0000| 001F DC00             IOMSK           .EQU    $001FDC00       ;MASK FOR I/O ERROR CHECKING
0000| 0060 0000             MEMMSK          .EQU    $00600000       ;mask for memory error checking
0000| 0180 0000             OTHRMSK         .EQU    $01800000       ;mask for keyboard/mouse check
0000| 0E00 0000             IOSMSK          .EQU    $0E000000       ;mask for I/O slot error checking
0000| 001E 3FFA             CONTMSK         .EQU    $001E3FFA       ;mask for CONTINUE option - allow continue
0000|                                                               ; for MMU,VIDEO,CLK,RS232,MEM,MPAR,KBDOUT,
0000|                                                               ; MOUSOUT,and IO slot errors
0000| 0018 3000             SCANMSK         .EQU    $00183000       ;mask for results of initial keyboard scan
0000| 7000 0000             ALTBMSK         .EQU    $70000000       ;mask for D7 when CONTINUE option invoked
0000| 008F FFFF             BOOTMSK         .EQU    $008FFFFF       ;mask for errors that continue to boot attempt
0000| 001F FFFF             CPIOMSK         .EQU    $001FFFFF       ;mask for checking for CPU and IO errors
0000|                               .ENDC
0000|
0000|                       ;  Equates for error codes displayed to user
0000|
0000|                               .IF  NEWTWIG = 0
0000|                               .ELSE
0000| 0000 0028             EMMU            .EQU    40              ;MMU ERROR
0000| 0000 0029             ECPUSEL         .EQU    41              ;CPU selection logic error
0000| 0000 002A             EVID            .EQU    42              ;CPU VIDEO LOGIC ERROR
0000| 0000 002B             ECPAR           .EQU    43              ;CPU PARITY LOGIC ERROR
0000| 0000 002C             ECPUINTR        .EQU    44              ;UNEXPECTED INTERRUPT OCCURRED
0000| 0000 002D             EBUSEXCP        .EQU    45              ;BUS ERROR
0000| 0000 002E             EADREXCP        .EQU    46              ;ADDRESS ERROR
0000| 0000 002F             EMISEXCP        .EQU    47              ;MISC EXCEPTION
0000| 0000 0030             EILLEXCP        .EQU    48              ;ILLEGAL INSTRUCTION ERROR
0000| 0000 0031             ETRPEXCP        .EQU    49              ;line 1111 or 1010 trap
0000|
0000| 0000 0032             EVIA1           .EQU    50              ;COPS VIA ERROR
0000| 0000 0033             EVIA2           .EQU    51              ;PARALLEL PORT VIA ERROR
0000| 0000 0034             EIOCOP          .EQU    52              ;IO BOARD COPS ERROR
0000| 0000 0035             EKBDCOP         .EQU    53              ;KEYBOARD COPS ERROR
0000| 0000 0036             ECLK            .EQU    54              ;CLOCK ERROR
0000| 0000 0037             ERS232A         .EQU    55              ;RS232 PORT A ERROR
0000| 0000 0038             ERS232B         .EQU    56              ;RS232 PORT B ERROR
0000| 0000 0039             EDISK           .EQU    57              ;DISK ERROR
0000| 0000 003A             EIOEXCP         .EQU    58              ;UNEXPECTED IO EXCEPTION OCCURRED
0000| 0000 003B             EIOCOP2         .EQU    59              ;IO board COPS code error
0000| 0000 003C             EIOKBD          .EQU    60              ;I/O or keyboard error
0000|
0000| 0000 0046             EMEM            .EQU    70              ;R/W MEMORY ERROR
0000| 0000 0047             EPAR            .EQU    71              ;PARITY ERROR
0000| 0000 004B             EBOOT           .EQU    75              ;general boot failure error code
0000|                       ;  Special COPS error codes for burnin cycling
0000|
0000| 0000 003D             SERR1           .EQU    61              ;error setting initial time
0000| 0000 003E             SERR2           .EQU    62              ;error setting alarm
0000|                               .ENDC
0000|                       ;  Secondary status flag (STATFLGS) equates
0000| 0000 0000             NORSTRT         .EQU    0               ;governs display of restart button
0000| 0000 0001             NOCONT          .EQU    1               ;error disallows Monitor CONTINUE option
0000| 0000 0002             MSBUTN          .EQU    2               ;mouse button detected
0000| 0000 0003             CMDFLG          .EQU    3               ;cmd button up/down
0000| 0000 0004             MOUSE           .EQU    4               ;mouse button up/down
0000| 0000 0005             CHKCMD          .EQU    5               ;if =1 user input from keyboard must
0000|                                                               ; be prefaced by CMD key
0000| 0000 0006             BTN             .EQU    6               ;flag for button use
0000| 0000 0007             MENU            .EQU    7               ;flag for menu use
0000|
0000|                       ;  MMU equates
0000|
0000| 0000 8000             MMUSADRL        .EQU    $00008000       ;STARTING MMU LIMIT ADDRESS
0000| 0000 8008             MMUSADRB        .EQU    $00008008       ;STARTING MMU BASE ADDRESS
0000| 00FE 8000             MMUEADRL        .EQU    $00FE8000       ;ENDING MMU LIMIT ADDRESS
0000| 00FE 8008             MMUEADRB        .EQU    $00FE8008       ;ENDING MMU BASE ADDRESS
0000| 0002 0000             ADR128K         .EQU    $00020000       ;128K IN HEX - INCR FOR MMU REGS PTRS
0000| 0000 0100             PAG128K         .EQU    $00000100       ;128K PAGE INCREMENT FOR ORG REGS
0000| 0000 0700             MEMLMT          .EQU    $0700           ;LIMIT VALUE FOR MEMORY SEGMENTS
0000| 0000 08FF             NMEMLMT         .EQU    $08FF           ;INVERSE OF VALUE (HIGH NIBBLE IGNORED)
0000|
0000|                               .IF  ROM4K = 0
0000| 0000 0900             IOLMT           .EQU    $0900           ;LIMIT VALUE FOR I/O SEGMENT
0000| 0000 06FF             NIOLMT          .EQU    $06FF           ;INVERSE
0000| 0000 0901             IOLMT2          .EQU    $0901           ;limit value for no reset feature
0000| 0000 0FFE             RSTLMT          .EQU    $0FFE           ;inverse mask for no reset feature
0000|                               .ELSE
0000|                               .ENDC
0000| 0000 0F00             SPLMT           .EQU    $0F00           ;LIMIT VALUE FOR SPECIAL I/O SPACE
0000| 0000 00FF             NSPLMT          .EQU    $00FF           ;INVERSE
0000| 0000 0C00             INVPAG          .EQU    $0C00           ;INVALID PAGE LIMIT
0000| 0000 8008             MMU0B           .EQU    $00008008       ;ADRESS OF ORG REG 0 (FOR LOW MEMORY)
0000| 0000 8000             MMU0L           .EQU    $00008000       ;ADDRESS OF LIMIT REG 0
0000| 00FC 8008             MMU126B         .EQU    $00FC8008       ;ADDRESS OF ORG REG 126 (FOR I/O SPACE)
0000| 00FC 8000             MMU126L         .EQU    $00FC8000       ;ADDRESS OF LIMIT REG 126
0000| 00FE 8008             MMU127B         .EQU    $00FE8008       ;ADDRESS OF BASE REG 127 (FOR ROM SPACE)
0000| 00FE 8000             MMU127L         .EQU    $00FE8000       ;ADDRESS OF LIMIT REG 127
0000| 00FC E00A             SEG1ON          .EQU    $00FCE00A       ;CONTEXT SELECTION BIT 1 ENABLE
0000| 00FC E008             SEG1OFF         .EQU    $00FCE008       ;CONTEXT SELECTION BIT 1 DISABLE
0000| 00FC E00E             SEG2ON          .EQU    $00FCE00E       ;CONTEXT SELECTION BIT 2 ENABLE
0000| 00FC E00C             SEG2OFF         .EQU    $00FCE00C       ;CONTEXT SELECTION BIT 2 DISABLE
0000|
0000|                       ; Equates for serial number read routine
0000|
0000| 0000 0009             Dlycnst         .equ    9               ;constant for delay loop
0000| 0000 00AC             TKiller         .equ    172             ;time killer constant
0000| 0000 0007             BytesPerRead    .equ    7               ;bytes per read
0000| 0000 000E             WordsPerRead    .equ    BytesPerRead*2  ;during reading one byte fits into one word
0000| 0000 0070             HalfSize        .equ    WordsPerRead*8  ;half the size of ScrachSize
0000| 0000 00E0             ScrachSize      .equ    HalfSize*2      ;size of the scrach array
0000|                                                               ;I/O segment 126
0000| 00FE 8000             Snum            .equ    $0fe8000        ;location of SN1 & SN2
0000|                                                               ;special I/O segment 127
0000| FFFF FFFC             dLcnt           .equ    -4              ;displacement for local variable LOOP COUNTER
0000| FFFF FFF8             dSavArry        .equ    dLcnt-4         ;disp. for Save Array pointer
0000| FFFF FF18             dScrach         .equ    dSavArry-ScrachSize
0000|                                                               ;disp. for pointer to local array SCRACH
0000| FFFF FF18             dStack          .equ    dScrach         ;disp. for the Link
0000|
0000|                       ; Equates for COPS and keyboard scan
0000|
0000| 0000 0086             MOUSDWN         .EQU    $86             ;MOUSE BUTTON PRESSED
0000| 0000 00FF             CMDKEY          .EQU    $FF             ;LEFT COMMAND KEY
0000| 0000 00FD             ALPHKEY         .EQU    $FD             ;ALPHA LOCK KEY "DOWN"
0000|
0000|                               .IF NEWTWIG = 0
0000|                               .ELSE
0000| 0000 00F4             KEY1            .EQU    $F4             ;'1' key - for Twiggy #1 boot
0000| 0000 00F1             KEY2            .EQU    $F1             ;'2' key - for Twiggy #2 boot
0000| 0000 00F2             KEY3            .EQU    $F2             ;'3' key - for Profile boot
0000| 0000 00F0             AKEY            .EQU    $F0             ;'A' key - for I/O slot #3, port 1
0000| 0000 00EE             BKEY            .EQU    $EE             ;'B' key - for I/O slot #3, port 2
0000| 0000 00ED             CKEY            .EQU    $ED             ;'C' key - for I/O slot #3, port 3
0000|                       ;DKEY            .EQU    $FB             ;'D' key - for I/O slot #1, port 4
0000|                       ;EKEY            .EQU    $E0             ;'E' key - for I/O slot #2, port 4
0000|                       ;FKEY            .EQU    $E9             ;'F' key - for I/O slot #3, port 4
0000| 0000 00AF             ENTRKEY         .EQU    $AF             ;Right ENTER key - for Monitor invoking
0000| 0000 00FE             SHFTKEY         .EQU    $FE             ;Shift key - used for power-cycling
0000| 0000 00C4             PKEY            .EQU    $C4             ;'P' key - for Power-cycling
0000|                               .ENDC
0000|
0000| 0000 0080             RSTCODE         .EQU    $80             ;reset code
0000| 0000 00FD             KUNPLG          .EQU    $FD             ;keyboard unplugged
0000| 0000 00FE             ICERR           .EQU    $FE             ;I/O board COPS RAM error
0000| 0000 00FF             KCERR           .EQU    $FF             ;keyboard COPS RAM error
0000| 0000 0007             MSUNPLG         .EQU    $07             ;mouse unplugged
0000| 0000 0087             MSPLG           .EQU    $87             ;mouse plugged in
0000|
0000|                               .IF     EXTERNAL = 1
0000|                               .ENDC
0000|
0000|                       ; Equates for Boot device id's
0000|                               .IF     NEWTWIG = 0
0000|                               .ELSE
0000| 0000 0000             TWIG1           .EQU    $0              ;TWIGGY DRIVE #1
0000| 0000 0001             TWIG2           .EQU    $1              ;TWIGGY DRIVE #2
0000| 0000 0002             PROFILE         .EQU    $2              ;PROFILE HARD DISK
0000| 0000 0003             IO1PORT1        .EQU    $3              ;I/O SLOT 1, port 1
0000| 0000 0004             IO1PORT2        .EQU    $4              ;I/O SLOT 1, port 2
0000| 0000 0006             IO2PORT1        .EQU    $6              ;I/O SLOT 2, port 1
0000| 0000 0007             IO2PORT2        .EQU    $7              ;I/O SLOT 2, port 2
0000| 0000 0009             IO3PORT1        .EQU    $9              ;I/O SLOT 3, port 1
0000| 0000 000A             IO3PORT2        .EQU    $A              ;I/O SLOT 3, port 2
0000| 0000 000F             PC              .EQU    $F              ;power cycle mode
0000| 0000 0010             MON             .EQU    $10             ;abort boot, go to monitor id
0000|
0000|                               .ENDC
0000|                               .IF USERINT = 0
0000|                               .ENDC
0000|
0000|                       ; Equates for device code display (ASCII codes)
0000|
0000|                               .IF  NEWTWIG = 0
0000|                               .ELSE
0000| 0000 0031             TWG1            .EQU    $31             ;Twiggy drive #1
0000| 0000 0032             TWG2            .EQU    $32             ;Twiggy drive #2
0000| 0000 0033             PRO             .EQU    $33             ;Profile
0000| 0000 0034             IOS1            .EQU    $34             ;I/O slot 1
0000| 0000 0037             IOS2            .EQU    $37             ;I/O slot 2
0000| 0000 0041             IOS3            .EQU    $41             ;I/O slot 3
0000|                               .ENDC
0000|
0000|                       ;----------------------------------------------------------------------------------
0000|                       ; Equates for Disk controller shared memory/Twiggy boot
0000|                       ;----------------------------------------------------------------------------------
0000|
0000| 0000 0001             TWIGGY          .EQU    1               ;controls Twiggy code assembly (1 = YES)
0000| 00FC C001             DISKMEM         .EQU    $00FCC001       ;base address of shared memory
0000| 0000 0002             CMD             .EQU    2               ;offset for command byte
0000| 0000 0004             DRV             .EQU    CMD+2           ;offset for drive #
0000| 0000 0006             SIDE            .EQU    DRV+2           ;side #
0000| 0000 0008             SCTR            .EQU    SIDE+2          ;sector #
0000| 0000 000A             TRAK            .EQU    SCTR+2          ;track #
0000|
0000|                               .IF  NEWTWIG = 0
0000|                               .ENDC
0000|                               .IF  NEWTWIG = 1
0000| 0000 000C             SPEED           .EQU    TRAK+2          ;motor speed control
0000| 0000 000E             CNFRM           .EQU    SPEED+2         ;confirm for format cmd
0000| 0000 0010             STAT            .EQU    CNFRM+2         ;error status
0000| 0000 0012             INTLV           .EQU    STAT+2          ;interleave factor                      CHG022
0000| 0000 0014             TYPE            .EQU    INTLV+2         ;drive type id                          CHG009
0000| 0000 0016             STST            .EQU    TYPE+2          ;self-test result                       CHG022
0000| 0000 0030             ROMV            .EQU    $30             ;ROM version #
0000| 0000 0058             RTRYCNT         .EQU    $58             ;retry count
0000| 0000 005E             INTSTAT         .EQU    $5E             ;interrupt status
0000| 0000 00BA             CHKCNT          .EQU    $BA             ;data checksum error count
0000| 0000 00C4             CHKCNT2         .EQU    $C4             ;address checksum error count
0000| 0000 03E8             DSKBUFF         .EQU    $3E8            ;start of disk buffer
0000| 0000 0400             DSKDATA         .EQU    DSKBUFF+24      ;first 12 bytes are header
0000| 00FC C031             DISKROM         .EQU    $FCC031         ;absoulte address for disk ROM id
0000| 0000 0005             SLOTMR          .EQU    5               ;id bit for slow timers                 CHG029
0000| 0000 0006             FASTMR          .EQU    6               ;id bit for fast timers                 CHG029
0000|
0000| 0000 0000             READS           .EQU    0               ;read sector w/checksum
0000| 0000 0001             WRT             .EQU    1
0000| 0000 0002             UNCLAMP         .EQU    2               ;unclamp diskette
0000| 0000 0003             FMT             .EQU    3
0000| 0000 0004             VFY             .EQU    4               ;verify disk
0000| 0000 0009             CLAMP           .EQU    9               ;clamp disk
0000| 0000 00FF             OK              .EQU    $FF             ;confirmation for format
0000|
0000| 0000 0083             SEEK            .EQU    $83             ;seek cmd
0000|                               .ENDC
0000|
0000| 0000 0081             EXRW            .EQU    $81             ;execute cmd
0000| 0000 0085             CLRSTAT         .EQU    $85             ;clear status cmd
0000| 0000 0086             ENBLINT         .EQU    $86             ;enable intrpt
0000| 0000 0087             DSABLINT        .EQU    $87             ;disable intrpt
0000| 0000 0088             SLEEP           .EQU    $88             ;loop in RAM cmd
0000| 0000 0089             DIE             .EQU    $89             ;loop in ROM cmd
0000|
0000| 0000 0000             DRV1            .EQU    0               ;drive #1 ID
0000| 0000 0080             DRV2            .EQU    $80             ;drive #2 ID
0000| 0000 0001             TRK1            .EQU    1               ;track 1
0000| 0000 0000             TOPSIDE         .EQU    0               ;top side of disk
0000| 0000 0001             BOTSIDE         .EQU    1               ;bottom side of disk
0000|
0000|                               .IF NEWTWIG = 0
0000|                               .ENDC
0000|                               .IF NEWTWIG = 1
0000| 0000 000C             HDRLEN          .EQU    12              ;length of Twiggy header
0000| 0000 0200             SECLEN          .EQU    512             ;length of one sector
0000| 0001 FFF4             TWGHDR          .EQU    $1FFF4          ;address to load boot header
0000| 0002 0000             TWGDATA         .EQU    $20000          ;address to load boot data
0000| 0000 06A6             LASTBLK         .EQU    1702            ;last block #
0000| 0000 06A6             DSKSIZE         .EQU    1702            ;total amount of blocks
0000|                               .ENDC
0000|
0000|                       ;  Equates for parameter memory used by boot ROM
0000|
0000| 00FC C161             STATSTRT        .EQU    $FCC161         ;start of special parameter memory area for boot ROM
0000| 00FC C161             STATSAV         .EQU    STATSTRT        ;save of error code
0000| 00FC C17D             STATSUM         .EQU    $FCC17D         ;checksum word for special area
0000| 0000 0008             STATWRDS        .EQU    8               ;length in words (16 bytes)
0000|
0000| 00FC C181             PMSTRT          .EQU    $FCC181         ;start of system paramter memory
0000| 00FC C189             DVCCODE         .EQU    $FCC189         ;boot device code
0000| 00FC C18D             MEMCODE         .EQU    $FCC18D         ;mouse/memory test indicator byte
0000| 0000 0007             MOUSEON         .EQU    7               ;bit for mouse attached (1=yes)
0000| 0000 0006             EXMEM           .EQU    6               ;bit for extended memory test (1=yes)
0000| 00FC C1FD             PMCHKSM         .EQU    $FCC1FD         ;checksum word
0000| 0000 0020             PMWRDS          .EQU    32              ;length in words (64 bytes)
0000|
0000|                       ;  Equates for disk errors
0000|
0000|                               .IF  NEWTWIG = 0
0000|                               .ENDC
0000|                               .IF  NEWTWIG = 1                ;new firmware, new error codes
0000| 0000 0007             DRVERR          .EQU    07              ;no disk in drive
0000| 0000 0007             NODISK          .EQU    DRVERR          ;another name for it
0000| 0000 0014             WRPERR          .EQU    20              ;write protect error
0000| 0000 0016             CLMPERR         .EQU    22              ;clamp error
0000| 0000 0017             RDWRERR         .EQU    23              ;read error
0000| 0000 0019             UCLMPERR        .EQU    25              ;unclamp error
0000| 0000 0026             BADTHDR         .EQU    38              ;bad header (not a boot file id)
0000| 0000 0027             TIMOUT          .EQU    39              ;timeout error
0000|
0000| 0012 0000             CMDTIME         .EQU    $120000         ;timeout for taking command (15 secs)
0000| 00C0 0000             FDIRTIME        .EQU    $C00000         ;timeout for setting FDIR (2 mins)
0000| 0180 0000             VFYTIME         .EQU        ;timeout for verify disk operation (4 mins)
0000| 0018 0000             EJCTTIME        .EQU    $180000         ;timeout for ejecting disk (15 secs)
0000| 001C 8000             DSKTMOUT        .EQU    $1C8000         ;timeout for initial speed check (15 secs)
0000| 00C0 0000             INSRTTIM        .EQU    FDIRTIME        ;timeout for disk to be inserted (2 mins)
0000| 0180 0000             FMTTIME         .EQU    VFYTIME         ;timeout for format operation
0000|                               .ENDC
0000|
0000|                       ;  Equates for disk interrupt status
0000|
0000| 0000 0000             DSK1IN          .EQU    0               ;drive #1 disk in place
0000| 0000 0001             BUTN1           .EQU    1               ;drive #1 button pushed
0000| 0000 0002             RWF1            .EQU    2               ;read/write/format done on drive #1
0000| 0000 0004             DSK2IN          .EQU    4               ;drive #2 disk in place
0000| 0000 0005             BUTN2           .EQU    5               ;drive #2 button pushed
0000| 0000 0006             RWF2            .EQU    6               ;read/write/format done on drive #2
0000|
0000|                       ;  Equates for disk status command response
0000|
0000| 0000 0002             DSKIN           .EQU    2               ;disk inserted
0000| 0000 0003             BUTN            .EQU    3               ;button pressed
0000|
0000| 00FC C015             DRVTYPE         .EQU    $FCC015         ;drive type id (0 = Twiggy,                     CHG009
0000|                                                               ; 1 = single SONY, 2 = double SONY)             CHG009
0000|
0000|                       ;----------------------------------------------------------------------------
0000|                       ;  Equates for use with Profile boot
0000|                       ;----------------------------------------------------------------------------
0000|
0000| 0000 0001             PROFLE          .EQU    1               ;controls assembly of Profile code
0000| 0000 0000             OCD             .EQU    0               ;OPEN CABLE DETECT INPUT
0000| 0000 0001             BSY             .EQU    1               ;BUSY LINE INPUT
0000| 0000 0304             CMDBUFR         .EQU    $304            ;BUFFER FOR COMMAND BYTES
0000| 0000 01B4             STATBFR         .EQU    $1B4            ;STATUS BYTE BUFFER (uses BOOTDATA area)
0000| 0000 01B4             STAT1           .EQU    $1B4            ;STATUS BYTE 1
0000| 0000 01B5             STAT2           .EQU    $1B5            ;STATUS BYTE 2
0000| 0000 01B6             STAT3           .EQU    $1B6            ;STATUS BYTE 3
0000| 0000 01B6             STAT4           .EQU    $1B6            ;STATUS BYTE 4
0000| C140 C000             STATMSK         .EQU    $C140C000       ;MASK FOR DON'T CARE STATUS BITS                CHG016
0000| 0000 0005             PCMDSZ          .EQU    5               ;BYTES FOR READ CMD - 1
0000| 0000 0000             PCMD            .EQU    0               ; COMMAND CODE
0000| 0000 0001             BLKH            .EQU    1               ; HIGH BLOCK ADDRESS
0000| 0000 0002             BLKM            .EQU    2               ; MID BLOCK ADDRESS
0000| 0000 0003             BLKL            .EQU    3               ; LOW BLOCK ADDRESS
0000| 0000 0004             RETRY           .EQU    4               ; RETRY COUNT
0000| 0000 0005             THRESH          .EQU    5               ; THRESHOLD COUNT
0000| 0001 FFEC             HDRBUFR         .EQU    $1FFEC          ;BUFFER FOR HEADER
0000| 0000 0004             FILEID          .EQU    4               ; OFFSET TO FILEID
0000| 0000 AAAA             BOOTPAT         .EQU    $AAAA           ;FILEID FOR BOOT PATTERN
0000| 0002 0000             DATABFR         .EQU    $20000          ;BUFFER FOR DATA
0000| 0000 0014             HDRSIZE         .EQU    20              ;HEADER LENGTH
0000| 0000 0200             BLKSIZE         .EQU    512             ;BLOCK SIZE
0000| 0120 0000             STRTIME         .EQU    $1200000        ;STARTUP TIMEOUT after power-up = about 3 minutes
0000| 0090 0000             RSTRTIME        .EQU    $900000         ;STARTUP TIMEOUT after reset = ABOUT 100 SECS
0000| 0018 0000             RDTIME          .EQU    $180000         ;READ TIMEOUT = ABOUT 16 SECS                   CHG037
0000| 0000 0500             BSYTIME         .EQU    $0500           ;Wait for busy high = about 10 ms
0000| 0000 FFFF             RSPTIME         .EQU    $FFFF           ;RESPONSE TIMEOUT = ABOUT 500 ms
0000| 0000 000A             RCNT            .EQU    10              ;BOOT RETRY COUNT
0000| 0000 0003             TCNT            .EQU    3               ;THRESHOLD COUNT FOR 30% SPARING
0000|
0000|                       ;  Equates for Profile boot error conditions
0000|                               .IF  NEWTWIG = 0
0000|                               .ELSE
0000| 0000 0050             NODSK           .EQU    80              ;DISK NOT ATTACHED
0000| 0000 0051             DSKBSY          .EQU    81              ;DISK NOT READY
0000| 0000 0052             BADRSP          .EQU    82              ;UNEXPECTED RESPONSE
0000| 0000 0053             STATNZ          .EQU    83              ;NONZERO STATUS BYTE
0000| 0000 0054             BADHDR          .EQU    84              ;INCORRECT HEADER
0000| 0000 0055             TMOUT           .EQU    85              ;TIMEOUT ERROR
0000|                               .ENDC
0000|
0000|                       ;----------------------------------------------------------------------------
0000|                       ;  Equates for I/O slot booting
0000|                       ;----------------------------------------------------------------------------
0000|
0000| 00FC 0001             SLOT1L          .EQU    $FC0001         ;I/O slot 1 SL address
0000| 00FC 4001             SLOT2L          .EQU    $FC4001         ;I/O slot 2 SL address
0000| 00FC 8001             SLOT3L          .EQU    $FC8001         ;I/O slot 3 SL address
0000| 0000 000E             STBIT           .EQU    14              ;status bit in id
0000| 0000 000D             ICBIT           .EQU    13              ;icon bit in id
0000| 0000 000C             TSTBIT          .EQU    12              ;test card bit in id
0000| 0002 0000             STENTRY         .EQU    $20000          ;entry point for status routine
0000| 0002 0002             BTENTRY         .EQU    $20002          ;boot routine entry point
0000| 0002 0004             ICONPTR         .EQU    $20004          ;pointer to icons, if any
0000| 0000 8001             APPLENET        .EQU    $8001           ;id for Applenet card
0000| 0000 9FFF             APPLQUAL        .EQU    $9FFF           ;qualifier for Applenet search
0000| 0000 1000             TSTCRD          .EQU    $1000           ;id for test card
0000| 0000 1800             TSTQUAL         .EQU    $1800           ;qualifier for test card search
0000|
0000|                       ;  Error codes for I/O slot booting
0000|
0000|                               .IF NEWTWIG = 0
0000|                               .ELSE
0000| 0000 005A             NOC             .EQU    90              ;no card installed
0000| 0000 005B             INV             .EQU    91              ;not bootable card
0000| 0000 005C             BADSM           .EQU    92              ;invalid checksum
0000| 0000 005D             BADST           .EQU    93              ;bad status returned
0000|                               .ENDC
0000|
0000|
0000|                               .PAGE
0000|                               .IF     BURNIN = 1
0000|                       ;----------------------------------------------------------------------------
0000|                       ;  Special equates for burnin cylcing code
0000|                       ;----------------------------------------------------------------------------
0000|
0000| 00FC C191             INITFLG         .EQU    $FCC191         ;first pass flag (01 = no)
0000| 00FC C193             HOURSAV         .EQU    $FCC193         ;save of last hour value from clock
0000| 00FC C195             LCNTHI          .EQU    $FCC195         ;loop count
0000| 00FC C197             LCNTLO          .EQU    $FCC197
0000| 00FC C199             TIMFLG          .EQU    $FCC199         ;flag to indicate hour save needed
0000| 00FC C19B             MINSAV          .EQU    $FCC19B         ;save of minute value for Twiggy test
0000| 00FC C19D             DSKCNTH         .EQU    $FCC19D         ;disk read error count - high byte
0000| 00FC C19F             DSKCNTL         .EQU    $FCC19F         ;disk read error count - low byte
0000| 00FC C1A1             CLKSAVE         .EQU    $FCC1A1         ;saved clock value
0000| 00FC C1B1             ALRMSAV         .EQU    $FCC1B1         ;saved alarm value last set
0000| 00FC C1C1             CYCLCNT         .EQU    $FCC1C1         ;count of minutes for power cycling
0000| 00FC C1C3             CYCLVAL         .EQU    $FCC1C3         ;# of mins between power cycles
0000| 00FC C1C5             MINCNT          .EQU    $FCC1C5         ;count of minutes for debug mode
0000| 00FC C1FF             ENDPM           .EQU    $FCC1FF         ;end of parameter memory
0000| 0000 0000             SET1            .EQU    $0              ;initial alarm/year/dd setting
0000| 1000 0000             SET2            .EQU    $10000000       ;d/hh/mm/ss/t setting
0000| 0000 01BC             HOUR            .EQU    $1BC            ;location of latest hour value read
0000| 0000 01BD             MINUTE          .EQU    $1BD            ;location of latest minute value read
0000| 00E0 F000             ONEHOUR         .EQU    $00E0F000       ;one hour setting for alarm
0000| 0003 C000             ONEMIN          .EQU    $0003C000       ;one minute setting for alarm
0000| 0000 9000             TENSECS         .EQU    $00009000       ;ten seconds
0000| 0010 0000             DLYTIME         .EQU    $100000         ;delay for screen display
0000|
0000|                               .ENDC
0000|
0000|                               .PAGE
0000|                       ;----------------------------------------------------------------------------
0000|                       ;  Equates for Monitor code and screen handling
0000|                       ;----------------------------------------------------------------------------
0000|
0000|                       ;  Ascii code equates
0000|
0000| 0000 003F             QUESTN          .EQU    $3F             ; ?
0000| 0000 000D             RET             .EQU    $0D             ; CR
0000| 0000 0008             BS              .EQU    $08             ; backspace
0000|
0000|                       ;  Keyboard code equates
0000|
0000| 0000 00F3             KEY4            .EQU    $F3             ;'4'
0000| 0000 00E4             KEY5            .EQU    $E4             ;'5'
0000| 0000 00E1             KEY6            .EQU    $E1             ;'6'
0000| 0000 00E2             KEY7            .EQU    $E2             ;'7'
0000| 0000 00E3             KEY8            .EQU    $E3             ;'8'
0000| 0000 00D0             KEY9            .EQU    $D0             ;'9'
0000| 0000 00F6             SKEY            .EQU    $F6             ;'S'
0000| 0000 00FF             CmdDwn          .EQU    CMDKEY          ;Command key down
0000| 0000 007F             CmdUp           .EQU    $7F             ;Command key up
0000| 0000 0006             MousUp          .EQU    $06             ;Mouse button up
0000|
0000|                       ;  Low memory usage
0000|
0000| 0000 02C0             KBDBFR          .EQU    $2C0            ;keyboard buffer start
0000| 0000 0300             KBDEND          .EQU    $300            ; and end (64 chars max)
0000|
0000|                               .IF  USERINT = 0
0000|                               .ELSE
0000| 0000 0300             CRTROW          .EQU    $300            ;display row ptr
0000| 0000 0302             CRTCOL          .EQU    $302            ;display col ptr
0000|                               .ENDC
0000| 0000 000C             MAXTEST         .EQU    12              ;max test # for LOOP option
0000|                               .IF  USERINT = 0
0000|                               .ELSE
0000|                       ;  Equates for new user interface code
0000|
0000| 0000 005A             ROWBYTES        .EQU    90              ;width of screen in bytes
0000| 0000 02D0             MaxX            .EQU    720             ;width in pixels
0000| 0000 016C             MaxY            .EQU    364             ;length in pixels
0000| 0000 05A0             MENULINE        .EQU    1440            ;bottom line loc for menu
0000| 0000 05FA             DESKLINE        .EQU    1530            ;top line loc for desktop
0000| 0000 7FF8             DESKLMT         .EQU    32760           ;bottom line loc for desktop
0000| AAAA 5555             DESKPATRN       .EQU    $AAAA5555       ;pattern for "grey" desktop
0000|
0000| 0000 0014             WROW            .EQU    20                      ;window row
0000| 0000 0002             WCOL            .EQU    2                       ;starting window col
0000| 0000 0056             WINDWIDTH       .EQU    86                      ;width of window in bytes
0000| 0000 0140             WINDHIGH        .EQU    320                     ;heigth of window in pixel lines
0000| 0000 00B4             WMIDROW         .EQU    +WROW       ;middle row in window
0000| 0000 002D             WMIDCOL         .EQU    +WCOL      ;middle col in window
0000| 0000 0017             W14COL          .EQU    +WCOL      ;col 1/4 across window
0000| 0000 0041             W34COL          .EQU    *3+WCOL    ;col 3/4 across window
0000| 0000 070A             WINDSTRT        .EQU    +WCOL    ;start of window
0000|
0000| 0000 0031             ALBOXROW        .EQU    49                           ;starting row for alert box
0000| 0000 0006             ALBOXCOL        .EQU    6                            ;starting col for alert box
0000| 0000 004E             ALRTWIDTH       .EQU    78                           ;width of alert box
0000| 0000 00A4             ALRTHIGH        .EQU    164                          ;heigth of alert box
0000| 0000 1140             ALRTSTRT        .EQU    +ALBOXCOL ;upper left corner of alert box
0000| 0000 0083             MIDALROW        .EQU    ALBOXROW+        ;middle row of alert box
0000| 0000 002D             MIDALCOL        .EQU    ALBOXCOL+       ;middle col of alert box
0000|
0000| 0000 000A             BTNWIDTH        .EQU    10                      ;width of button
0000| 0000 001C             BTNHIGH         .EQU    28                      ;heigth of button
0000| 0000 10E0             BTNSPC          .EQU    48*ROWBYTES             ;space between upper left corner of buttons
0000| 0000 0392             BTNMSPC         .EQU    <10*ROWBYTES>+BTNWIDTH+4 ;position of button label relative to button
0000| 0000 0045             BTNROW          .EQU    ALBOXROW+20             ;starting display row for buttons
0000| 0000 0034             BTNCOL          .EQU    52                      ;starting display col for buttons
0000| 0000 1876             BTN1STRT        .EQU    +BTNCOL ;location of first button
0000| 0000 2956             BTN2STRT        .EQU    BTN1STRT+BTNSPC         ;location of second button
0000| 0000 3A36             BTN3STRT        .EQU    BTN2STRT+BTNSPC         ;location of third button
0000| 0000 1C08             BTN1MSG         .EQU    BTN1STRT+BTNMSPC        ;location of button descriptions
0000| 0000 2CE8             BTN2MSG         .EQU    BTN2STRT+BTNMSPC
0000| 0000 3DC8             BTN3MSG         .EQU    BTN3STRT+BTNMSPC
0000|
0000| 0000 05A2             MENUSTRT        .EQU    MENULINE+2      ;start of pull down menu
0000| 0000 000B             MENULEN         .EQU    11              ;length of menu per entry
0000| 0000 03DE             MENUSPC         .EQU    990             ;vertical space between menu entries
0000| 0000 0012             MENUWIDTH       .EQU    18              ;width of pull down menu
0000| 0000 0111             MENULOC         .EQU    273             ;start pt for menu heading
0000| 0000 0658             MENU1MSG        .EQU    MENUSTRT+182    ;location of first menu entry
0000| 0000 0010             MBARLEN         .EQU    16              ;heigth of menu bar
0000|
0000| 0000 0007             MITEMS          .EQU    7                          ;number of menu items
0000| 0000 20B4             MENUEND         .EQU    MENUSTRT+  ;bottom of menu
0000|
0000|                               .IF  BMENU = 1
0000| 0000 0012             BMENUWIDTH      .EQU    MENUWIDTH       ;width of pull down menu
0000| 0000 0022             BMENULEN        .EQU    34              ;length of each boot menu entry
0000| 0000 0BF4             BMENUSPC        .EQU       ;vertical space between boot menu entries
0000|                               .ENDC
0000|
0000| 0000 0042             DBOXWIDTH       .EQU    84-MENUWIDTH               ;width of dialog box
0000| 0000 0014             DBOXHIGH        .EQU    20                         ;heigth of dialog box
0000| 0000 0168             DBOXTOP         .EQU    4*ROWBYTES                 ;dialog box spacing down from menu line
0000| 0000 0014             DBOXLEFT        .EQU    MENUWIDTH+2                ;dialog box spacing left from menu
0000| 0000 071E             DBOXSTRT        .EQU    MENUSTRT+DBOXLEFT+DBOXTOP  ;start of dialog box
0000| 0000 0018             DBOXROW         .EQU    +4            ;pixel row for dialog msg
0000| 0000 0018             DBOXCOL         .EQU    MENUWIDTH+6                ;byte col for dialog msg
0000|
0000| 0000 07BC             SVCTOP          .EQU    *ROWBYTES      ;service window spacing down
0000|                                                                          ; from top of dialog box
0000| 0000 0014             SVCLEFT         .EQU    MENUWIDTH+2                ;service window spacing left from menu
0000| 0000 0EDA             SVCSTRT         .EQU    DBOXSTRT+SVCTOP            ;left corner for service window
0000| 0000 0042             SVCWIDTH        .EQU    84-MENUWIDTH               ;width of service window
0000| 0000 0140             SVCHIGH         .EQU    320                        ;length of service window
0000|
0000| 0000 003E             FIRSTROW        .EQU    +20            ;first row for display of msgs
0000| 0000 0018             FIRSTCOL        .EQU    MENUWIDTH+6                ;first column
0000| 0000 012C             ROWSLEFT        .EQU    SVCHIGH-20                 ;pixel rows to bottom of service window
0000| 0000 001B             CHARROWS        .EQU    -3            ;rows used for character display
0000| 0000 014C             LASTROW         .EQU    +FIRSTROW     ;last pixel row for display
0000| 0000 0058             LASTCOL         .EQU    FIRSTCOL+SVCWIDTH-2        ;last column
0000| 0000 000A             ROWLINES        .EQU    10                         ;pixel row lines per character
0000| 0000 0042             ROWLEN          .EQU    |1+1     ;bytes per pixel row (must be even!)
0000| 0000 001B             NROWS           .EQU    /ROWLINES ;number of character rows
0000| 0000 0008             CHRHIGH         .EQU    8                          ;character heigth in pixel lines
0000| 0000 0001             CHRWIDTH        .EQU    1                          ;width of char in bytes
0000| 0000 000A             CHRSPC          .EQU    CHRHIGH+2                  ;vert pixel lines between chars
0000|
0000| 0000 0006             ICONWIDTH       .EQU    6                       ;width in bytes of icons
0000| 0000 0020             ICONHIGH        .EQU    32                      ;heigth of icons in pixel rows
0000|
0000| 0000 0031             TSTROW          .EQU    ALBOXROW                ;starting row for test alert box
0000| 0000 000A             TSTCOL          .EQU    10                       ;starting col for test alert box
0000| 0000 1144             TSTWSTRT        .EQU    +TSTCOL ;test alert box start
0000| 0000 0046             TSTWWIDTH       .EQU    70                       ;width for test alert box
0000| 0000 0054             TSTWHIGH        .EQU    84                      ;heigth for test alert box
0000| 0000 0040             TSTMROW         .EQU    TSTROW+15               ;row for test message display
0000| 0000 000E             TSTMCOL         .EQU    TSTCOL+4                ;col for test message display
0000| 0000 005B             MIDTSTROW       .EQU    TSTROW+     ;middle row of test box
0000| 0000 004B             CHKROW          .EQU    MIDTSTROW-  ;row for check mark display
0000| 0000 0055             TSTIROW         .EQU    CHKROW+10               ;row for test icon display
0000| 0000 0014             TSTICOL         .EQU    TSTCOL+10               ;col for test icon display
0000| 0000 000E             TSTISPC         .EQU    ICONWIDTH+8             ;space between test icons
0000|
0000| 0000 1DF6             CPUSTRT         .EQU    +TSTICOL ;upper left corner for CPU icon
0000| 0000 1E04             MEMSTRT         .EQU    CPUSTRT+TSTISPC            ;upper left corner for MEM icon
0000| 0000 1E12             IOSTRT          .EQU    MEMSTRT+TSTISPC            ;upper left corner for I/O icon
0000| 0000 1E20             XCRDSTRT        .EQU    IOSTRT+TSTISPC             ;upper left corner for slot icon
0000|
0000| 0000 0073             ERRROW          .EQU    MIDALROW-   ;row for error icon display
0000| 0000 0010             ERRCOL          .EQU    ALBOXCOL+10             ;col for error icon display
0000| 0000 287E             ERRSTRT         .EQU    +ERRCOL ;start address for error icon display
0000| 0000 0073             ALRTROW         .EQU    ERRROW                  ;row for alert icon display
0000| 0000 0010             ALRTCOL         .EQU    ERRCOL                  ;col for alert icon display
0000| 0000 0097             CODEROW         .EQU    ERRROW+36               ;row for error code display
0000| 0000 0012             CODECOL         .EQU    ERRCOL+2                ;col for error code display
0000| 0000 007E             MSGROW          .EQU    ALRTROW+11              ;row for alert/error message display
0000| 0000 0018             MSGCOL          .EQU    ALRTCOL+8               ;col for alert/error message display
0000| 0000 0010             MEMROW          .EQU    16                      ;offset row for memory board id # display
0000| 0000 0004             MEMCOL          .EQU    4                       ;offset col for memory board id # display
0000| 0000 0012             DISKROW         .EQU    18                      ;offset row for diskette id # display
0000| 0000 0004             DISKCOL         .EQU    4                       ;offset col for diskette id # display    CHG024
0000| 0000 0016             SLOTROW         .EQU    22                      ;offset row for slot card id # display
0000| 0000 0003             SLOTCOL         .EQU    3                       ;offset col for slot card id # display
0000| 0000 0006             DRVROW          .EQU    6                       ;offset row for drive id # display       CHG009
0000| 0000 0003             DRVCOL          .EQU    3                       ;offset col for drive id # display       CHG009
0000| 0000 0005             INSRTROW        .EQU    5                       ;offset row for insert rqst id # display CHG009/CHG024
0000| 0000 0004             INSRTCOL        .EQU    4                       ;offset col for insert rqst id # display CHG009
0000|
0000|
0000| 0000 00A4             DEFROW          .EQU    WMIDROW-      ;row for default boot icon display
0000| 0000 003E             DEFCOL          .EQU    W34COL-      ;col for default boot icon display
0000| 0000 39E6             DEFSTRT         .EQU    +DEFCOL  ;start address for default boot icon
0000| 0000 0014             ALTCOL          .EQU    W14COL-      ;col for alternate boot icon display
0000| 0000 1B72             COL1STRT        .EQU    <78*ROWBYTES>+6           ;start for first column of boot icons
0000| 0000 1B7E             COL2STRT        .EQU    COL1STRT+12               ;start for second col of boot icons
0000| 0000 39BC             COL2MID         .EQU    +ALTCOL  ;middle of second col
0000| 0000 1B8A             COL3STRT        .EQU    COL2STRT+12               ;start for third col of boot icons
0000| 0000 1680             ICONCSPC        .EQU    <64*ROWBYTES>             ;space between left corner of icons in col
0000| 0000 0440             ICONMSPC        .EQU    <12*ROWBYTES>+6+2         ;start addr offset for boot icon alternate keycode
0000| 0000 000C             ICONRSPC        .EQU    12                        ;space in between cols in same row
0000|
0000| 0000 0445             ALTKYADDR       .EQU    ICONMSPC+5      ;address offset for display of alternate keycode in menu bar
0000|
0000| 0000 0056             PCWIDTH         .EQU    86              ;width of window for power cycling msgs
0000| 0000 00C0             PCHIGH          .EQU    192             ;height of window
0000| 0000 070A             PCSTRT          .EQU    WINDSTRT        ;upper left corner of window
0000| 0000 0059             PCROW           .EQU    ALBOXROW+40     ;first row for power cycle msgs
0000| 0000 000C             PCCOL           .EQU    ALBOXCOL+6      ;first col for power cycle msgs
0000|
0000| 0000 0003             ROMIDROW        .EQU    3               ;cursor row ptr for ROM id display              CHG001
0000| 0000 0050             ROMIDCOL        .EQU    80              ;cursor col ptr for ROM id display              CHG001
0000|
0000|                               .IF  DEBUG = 0
0000| 0000 0480             GLOBALS         .EQU    STKBASE         ;start of global area for mouse/cursor
0000|                               .ELSE
0000|                               .ENDC
0000|
0000| 0000 0480             ClockBytes      .EQU    Globals         ;clock data save area
0000| 0000 0486             MousX           .EQU    ClockBytes+6    ;mouse X-coordinate (word)
0000| 0000 0488             MousY           .EQU    MousX+2         ;mouse Y-coordinate (word)
0000| 0000 048A             MousDx          .EQU    MousY+2         ;mouse delta-x (byte)
0000| 0000 048B             MousDy          .EQU    MousDx+1        ;mouse delta-y (byte)
0000| 0000 048C             MousScaling     .EQU    MousDy+1        ;0=disabled, else=enabled (byte)
0000| 0000 048E             MousThresh      .EQU    MousScale|1+1   ;mouse movement threshold (word)
0000|
0000| 0000 0490             CrsrHotx        .EQU    MousThresh+2    ;hotspot X-coordinate (word)
0000| 0000 0492             CrsrHoty        .EQU    CrsrHotX+2      ;hotspot Y-coordinate (word)
0000| 0000 0494             CrsrHeight      .EQU    CrsrHotY+2      ;cursor height, 0-32 (word)
0000| 0000 0496             CrsrX           .EQU    CrsrHeight+2    ;cursor X-coordinate (word)
0000| 0000 0498             CrsrY           .EQU    CrsrX+2         ;cursor Y-coordinate (word)
0000| 0000 049A             CrsrTracking    .EQU    CrsrY+2         ;0=disabled, else=enabled (byte)
0000| 0000 049B             CrsrBusy        .EQU    CrsrTracking+1  ;0=not busy, else=busy (byte)
0000| 0000 049C             CrsrVisible     .EQU    CrsrBusy+1      ;0=not visible, else=visible (byte)
0000| 0000 049E             CrsrHidden      .EQU    CrsrVisible|1+1 ;<=0 implies hiddden (word)
0000| 0000 04A0             CrsrObscured    .EQU    CrsrHidden+2    ;0=not obscured, else=obscured (byte)
0000|
0000| 0000 04A2             SavedData       .EQU    CrsrObscured+2  ;data from under cursor (128 bytes)
0000| 0000 0522             SavedX          .EQU    SavedData+128   ;saved data X-coordinate (word)
0000| 0000 0524             SavedY          .EQU    SavedX+2        ;saved data Y-coordinate (word)
0000| 0000 0526             SavedRows       .EQU    SavedY+2        ;rows of saved data (word)
0000| 0000 0528             SavedAddr       .EQU    SavedRows+2     ;saved data screen address (long)
0000|
0000| 0000 052C             LwrRight        .EQU    SavedAddr+4     ;saved lower right corner address (word)
0000| 0000 052E             MsgLen          .EQU    LwrRight+2      ;length of dialog box msg (word)
0000|
0000|                               .IF  BMENU = 0
0000|                               .ELSE
0000| 0000 0530             MenuBase        .EQU    Msglen+2        ;address of last boot menu "box" (word)
0000| 0000 0532             IconAddr        .EQU    MenuBase+2      ;address for last boot icon displayed (word)
0000|                               .ENDC
0000|
0000| 0000 0534             IconCnt         .EQU    IconAddr+2      ;count of boot icons displayed (byte)
0000|
0000| 0000 0535             DRIVE           .EQU    IconCnt+1       ;drive id for dump/verify options (byte)
0000| 0000 0536             BLKNUM          .EQU    DRIVE+1         ;block # for dump option (word)
0000| 0000 0538             CONTXT          .EQU    BLKNUM+2        ;context for dump of MMU contents (byte)
0000|
0000| 0000 053A             RectCnt         .EQU    CONTXT+2        ;count for active rect table (word)
0000| 0000 053A             RectTable       .EQU    RectCnt         ;active rectangle table (same start)
0000|
0000|                               .ENDC
0000|                               .PAGE
0000|                       ;----------------------------------------------------------------------------
0000|                       ; The following memory locations are reserved for ROM use to save test data
0000|                       ;----------------------------------------------------------------------------
0000|
0000| 0000 0180             STATUS          .EQU    $0180           ;POWER-UP STATUS (0=OK)
0000| 0000 0184             SIZRSLT         .EQU    STATUS+4        ;memory sizing test results
0000| 0000 0186             MEMRSLT         .EQU    SIZRSLT+2       ;MEMORY TEST RESULTS
0000| 0000 0188             BOOTMEM         .EQU    MEMRSLT+2       ;result for boot area of memory (128K)
0000| 0000 01A6             PEADDR          .EQU    MEMRSLT+32      ;PARITY ERROR ADDRESS
0000| 0000 01AA             ADRLTCH         .EQU    PEADDR+4        ;CONTENTS OF MEMORY ADDRESS LATCH
0000| 0000 01AC             D7SAV           .EQU    ADRLTCH+2       ;save for D7 when exception occurs
0000| 0000 01B0             MMURSLT         .EQU    $01B0           ;MMU TEST RESULTS
0000| 0000 01B2             KEYID           .EQU    $01B2           ;Keyboard ID
0000| 0000 01B3             BOOTDVCE        .EQU    $01B3           ;BOOT DEVICE CODE
0000| 0000 01B4             BOOTDATA        .EQU    $01B4           ;BOOT FAILURE DATA
0000| 0000 01BA             CLKDATA         .EQU    $01BA           ;CLOCK SETTING READ
0000| 0000 01C0             DATARGS         .EQU    $01C0           ;DATA REG SAVE AREA
0000| 0000 01E0             ADRREGS         .EQU    $01E0           ;ADDRESS REG SAVE AREA
0000| 0000 01F8             A6SAV           .EQU    $01F8           ;SAVE AREA FOR REG A6
0000| 0000 01FC             USPSAV          .EQU    $01FC           ;SAVE AREA FOR USER STACK PTR
0000|
0000| 0000 0240             SERNUM          .EQU    $0240           ;saved serial number (28 bytes)
0000| 0000 0260             KBDQPTR         .EQU    $0260           ;ptr for keyboard queue
0000|
0000| 0000 0268             XPCTADDR        .EQU    $0268           ;memory test address for parity error           CHG015
0000| 0000 026C             XPCTDATA        .EQU    $026C           ;memory test expected data                      CHG015
0000| 0000 0270             ACTADDR         .EQU    $0270           ;parity error address, phase 2                  CHG015
0000| 0000 0274             ACTDATA         .EQU    $0274           ;actual data read on parity error, phase 2      CHG015
0000| 0000 0278             PEADR2          .EQU    $0278           ;address read from error latch                  CHG015
0000| 0000 027C             PCHPROW         .EQU    $027C           ;parity chip row                                CHG015
0000| 0000 027D             PCHIP           .EQU    $027D           ;parity chip id                                 CHG015
0000|
0000| 0000 0280             EXCFC           .EQU    $0280           ; bus function code
0000| 0000 0282             EXCADR          .EQU    $0282           ; address of error
0000| 0000 0286             EXCIR           .EQU    $0286           ; instruction reg
0000| 0000 0288             EXCSR           .EQU    $0288           ; status reg
0000| 0000 028A             EXCPC           .EQU    $028A           ; PC at time of exception
0000| 0000 028E             EXCTYPE         .EQU    $028E           ; exception type
0000| 0000 0290             SUPSTK          .EQU    $0290           ;SUPERVISOR STACK PTR
0000| 0000 0294             MAXMEM          .EQU    $0294           ;MAX MEMORY ADDRESS + 1
0000| 0000 0298             IO1ID           .EQU    $0298           ;I/O SLOT 1 ID
0000| 0000 029A             IO2ID           .EQU    $029A           ;I/O SLOT 2 ID
0000| 0000 029C             IO3ID           .EQU    $029C           ;I/O SLOT 3 ID
0000| 0000 029E             IO1STAT         .EQU    $029E           ;I/O SLOT 1 STATUS
0000| 0000 029F             IO2STAT         .EQU    $029F           ;I/O SLOT 2 STATUS
0000| 0000 02A0             IO3STAT         .EQU    $02A0           ;I/O SLOT 3 STATUS
0000| 0000 02A1             IOROM           .EQU    $02A1           ;I/O ROM VERSION #
0000| 0000 02A2             STATFLGS        .EQU    $02A2           ;additional status indicators
0000| 0000 02A4             MINMEM          .EQU    $02A4           ;MINIMUM PHYSICAL ADDRESS
0000| 0000 02A8             TOTLMEM         .EQU    $02A8           ;total amount of memory
0000| 0000 02AC             SCCRSLT         .EQU    $02AC           ;SCC test results
0000| 0000 02AD             MEMSLOT         .EQU    $02AD           ;Slot # for memory board if memory error
0000| 0000 02AE             DSKRSLT         .EQU    $02AE           ;Disk controller self-test status byte (0=no error)
0000| 0000 02AF             SYSTYPE         .EQU    $02AF           ;System type (0 = Lisa 1; 1, 2, 3 = Lisa 2)        CHG029
0000| 0000 02B0             KBDQ            .EQU    $02B0           ;KEYBOARD QUEUE
0000| 0000 02C0             QEND            .EQU    $02C0           ;END OF Q
0000|
0000|                               .INCLUDE RM248.K.TEXT
0000|
0000|                               .IF     EXTERNAL = 1
0000|                               .ENDC
0000|
0000|                               .PAGE
0000|                       ;        .ABSOLUTE               ;makes listing look nicer
0000|                               .PROC   LISAROM,0
0000|
0000|                               .ORG    0               ; ORG'ED AT 0 BUT RUNS AT $00FE0000
0000|
0000|                       ;  Reset vectors here to pick up SP and PC values
0000|
0000|                       BASE
0000| 0000                          .WORD   $0000           ;initial SP
0002| 0480                          .WORD   STKBASE
0004|
0004| 00FE                          .WORD   ROMSLCT         ;initial PC (assumes use of MMU reg 127)
0006| 00F6                          .WORD   BEGIN
0008|
0008|                       ;  Set up next locations for exception vectors
0008|
0008| 00FE                  BUSVCT  .WORD   ROMSLCT           ; BUS ERROR VECTOR
000A| 0030                          .WORD   EXCPERR
000C| 00FE                  ADRVCT  .WORD   ROMSLCT           ; ADDRESS ERROR
000E| 0030                          .WORD   EXCPERR
0010| 00FE                  ILLVCT  .WORD   ROMSLCT           ; ILLEGAL INSTRUCTION
0012| 0030                          .WORD   EXCPERR
0014| 00FE                  DIV0VCT .WORD   ROMSLCT           ; DIVIDE BY ZERO ERROR
0016| 0030                          .WORD   EXCPERR
0018| 00FE                  CHKVCT  .WORD   ROMSLCT           ; CHK INSTRUCTION
001A| 0030                          .WORD   EXCPERR
001C| 00FE                  TRAPVCT .WORD   ROMSLCT           ; TRAPV INSTRUCTION
001E| 0030                          .WORD   EXCPERR
0020| 00FE                  PRIVCT  .WORD   ROMSLCT           ; PRIVILEGE VIOLATION
0022| 0030                          .WORD   EXCPERR
0024| 00FE                  TRCVCT  .WORD   ROMSLCT           ; TRACE OPERATION
0026| 0030                          .WORD   EXCPERR
0028| 00FE                  L10VCT  .WORD   ROMSLCT           ; OPCODE 1010 DETECTED
002A| 0030                          .WORD   EXCPERR
002C| 00FE                  L11VCT  .WORD   ROMSLCT           ; OPCODE 1111 DETECTED
002E| 0030                          .WORD   EXCPERR
0030|
0030|                       ;------------------------------------------------------------------
0030|                       ;  Exception and interrupt vector handler for ROM - resets SP and
0030|                       ;  tries a restart
0030|                       ;------------------------------------------------------------------
0030|
0030| 3E7C 0480             EXCPERR MOVEA   #STKBASE,SP     ;reset stack ptr
0034| 4287                          CLR.L   D7              ;clear error indicator                  CHG004
0036| 6000 015C                     BRA     ROMTST          ;and restart diags                      CHG004
003A|
003A|                               .PAGE
003A|
003A|                       ;--------------------------------------------------------------------
003A|                       ;  Subroutine for saving registers and stack pointers
003A|                       ;--------------------------------------------------------------------
003A|                       SAVEREGS
003A| 21CF 0290                     MOVE.L  SP,SUPSTK       ;save sup stack ptr
003E|                       SAVEREG2
003E| 21CE 01F8                     MOVE.L  A6,A6SAV        ;save other regs (that aren't reset)
0042| 4E6E                          MOVE.L  USP,A6
0044| 21CE 01FC                     MOVE.L  A6,USPSAV
0048| 3C7C 01F8                     MOVE    #A6SAV,A6       ;set ptr for saving regs
004C| 48E6 FFFC                     MOVEM.L D0-D7/A0-A5,-(A6)
0050| 4E75                          RTS
0052|
0052|                       ;  use spare bytes for message
0052|
0052| 53 45 52 56 49 43 45  SVCMSG  .ASCII  'SERVICE MODE'  ;                                       RM000
0059| 20 4D 4F 44 45
005E| 00                            .BYTE   0               ;                                       RM000
005F|
005F| 00                            .ORG    $60
0060|
0060|                       ;  The next set of vectors cover spurious and autovector interrupts
0060|
0060| 00FE                  SPURVCT .WORD   ROMSLCT           ; SPURIOUS INTERRUPT
0062| 0030                          .WORD   EXCPERR
0064| 00FE                  LVL1VCT .WORD   ROMSLCT           ; INTERNAL I/O INTERRUPTS (DISK,VERT TRACE,ETC.)
0066| 0030                          .WORD   EXCPERR
0068| 00FE                  LVL2VCT .WORD   ROMSLCT           ; KEYBOARD INTERRUPT
006A| 0030                          .WORD   EXCPERR
006C| 00FE                  LVL3VCT .WORD   ROMSLCT           ; I/O SLOT 2 INTERRUPT
006E| 0030                          .WORD   EXCPERR
0070| 00FE                  LVL4VCT .WORD   ROMSLCT           ; I/O SLOT 1
0072| 0030                          .WORD   EXCPERR
0074| 00FE                  LVL5VCT .WORD   ROMSLCT           ; I/O SLOT 0
0076| 0030                          .WORD   EXCPERR
0078| 00FE                  LVL6VCT .WORD   ROMSLCT           ; RS-232
007A| 0030                          .WORD   EXCPERR
007C| 00FE                  LVL7VCT .WORD   ROMSLCT           ; NMI
007E| 00CA                          .WORD   NMIEXCP           ;                                     RM010
0080|
0080|                               .IF     EXTERNAL = 1
0080|                               .ENDC
0080|
0080|                               .PAGE
0080|                               .ORG    $80
0080|                       ;-------------------------------------------------------------------------
0080|                       ;  Jump Table for calling by external routines
0080|                       ;-------------------------------------------------------------------------
0080|
0080|                       JMPTBL
0080| 4EFA 25D0                     JMP     DORESET         ;go to restart point                    RM000
0084| 4EFA 24AE                     JMP     INITMON         ;jump to ROM Monitor
0088|
0088|                               .IF  USERINT = 0
0088|                               .ELSE
0088| 4EFA 3664                     JMP     CONVRTD5        ;convert row ptr and display message
008C|                               .ENDC
008C|
008C| 4EFA 052C                     JMP     WRTMMU          ;write to set of MMU registers
0090| 4EFA 1EDE                     JMP     PROREAD         ;Profile read a block routine
0094| 4EFA 1CE0                     JMP     TWGREAD         ;Twiggy read a sector routine
0098|
0098|                               .IF  DIAGS = 1
0098| 4EFA 0E16                     JMP     RAMTEST         ;basic memory test
009C| 4E71                          NOP                     ;                                       CHG015
009E| 4E75                          RTS                     ;                                       CHG015
00A0| 4E71                          NOP                     ;                                       CHG015
00A2| 4E75                          RTS                     ;                                       CHG015
00A4|                               .ENDC
00A4|
00A4| 4EFA 052A                     JMP     READMMU         ;read MMU registers
00A8| 4EFA 08AC                     JMP     COPSCMD         ;Send COPS command
00AC|
00AC|                               .IF  DIAGS = 1
00AC| 4EFA 11F2                     JMP     READCLK         ;Read clock setting
00B0|                               .ELSE
00B0|                               .ENDC
00B0|
00B0| 4EFA 157E                     JMP     DSPDEC          ;display hex error code in decimal
00B4| 4EFA 074C                     JMP     CONSET2         ;for setting contrast
00B8| 4EFA 0A3C                     JMP     TONE            ;to beep speaker
00BC| 4EFA 17CE                     JMP     VFYCHKSM        ;verify checksum
00C0|
00C0|                               .IF  ROM4K = 0
00C0| 4EFA 17BC                     JMP     WRTSUM          ;rewrite parameter memory               CHG017
00C4| 4EFA 0B30                     JMP     RDSERN          ;go read system serial #
00C8|                               .ENDC
00C8|
00C8|                       ;******************** Loop point for ROM test failure ********************************
00C8| 60FE                  SPIN    BRA.S   SPIN            ;hang system                                    CHG007
00CA|
00CA|                       ;*************************************************************************************
00CA|
00CA|                               .IF     EXTERNAL = 1
00CA|                               .ENDC
00CA|
00CA|                       ;----------------------------------------------------------------------------
00CA|                       ;  NMI Exception Handler                                                        RM010
00CA|                       ;----------------------------------------------------------------------------
00CA|
00CA| 4239 00FC E012        NMIEXCP CLR.B   SETUP           ;enable memory access                           RM010
00D0| 0839 0001 00FC F801           BTST    #1,STATREG      ;parity error?                                  RM010
00D8| 6614                          BNE.S   @1              ;skip if not to ignore                          RM010
00DA| 31F9 00FC F000 01AA           MOVE    MEALTCH,ADRLTCH ;save address if yes                            RM010
00E2| 4A39 00FC E01C                TST.B   PAROFF          ;and toggle to clear error bit                  RM010
00E8| 4A39 00FC E01E                TST.B   PARON           ;                                               RM010
00EE| 4A39 00FC E010        @1      TST.B   SETUPON         ;return to SETUP state                          RM010
00F4| 4E73                          RTE                     ;                                               RM010
00F6|
00F6|                               .PAGE
00F6|                       ;----------------------------------------------------------------------------
00F6|                       ;  First do "warm-start" no reset check - scan I/O MMU regs to see if set up
00F6|                       ;----------------------------------------------------------------------------
00F6|
00F6|                       BEGIN
00F6|                               .IF     NORESET = 1
00F6| 3039 00FC 8000                MOVE    MMU126L,D0      ;check reg 126 for special I/O space
00FC| 0240 0FFF                     ANDI    #$0FFF,D0       ;ignore don't care bits
0100| 0C40 0901                     CMPI    #IOLMT2,D0      ;for no reset, 126L = $x901  (x = random value)
0104| 664C                          BNE.S   BEGIN2          ;skip if not set up
0106| 0279 0FFF 00FC 8008           ANDI    #$0FFF,MMU126B  ;else also check 126B = $x000
010E| 6642                          BNE.S   BEGIN2
0110|
0110|                       ;  Check OK - set MMU for ROM access and change SETUP before vectoring
0110|
0110| 33FC 0700 0000 8000           MOVE    #MEMLMT,MMU0L   ;set low memory for r/w (to save regs,etc.)
0118| 33FC 0901 00FC 8000           MOVE    #IOLMT2,MMU126L ;set for I/O space access (reset value)
0120| 33FC 0F00 00FE 8000           MOVE    #SPLMT,MMU127L  ;set access for ROM space
0128| 4279 00FE 8008                MOVE    #0,MMU127B
012E| 4239 00FC E012                CLR.B   SETUP           ;enable memory access
0134|
0134| 21CF 0290                     MOVE.L  SP,SUPSTK       ;save supervisor stack ptr
0138| 3E7C 0480                     MOVEA   #STKBASE,SP     ;move stack pointer for ROM use
013C| 6100 FF00                     BSR.S   SAVEREG2        ;save other registers
0140|
0140|                       ;  Restore ROM Monitor environment
0140|
0140|                               BSR4    CONSET          ;go set default contrast
0140| 49FA 0006            #          LEA      @1,A4
0144| 6000 06B4            #          BRA      CONSET
0148|                      #@1
0148| 95CA                          SUBA.L  A2,A2           ;set for no icons
014A| 4280                          CLR.L   D0              ; error codes
014C| 97CB                          SUBA.L  A3,A3           ;  or messages
014E| 6000 23F4                     BRA     INIT1           ;exit directly to monitor (avoid resaving regs)
0152|
0152|                               .ENDC
0152|
0152|                       ;-------------------------------------------------------------------------
0152|                       ;  Do second warm-start check to see if contrast should be reset
0152|                       ;-------------------------------------------------------------------------
0152|
0152| 4287                  BEGIN2  CLR.L   D7              ;clear for error use
0154| 3039 00FE 8000                MOVE    MMU127L,D0      ;check reg 127 for ROM space
015A| 0240 0FFF                     ANDI    #$0FFF,D0       ;ignore don't care bits
015E| 0C40 0F00                     CMPI    #SPLMT,D0       ;expect 127L = $xF00  (x = random value)
0162| 6630                          BNE.S   ROMTST          ;skip if not
0164| 0279 0FFF 00FE 8008           ANDI    #$0FFF,MMU127B  ;else check if 127B = $x000
016C| 6626                          BNE.S   ROMTST
016E|
016E|                       ;  Check OK - set MMU for I/O and ROM access and go set contrast
016E|
016E| 08C7 001E                     BSET    #WRMSTRT,D7     ;set warm start indicator
0172| 7000                          MOVEQ   #0,D0           ;clear for use
0174| 33FC 0900 00FC 8000           MOVE    #IOLMT,MMU126L  ;set access for I/O space
017C| 33C0 00FC 8008                MOVE    D0,MMU126B
0182| 33FC 0F00 00FE 8000           MOVE    #SPLMT,MMU127L  ;set access for ROM space
018A|
018A| 4E70                  BEGIN3  RESET                   ;ensure clean I/O state for "warm-start"
018C|
018C|                               .IF  NEWLISA = 1
018C|                               BSR4    CONOFF          ;and go disable contrast
018C| 49FA 0006            #          LEA      @1,A4
0190| 6000 066E            #          BRA      CONOFF
0194|                      #@1
0194|                               .ELSE
0194|                               .ENDC
0194|
0194|
0194|                               .PAGE
0194|                       ;-------------------------------------------------------------------------
0194|                       ;  Start diagnostics - do ROM checksum test first; expected result = 0
0194|                       ;-------------------------------------------------------------------------
0194|
0194|                       ROMTST
0194|                               .IF  DIAGS = 1
0194|
0194| 4280                          CLR.L   D0              ;clear for checksum use
0196| 41FA FE68                     LEA     BASE,A0         ;init ROM address ptrs
019A| 43FA 3E62                     LEA     LAST,A1
019E| D058                  DOSUM   ADD     (A0)+,D0        ;read location and add to sum
01A0| E358                          ROL     #1,D0           ;rotate to catch multiple bit errors
01A2| B3C8                          CMPA.L  A0,A1           ;loop until done
01A4| 66F8                          BNE.S   DOSUM
01A6| D058                          ADD     (A0)+,D0        ;add checksum word
01A8| 6600 FF1E                     BNE     SPIN            ;loop if error                          CHG007
01AC| 4A87                          TST.L   D7              ;in loop mode?
01AE| 6BE4                          BMI.S   ROMTST          ;restart test if yes
01B0|
01B0|                               .ENDC
01B0|                               .PAGE
01B0|                       ;----------------------------------------------------------------------------
01B0|                       ;  Next do read/write and address test of MMU supervisor regs
01B0|                       ;  Register Usage (by this routine and/or its subroutines):
01B0|                       ;       A0 = MMU reg pointer            D0 = test pattern
01B0|                       ;       A1 = last MMU limit reg addr    D1 = contents read from MMU reg
01B0|                       ;       A2 = MMU address increment      D2 = OR mask of results
01B0|                       ;       A3 = last MMU base reg addr     D3 = pattern expected at last error
01B0|                       ;       A4 = used for return address    D4 = final value for MMU reg
01B0|                       ;       A5 = MMU address of last error  D5 = unused
01B0|                       ;       A6 = used for return address    D6 = unused
01B0|                       ;       A7 = stack pointer              D7 = error indicator (0 = R/W error)
01B0|                       ;----------------------------------------------------------------------------
01B0|
01B0|                       MMUTST
01B0|                               .IF     DIAGS = 1
01B0|                               BSR4    MMUINIT         ;initialize test variables
01B0| 49FA 0006            #          LEA      @1,A4
01B4| 6000 0060            #          BRA      MMUINIT
01B8|                      #@1
01B8|                               BSR6    MMURW           ;and go do read/write test
01B8| 4DFA 0006            #          LEA      @1,A6
01BC| 6000 006C            #          BRA      MMURW
01C0|                      #@1
01C0| 6616                          BNE.S   MMUERR          ;abort if error
01C2|
01C2|                               BSRS4   MMUINIT         ;reinitialize
01C2| 49FA 0004            #          LEA      @1,A4
01C6| 604E                 #          BRA.S    MMUINIT
01C8|                      #@1
01C8|                               BSR6    MMUACHK         ;and do address test
01C8| 4DFA 0006            #          LEA      @1,A6
01CC| 6000 00A2            #          BRA      MMUACHK
01D0|                      #@1
01D0| 6604                          BNE.S   @2              ;skip if error
01D2| 6000 00F2                     BRA     SETMMU          ;else go do initial MMU setup
01D6| 4647                  @2      NOT     D7              ;set address error indicator
01D8|
01D8|                               .PAGE
01D8|                       ;----------------------------------------------------------------------------
01D8|                       ;  The following code is used to toggle every address and data line
01D8|                       ;  going to the MMU if an error in the MMU context 0 tests is found.
01D8|                       ;  Reset signals indicate read/write or addressing error.
01D8|                       ;----------------------------------------------------------------------------
01D8|
01D8| 4A47                  MMUERR  TST     D7              ;check error type
01DA| 6702                          BEQ.S   @2
01DC| 4E70                          RESET                   ;two reset signals for address error
01DE| 4E70                  @2      RESET                   ;only one for R/W error
01E0|
01E0|                       ;  Toggle every data and address bit
01E0|
01E0| 207C 0002 8000        MMULP   MOVE.L  #$00028000,A0   ;set MMU limit reg start address
01E6| 7201                          MOVEQ   #1,D1           ;and starting data pattern
01E8| 7407                          MOVEQ   #7,D2           ;and loop count
01EA|                               BSRS4   TSTLOOP         ;go toggle for limit regs
01EA| 49FA 0004            #          LEA      @1,A4
01EE| 6010                 #          BRA.S    TSTLOOP
01F0|                      #@1
01F0| 207C 0002 8008                MOVE.L  #$00028008,A0   ;set MMU base reg start address
01F6| 7405                          MOVEQ   #5,D2           ;and loop count
01F8|                               BSRS4   TSTLOOP         ;go test base regs
01F8| 49FA 0004            #          LEA      @1,A4
01FC| 6002                 #          BRA.S    TSTLOOP
01FE|                      #@1
01FE|
01FE| 60D8                          BRA.S   MMUERR          ;and loop indefinitely
0200|                       ;  Subroutine to do reg testing
0200|
0200| 2008                  TSTLOOP MOVE.L  A0,D0           ;save starting address
0202| 3081                  REGTST  MOVE    D1,(A0)         ;do write
0204| 3610                          MOVE    (A0),D3         ;then read
0206| E349                          LSL     #1,D1           ;update pattern
0208| 4840                          SWAP    D0              ;get address
020A| E348                          LSL     #1,D0           ;update and restore
020C| 4840                          SWAP    D0
020E| 2040                          MOVE.L  D0,A0
0210| 5342                          SUBQ    #1,D2           ;loop until done
0212| 66EE                          BNE.S   REGTST
0214|                               RTS4                    ;exit
0214| 4ED4                 #          JMP      (A4)
0216|
0216|                               .PAGE
0216|                       ;----------------------------------------------------------------------------
0216|                       ;  Subroutine to do initial setup for MMU testing
0216|                       ;----------------------------------------------------------------------------
0216|
0216| 303C A55A             MMUINIT MOVE    #PATRN2,D0      ;set test pattern
021A| 7200                          MOVEQ   #0,D1           ;clear for result/error use
021C| 7400                          MOVEQ   #0,D2           ; use MOVEQ for speed
021E| 247C 0002 0000                MOVE.L  #ADR128K,A2     ;set up increment value
0224| 007C 0710                     ORI     #$0710,SR       ;set extend bit and disable interrupts
0228|                               RTS4
0228| 4ED4                 #          JMP      (A4)
022A|
022A|                               .PAGE
022A|                       ;----------------------------------------------------------------------------
022A|                       ;  Subroutine to do MMU Read/Write Test for all registers in one context.
022A|                       ;  Zero bit set in CCR if no errors.
022A|                       ;----------------------------------------------------------------------------
022A|
022A| 207C 0000 8000        MMURW   MOVE.L  #MMUSADRL,A0    ;SET MMU LIMIT START ADDR
0230| 227C 00FE 8000                MOVE.L  #MMUEADRL,A1    ;SET MMU LIMIT END ADDR
0236| 267C 00FE 8008                MOVE.L  #MMUEADRB,A3    ;SET MMU BASE END ADDR
023C|
023C|                       RWCHK1  BSR4    CHKRW           ;GO DO READ/WRITE CHECK
023C| 49FA 0006            #          LEA      @1,A4
0240| 6000 0072            #          BRA      CHKRW
0244|                      #@1
0244| 4640                          NOT     D0              ;INVERT FOR NEXT PASS
0246|                               BSRS4   CHKRW           ;GO DO AGAIN
0246| 49FA 0004            #          LEA      @1,A4
024A| 6068                 #          BRA.S    CHKRW
024C| 4640                  RWCHK2  NOT     D0              ;INVERT BACK TO ORIGINAL PATTERN
024E|                               BSRS4   CHKRW           ;ONE MORE TIME
024E| 49FA 0004            #          LEA      @1,A4
0252| 6060                 #          BRA.S    CHKRW
0254|                      #@1
0254| E350                  RWCHK3  ROXL    #1,D0           ;SET UP NEW PATTERN
0256| B3C8                          CMPA.L  A0,A1           ;CHECK IF DONE
0258| 6704                          BEQ.S   CHKBASE         ;IF YES GO CHECK FOR BASE REG TESTING
025A| D1CA                          ADDA.L  A2,A0           ;ELSE BUMP MMU ADDR
025C| 60DE                          BRA.S   RWCHK1
025E|
025E| B7C8                  CHKBASE CMPA.L  A0,A3           ;DONE WITH BASE?
0260| 670A                          BEQ.S   @2              ;EXIT IF YES
0262| 207C 0000 8008                MOVE.L  #MMUSADRB,A0    ;ELSE SET STARTING BASE ADDRESS
0268| 224B                          MOVEA.L A3,A1           ; AND ENDING ADDRESS
026A| 60D0                          BRA.S   RWCHK1          ;GO CHECK BASE REGS
026C|
026C| 4A42                  @2      TST     D2              ;check for errors
026E|                               RTS6                    ;and exit test
026E| 4ED6                 #          JMP      (A6)
0270|
0270|                               .PAGE
0270|                       ;----------------------------------------------------------------------------
0270|                       ;  Subroutine to do MMU address check
0270|                       ;  Leaves limit registers with invalid page value, base regs with 0
0270|                       ;----------------------------------------------------------------------------
0270|
0270| 207C 0000 8000        MMUACHK MOVE.L  #MMUSADRL,A0    ;SET MMU LIMIT START ADDR
0276| 227C 00FE 8000                MOVE.L  #MMUEADRL,A1    ;SET MMU LIMIT END ADDR
027C| 267C 00FE 8008                MOVE.L  #MMUEADRB,A3    ;SET MMU BASE END ADDR
0282| 383C 0C00                     MOVE    #INVPAG,D4      ;SET FINAL VALUE FOR LIMIT REGS
0286|
0286| 3210                  ACHK1   MOVE    (A0),D1         ;READ REG
0288| B141                          EOR     D0,D1           ;CHECK IF EXPECTED
028A| 0241 0FFF                     ANDI    #$0FFF,D1       ;MASK DON'T CARES
028E| 6620                          BNE.S   MADRERR         ;EXIT IF ERROR
0290|
0290| 3084                  MMUSET  MOVE    D4,(A0)         ;SET FINAL REG VALUE
0292| E350                          ROXL    #1,D0           ;SET UP NEW PATTERN
0294| B3C8                          CMPA.L  A0,A1           ;CHECK IF DONE
0296| 6704                          BEQ.S   ACHK2           ;IF YES GO CHECK FOR BASE REG TESTING
0298| D1CA                          ADDA.L  A2,A0           ;ELSE BUMP MMU ADDR
029A| 60EA                          BRA.S   ACHK1
029C|
029C| B7C8                  ACHK2   CMPA.L  A0,A3           ;DONE WITH BASE?
029E| 670C                          BEQ.S   @2              ;EXIT IF YES
02A0| 207C 0000 8008                MOVE.L  #MMUSADRB,A0    ;ELSE SET STARTING BASE ADDRESS
02A6| 224B                          MOVEA.L A3,A1           ; AND ENDING ADDRESS
02A8| 7800                          MOVEQ   #0,D4           ;SET FINAL VALUE FOR BASE REGS
02AA| 60DA                          BRA.S   ACHK1           ;GO CHECK BASE REGS
02AC|
02AC| 4A42                  @2      TST     D2              ;check for errors
02AE|                               RTS6                    ;and exit test
02AE| 4ED6                 #          JMP      (A6)
02B0|                       ;  Handle MMU address error
02B0|
02B0| 8441                  MADRERR OR      D1,D2           ;save error bits
02B2| 60DC                          BRA.S   MMUSET          ; and continue test
02B4|
02B4|                               .ELSE
02B4|                               .ENDC
02B4|
02B4|                       ;----------------------------------------------------------------------------
02B4|                       ; Subroutine to do MMU actual read/write
02B4|                       ;----------------------------------------------------------------------------
02B4|
02B4| 3080                  CHKRW   MOVE    D0,(A0)         ;do write
02B6| 3210                          MOVE    (A0),D1         ;read back
02B8| B141                          EOR     D0,D1           ;compare
02BA| 0241 0FFF                     ANDI    #$0FFF,D1       ;mask don't cares
02BE| 6602                          BNE.S   RWERR           ;skip if error
02C0|                               RTS4                    ;else return
02C0| 4ED4                 #          JMP      (A4)
02C2|
02C2|                       ;  Error collection
02C2|
02C2| 8441                  RWERR   OR      D1,D2           ;save error bits
02C4|                               RTS4                    ;and return
02C4| 4ED4                 #          JMP      (A4)
02C6|
02C6|                               .PAGE
02C6|                       ;--------------------------------------------------------------------------
02C6|                       ;  Now do setup of MMU supervisor registers for RAM and I/O space access.
02C6|                       ;  Also do read check after write and abort if error.
02C6|                       ;--------------------------------------------------------------------------
02C6|
02C6|                       ;  Do origin registers first
02C6|
02C6| 207C 0000 8008        SETMMU  MOVE.L  #MMUSADRB,A0    ;GET MMU PTR
02CC| 7000                          MOVEQ   #0,D0           ;clear for use
02CE| 7200                          MOVEQ   #0,D1
02D0| 3802                          MOVE    D2,D4           ;SAVE PREVIOUS RESULTS IF ANY
02D2| 7400                          MOVEQ   #0,D2
02D4| 7C00                          MOVEQ   #0,D6
02D6| 247C 0002 0000                MOVE.L  #ADR128K,A2     ;ADDRESS INCREMENT
02DC| 267C 0000 0100                MOVE.L  #PAG128K,A3     ;SET UP BASE ADDRESS INCREMENT
02E2| 7C10                          MOVEQ   #16,D6          ;LOOP COUNT
02E4|                       LOADORG BSRS4   CHKRW           ;DO WRITE/READ CHECK
02E4| 49FA 0004            #          LEA      @1,A4
02E8| 60CA                 #          BRA.S    CHKRW
02EA|                      #@1
02EA| D08B                          ADD.L   A3,D0           ;COMPUTE NEXT MEMORY BASE ADDRESS
02EC| D1CA                          ADDA.L  A2,A0           ;BUMP MMU ORG PTR
02EE| 5346                          SUBQ    #1,D6
02F0| 66F2                          BNE.S   LOADORG         ;LOOP UNTIL DONE
02F2|
02F2|                       ;  Set base for I/O and special I/O space
02F2|
02F2| 207C 00FC 8008                MOVEA.L #MMU126B,A0     ;PT TO ORG REG 126
02F8| 7000                          MOVEQ   #0,D0           ;set data value
02FA|                               BSRS4   CHKRW
02FA| 49FA 0004            #          LEA      @1,A4
02FE| 60B4                 #          BRA.S    CHKRW
0300|                      #@1
0300| D1CA                          ADDA.L  A2,A0           ;BUMP PTR TO REG 127
0302|                               BSRS4   CHKRW
0302| 49FA 0004            #          LEA      @1,A4
0306| 60AC                 #          BRA.S    CHKRW
0308|                      #@1
0308|
0308|                       ;  Now do limit registers
0308|
0308| 207C 0000 8000                MOVEA.L #MMUSADRL,A0    ;GET MMU LIMIT REG PTR
030E| 303C 0700                     MOVE    #MEMLMT,D0      ;LIMIT FOR 128K MEMORY SEGMENTS
0312| 7200                          MOVEQ   #0,D1           ;use as working reg
0314| 7C10                          MOVEQ   #16,D6          ;LOOP COUNT
0316|                       LOADLMT BSRS4   CHKRW
0316| 49FA 0004            #          LEA      @1,A4
031A| 6098                 #          BRA.S    CHKRW
031C|                      #@1
031C| D1CA                          ADDA.L  A2,A0           ;BUMP MMU PTR
031E| 5346                          SUBQ    #1,D6
0320| 66F4                          BNE.S   LOADLMT         ;LOOP UNITL DONE
0322|
0322|                       ;  Now do MMU limit reg setup for I/O and Special I/O access
0322|
0322| 207C 00FC 8000                MOVEA.L #MMU126L,A0     ;PT TO LMT REG 126
0328| 303C 0900                     MOVE    #IOLMT,D0       ;SET FOR I/O SPACE, FULL ACCESS
032C|                               BSRS4   CHKRW
032C| 49FA 0004            #          LEA      @1,A4
0330| 6082                 #          BRA.S    CHKRW
0332|                      #@1
0332| D1CA                          ADDA.L  A2,A0           ;BUMP PTR TO REG 127
0334| 303C 0F00                     MOVE    #SPLMT,D0       ;SET FOR SPECIAL I/O, FULL ACCESS
0338|                               BSRS4   CHKRW
0338| 49FA 0006            #          LEA      @1,A4
033C| 6000 FF76            #          BRA.S    CHKRW
0340|                      #@1
0340|
0340|                               .IF  DIAGS = 1
0340|                       ;  Check if errors detected
0340| 4A42                          TST     D2              ;CHECK ERROR MASK
0342| 6600 FE94                     BNE     MMUERR          ;ABORT IF ERROR
0346| 3404                          MOVE    D4,D2           ;ELSE RESTORE PREVIOUS RESULTS
0348|                               .ENDC
0348|
0348|                               .PAGE
0348|                       ;--------------------------------------------------------------------------
0348|                       ;  Complete testing of MMU by checking other context regs.
0348|                       ;  Uses reg D6 for context indicator.
0348|                       ;--------------------------------------------------------------------------
0348|                               .IF     DIAGS = 1
0348|
0348| 7C00                  MMUTST2 MOVEQ   #0,D6           ;FOR CONTEXT INDICATOR
034A|                               BSR4    MMUINIT         ;REINITIALIZE FOR TESTING
034A| 49FA 0006            #          LEA      @1,A4
034E| 6000 FEC6            #          BRA      MMUINIT
0352|                      #@1
0352|
0352| 4A39 00FC E00A                TST.B   SEG1ON          ;SET FOR CONTEXT 1
0358| 7C01                          MOVEQ   #1,D6           ;SET CONTEXT INDICATOR
035A|
035A|                               BSR4    CONCHK          ;CHECK IF MMU CONTEXT CHANGED
035A| 49FA 0006            #          LEA      @1,A4
035E| 6000 00B0            #          BRA      CONCHK
0362| 6700 0090                     BEQ     MMUERR2         ;EXIT IF NO - SEG BIT ERROR
0366|
0366|                               BSR6    MMURW           ;ELSE GO DO R/W TEST
0366| 4DFA 0006            #          LEA      @1,A6
036A| 6000 FEBE            #          BRA      MMURW
036E| 6600 0084                     BNE     MMUERR2         ;exit if error
0372|
0372| 4A39 00FC E00E                TST.B   SEG2ON          ;SET FOR CONTEXT 3
0378| 7C03                          MOVEQ   #3,D6
037A|
037A|                               BSR4    CONCHK          ;CHECK IF MMU CONTEXT CHANGED
037A| 49FA 0006            #          LEA      @1,A4
037E| 6000 0090            #          BRA      CONCHK
0382|                      #@1
0382| 6770                          BEQ.S   MMUERR2         ;EXIT IF NO - SEG BIT ERROR
0384|
0384|                               BSR6    MMURW           ;ELSE GO TEST
0384| 4DFA 0006            #          LEA      @1,A6
0388| 6000 FEA0            #          BRA      MMURW
038C|                      #@1
038C| 6666                          BNE.S   MMUERR2         ;exit if error
038E|
038E| 4A39 00FC E008                TST.B   SEG1OFF         ;SET FOR CONTEXT 2
0394| 7C02                          MOVEQ   #2,D6
0396|
0396|                               BSRS4   CONCHK          ;CHECK IF MMU CONTEXT CHANGED
0396| 49FA 0004            #          LEA      @1,A4
039A| 6074                 #          BRA.S    CONCHK
039C|                      #@1
039C| 675C                          BEQ.S   MMUERR3         ;EXIT IF NO - SEG BIT ERROR
039E|
039E|                               BSRS6   MMURW           ;ELSE GO TEST
039E| 4DFA 0006            #          LEA      @1,A6
03A2| 6000 FE86            #          BRA.S    MMURW
03A6|                      #@1
03A6| 6652                          BNE.S   MMUERR3         ;exit if error
03A8|
03A8| 4A39 00FC E00C                TST.B   SEG2OFF         ;RESET FOR CONTEXT 0 REGS
03AE|
03AE|                       ;  Now do MMU addressing check of remaining context regs
03AE|
03AE|                               BSR4    MMUINIT         ;REINITIALIZE
03AE| 49FA 0006            #          LEA      @1,A4
03B2| 6000 FE62            #          BRA      MMUINIT
03B6|                      #@1
03B6|
03B6| 4A39 00FC E00A                TST.B   SEG1ON          ;SET FOR CONTEXT 1
03BC| 7C01                          MOVEQ   #1,D6
03BE|                               BSR6    MMUACHK         ;TEST CONTEXT 1
03BE| 4DFA 0006            #          LEA      @1,A6
03C2| 6000 FEAC            #          BRA      MMUACHK
03C6|                      #@1
03C6| 662C                          BNE.S   MMUERR2         ;exit if error
03C8| 4A39 00FC E00E                TST.B   SEG2ON          ;TEST CONTEXT 3
03CE| 7C03                          MOVEQ   #3,D6
03D0|                               BSR6    MMUACHK
03D0| 4DFA 0006            #          LEA      @1,A6
03D4| 6000 FE9A            #          BRA      MMUACHK
03D8| 661A                          BNE.S   MMUERR2         ;exit if error
03DA|
03DA| 4A39 00FC E008                TST.B   SEG1OFF         ;TEST CONTEXT 2
03E0| 7C02                          MOVEQ   #2,D6
03E2|                               BSR6    MMUACHK
03E2| 4DFA 0006            #          LEA      @1,A6
03E6| 6000 FE88            #          BRA      MMUACHK
03EA|                      #@1
03EA| 660E                          BNE.S   MMUERR3         ;exit if error
03EC|
03EC| 4A39 00FC E00C                TST.B   SEG2OFF         ;RESET TO CONTEXT 0
03F2| 6014                          BRA.S   MMULPCHK        ;go check for loop mode
03F4|
03F4| 4A39 00FC E008        MMUERR2 TST.B   SEG1OFF         ;ENSURE RESET FOR CONTEXT 0
03FA| 4A39 00FC E00C        MMUERR3 TST.B   SEG2OFF
0400|
0400| E85E                          ROR     #4,D6           ;get context indicator
0402| 8446                          OR      D6,D2           ;save with error bits (if any)
0404| 08C7 0000                     BSET    #MMU,D7         ;set error indicator
0408|                       MMULPCHK
0408| 4A87                          TST.L   D7              ;in loop mode?
040A| 6B00 FDA4                     BMI.S   MMUTST          ;restart full MMU test if yes
040E| 6030                          BRA.S   START           ;else continue to next test
0410|
0410|                               .PAGE
0410|                       ;-------------------------------------------------------------------------
0410|                       ;  Subroutine to verify context change made - does comparison to ensure
0410|                       ;  destruction of context 0 mapping avoided.  Zero bit set if error.
0410|                       ;-------------------------------------------------------------------------
0410|
0410| 3839 00FC 8000        CONCHK  MOVE    MMU126L,D4      ;check limit reg for I/O space
0416| 0244 0FFF                     ANDI    #$0FFF,D4       ;mask don't care
041A| 0C44 0900                     CMPI    #IOLMT,D4       ;still in same context?
041E| 661E                          BNE.S   CONOK           ;exit if not
0420|
0420| 3839 00FE 8000                MOVE    MMU127L,D4      ;else also check reg for ROM space
0426| 0244 0FFF                     ANDI    #$0FFF,D4       ;mask don't care
042A| 0C44 0F00                     CMPI    #SPLMT,D4       ;also set up?
042E| 660E                          BNE.S   CONOK           ;exit if not
0430|
0430| 3839 0000 8000                MOVE    MMU0L,D4        ;else do final check on reg for memory access
0436| 0244 0FFF                     ANDI    #$0FFF,D4
043A| 0C44 0700                     CMPI    #MEMLMT,D4      ;return with match results to caller
043E|
043E|                       CONOK   RTS4
043E| 4ED4                 #          JMP      (A4)
0440|
0440|                               .ENDC
0440|                               .IF  ROM4K = 0
0440|                               .IF  DIAGS = 0
0440|                               .ENDC                   ;{DIAGS}
0440|                               .ENDC                   ;{ROM4K}
0440|                               .PAGE
0440|                       ;-------------------------------------------------------------------------
0440|                       ;  Reset SETUP bit to enable system access and continue with testing
0440|                       ;-------------------------------------------------------------------------
0440|
0440| 4239 00FC E012        START   CLR.B   SETUP           ;TURN OFF SETUP TO ENTER MAP LAND ...
0446|                       ;----------------------------------------------------------------------------
0446|                       ;  Now do memory sizing - assumes 128K minimum memory increment
0446|                       ;  Register usage:
0446|                       ;       A0 = minimum physical address           D0 = scratch use
0446|                       ;       A1 = maximum physical address/scratch   D1 = incr for search address
0446|                       ;       A2 = unused                             D2 = unused
0446|                       ;       A3 = next base memory addr to test      D3 = inverted sizing test pattern
0446|                       ;       A4 = return address                     D4 = sizing test pattern
0446|                       ;       A5 = unused                             D5 = retry count
0446|                       ;       A6 = saved error mask                   D6 = error mask
0446|                       ;----------------------------------------------------------------------------
0446|
0446| 4280                  MEMSIZ  CLR.L   D0              ;setup regs for loop
0448| 2040                          MOVE.L  D0,A0
044A| 2240                          MOVE.L  D0,A1
044C| 2640                          MOVE.L  D0,A3
044E| 2C40                          MOVE.L  D0,A6
0450| 7202                          MOVEQ   #2,D1           ;size at 128K boundaries                                RM000
0452| 4841                          SWAP    D1              ;                                                       RM000
0454| 283C AA55 A55A                MOVE.L  #PATRN,D4       ;set test patterns for sizing                           CHG002
045A| 3604                          MOVE    D4,D3           ;use only lower word
045C| 4643                          NOT     D3              ;and its inverse
045E|
045E|                       CHKLO   BSR4    CHKMEM          ;first search for low memory address
045E| 49FA 0006            #          LEA      @1,A4
0462| 6000 00A4            #          BRA      CHKMEM
0466|                      #@1
0466| 4A46                          TST     D6              ;memory found?
0468| 6752                          BEQ.S   SAVELO          ;yes - go save address
046A| 4646                          NOT     D6              ;else invert to check if all bits in error
046C| 4A46                          TST     D6              ;if not, assume memory error
046E| 6648                          BNE.S   @3              ; and go save address
0470| D7C1                  @2      ADDA.L  D1,A3           ;else bump search address
0472| 224B                          MOVEA.L A3,A1           ;set as next working address
0474| B3FC 0020 0000                CMPA.L  #MAXADR,A1      ;at max address?
047A| 66E2                          BNE.S   CHKLO           ;continue search if not
047C|
047C|                       ;  No memory found - toggle LED and check for I/O board; if no I/O (bus error)          CHG004
047C|                       ;  diagnostics are restarted                                                            CHG004
047C|
047C| 13FC 00AF 00FC E800           MOVE.B  #DEFVID2,VIDLTCH ;set LED on and default video latch setting (PAGE 2F)  CHG004
0484| 303C 61A8                     MOVE    #TNTHSEC,D0      ;delay for .1 sec                                      CHG004
0488| 5340                  @9      SUBQ    #1,D0            ;                                                      CHG004
048A| 66FC                          BNE.S   @9               ;                                                      CHG004
048C| 13FC 002F 00FC E800           MOVE.B  #DEFVID,VIDLTCH  ;reset LED and leave video latch setting               CHG004
0494| 207C 00FC DD81                MOVE.L  #VIA1BASE,A0     ;check for I/O board                                   CHG004
049A| 4A10                          TST.B   (A0)             ;bus error will occur if not installed                 CHG004
049C|
049C|                       ;  Go into read/write loop if no memory found but I/O installed
049C|
049C|                               BSR2    LOTONE          ;beep speaker for error
049C| 45FA 0006            #          LEA      @1,A2
04A0| 6000 00B2            #          BRA      LOTONE
04A4|                      #@1
04A4|                               BSR4    CONSET          ;set contrast
04A4| 49FA 0006            #          LEA      @1,A4
04A8| 6000 0350            #          BRA      CONSET
04AC|                      #@1
04AC| 207C 000F FFFE                MOVE.L  #ONEMEG-2,A0    ;set default memory address (to span both boards)       CHG002
04B2| 2084                  @4      MOVE.L  D4,(A0)         ;go into read/write loop                                CHG002
04B4| 2610                          MOVE.L  (A0),D3         ;                                                       CHG002
04B6| 60FA                          BRA.S   @4
04B8|
04B8|                       ;  Low memory address found - save and continue
04B8| 4646                  @3      NOT     D6              ;reinvert and
04BA| 3C46                          MOVE    D6,A6           ; save results
04BC|
04BC| 204B                  SAVELO  MOVEA.L A3,A0           ;save low address
04BE| B1FC 0010 0000                CMPA.L  #ONEMEG,A0      ;check for min low address
04C4| 6F06                          BLE.S   @1              ;skip if OK
04C6| 207C 0010 0000                MOVEA.L #ONEMEG,A0      ;else set at min value (one 512K board in slot 1)
04CC|
04CC|                               .PAGE
04CC|                       ;-----------------------------------------------------------------------------
04CC|                       ;  Now check for high memory address; search to max address of 2 meg
04CC|                       ;-----------------------------------------------------------------------------
04CC|
04CC| 244B                  @1      MOVEA.L A3,A2           ;save low address as first high address
04CE|
04CE|                       TSTHI
04CE| D7C1                          ADDA.L  D1,A3           ;compute next 128K increment
04D0| 224B                          MOVEA.L A3,A1           ;use as new search value
04D2| B3FC 0020 0000                CMPA.L  #MAXADR,A1      ;done?
04D8| 6728                          BEQ.S   SIZXIT
04DA|
04DA|                       ;  Following patch added to detect for wraparound problem of old memory boards
04DA| 2008                          MOVE.L  A0,D0           ;check low address                                      RM015
04DC| 6604                          BNE.S   CHKHI           ;old memory boards start at address 0                   RM015
04DE| B651                          CMP     (A1),D3         ;are we wrapped back to already tested location?
04E0| 671E                          BEQ.S   WRAPXIT         ;skip if yes (i.e., old memory board)                   RM015
04E2|
04E2|                       ;  Else continue with check for high address
04E2|
04E2|                       CHKHI   BSRS4   CHKMEM          ;go do memory search
04E2| 49FA 0004            #          LEA      @1,A4
04E6| 6020                 #          BRA.S    CHKMEM
04E8|                      #@1
04E8| 4A46                          TST     D6              ;any errors?
04EA| 670E                          BEQ.S   SAVEHI          ;skip if not to save address
04EC| 4646                          NOT     D6              ;else invert to see if all bits in error
04EE| 4A46                          TST     D6
04F0| 67DC                          BEQ.S   TSTHI           ;skip if yes to ignore address
04F2| 300E                          MOVE    A6,D0           ;else get previous results
04F4| 4646                          NOT     D6              ;reinvert and
04F6| 8046                          OR      D6,D0           ; add new results
04F8| 3C40                          MOVE    D0,A6           ;save for later
04FA|
04FA| 244B                  SAVEHI  MOVEA.L A3,A2           ;save as new potential high address
04FC| 4253                          CLR     (A3)            ;clear test pattern                                     RM015
04FE| 60CE                          BRA.S   TSTHI           ; and continue loop
0500|
0500| 4251                  WRAPXIT CLR     (A1)            ;clear test pattern                                     RM015
0502|
0502| D5C1                  SIZXIT  ADDA.L  D1,A2           ;high address = last valid addr + 128K
0504| 224A                          MOVEA.L A2,A1           ;save for later use
0506| 605E                          BRA.S   RSTMMU          ;continue on
0508|
0508|                               .PAGE
0508|                       ;----------------------------------------------------------------------------
0508|                       ;  Subroutine to do memory check for sizing.  If error, tries successive
0508|                       ;  memory locations up to retry count (D5).  Returns with error mask in D6.
0508|                       ;----------------------------------------------------------------------------
0508|
0508| 7A20                  CHKMEM  MOVEQ   #RETRYCNT,D5    ; set retry count in case of errors
050A| 4246                          CLR     D6              ; clear for error mask
050C| 3284                  @1      MOVE    D4,(A1)         ; check if true data stores
050E| 3343 0002                     MOVE    D3,2(A1)        ; and try complement to next location
0512| B851                          CMP     (A1),D4
0514| 6706                          BEQ.S   @2              ; continue if yes
0516| 3011                          MOVE    (A1),D0         ; else get error bits
0518| B940                          EOR     D4,D0
051A| 8C40                          OR      D0,D6           ; and save them
051C|
051C| B669 0002             @2      CMP     2(A1),D3        ; check second location
0520| 6708                          BEQ.S   @3              ; exit if data correct
0522| 3029 0002                     MOVE    2(A1),D0        ; else read again
0526| B740                          EOR     D3,D0           ; get error bits
0528| 8C40                          OR      D0,D6           ; save in error mask
052A|
052A| 3344 0002             @3      MOVE    D4,2(A1)        ; now try in reverse order
052E| 3283                          MOVE    D3,(A1)
0530| B869 0002                     CMP     2(A1),D4        ; check second location
0534| 6708                          BEQ.S   @4              ; skip if OK
0536| 3029 0002                     MOVE    2(A1),D0        ; else save error bits
053A| B940                          EOR     D4,D0
053C| 8C40                          OR      D0,D6
053E|
053E| B651                  @4      CMP     (A1),D3         ; and check first
0540| 6706                          BEQ.S   @5              ; continue if yes
0542| 3011                          MOVE    (A1),D0         ; else get error bits
0544| B740                          EOR     D3,D0
0546| 8C40                          OR      D0,D6           ; and save them
0548|
0548| 4A46                  @5      TST     D6              ; any  errors?
054A| 6706                          BEQ.S   @6              ; skip if no
054C| 4A99                          TST.L   (A1)+           ; else bump search address to next pair
054E| 5345                          SUBQ    #1,D5           ; decr retry count
0550| 66BA                          BNE.S   @1              ; continue until count exhausted
0552|
0552|                       @6      RTS4                    ; return with results in D6
0552| 4ED4                 #          JMP      (A4)
0554|
0554|                               .PAGE
0554|                       ;-------------------------------------------------------------------------
0554|                       ; Subroutine to set parms for lo tone from speaker
0554|                       ;-------------------------------------------------------------------------
0554|
0554| 7060                  LOTONE  MOVEQ   #$60,D0         ;set frequency
0556| 323C 00FA                     MOVE    #250,D1         ;and duration
055A| 7404                          MOVEQ   #4,D2           ;and volume (medium)
055C|                               BSR4    TONE2           ;go do tone
055C| 49FA 0006            #          LEA      @1,A4
0560| 6000 05A4            #          BRA      TONE2
0564|                      #@1
0564|                               RTS2
0564| 4ED2                 #          JMP      (A2)
0566|
0566|
0566|                               .PAGE
0566|                       ;---------------------------------------------------------------------------
0566|                       ;  Now reset MMU regs according to low and high physical address
0566|                       ;  Remainder of MMU regs in context 0 are set to invalid page
0566|                       ;
0566|                       ;  Register Usage:
0566|                       ;       A0 - low physical address       D0 - scratch/value stored in base reg
0566|                       ;       A1 - high physical address      D1 - value stored in limit reg
0566|                       ;       A2 - MMU base reg ptr           D2 - unused
0566|                       ;       A3 - MMU limit reg ptr          D3 - holds base reg page incr value
0566|                       ;       A4 - used for return address    D4 - used for count of regs to set
0566|                       ;       A5 - MMU address increment      D5 - low physical page
0566|                       ;       A6 - not used                   D6 - high physical page
0566|                       ;---------------------------------------------------------------------------
0566|
0566|                       ;  First translate memory addresses to 512 byte page values for MMU use
0566|
0566|                       RSTMMU
0566| 2A08                          MOVE.L  A0,D5           ;GET MEMORY ADDRESS VALUES
0568| 2C09                          MOVE.L  A1,D6
056A| 7009                          MOVEQ   #9,D0           ;SET SHIFT COUNT
056C| E0AD                          LSR.L   D0,D5           ;TRANSLATE TO PAGE VALUES
056E| E0AE                          LSR.L   D0,D6
0570|
0570|                       ;  Now initialize for MMU write operations
0570|
0570| 247C 0000 8008                MOVEA.L #MMUSADRB,A2    ;SET MMU BASE REG PTR
0576| 267C 0000 8000                MOVEA.L #MMUSADRL,A3    ;SET LIMIT REG PTR
057C| 2A7C 0002 0000                MOVE.L  #ADR128K,A5     ;SET INCREMENT VALUE FOR MMU ADDRESSES
0582| 263C 0000 0100                MOVE.L  #PAG128K,D3     ;SET INCR VALUE FOR BASE REG CONTENTS
0588| 787E                          MOVEQ   #126,D4         ;SET REG COUNT - NO RESETTING OF REGS 126,127
058A| 3005                          MOVE    D5,D0           ;SET BASE VALUE
058C| 323C 0700                     MOVE    #MEMLMT,D1      ;SET LIMIT VALUE
0590|
0590|                       ;  Remap MMU regs for existing memory
0590|
0590|                       REMAP   BSRS4   WRTMMU          ;REWRITE SET OF MMU REGS
0590| 49FA 0004            #          LEA      @1,A4
0594| 6024                 #          BRA.S    WRTMMU
0596|                      #@1
0596| 5344                          SUBQ    #1,D4           ;DECR REG COUNT
0598| D083                          ADD.L   D3,D0           ;BUMP PAGE ADDRESS
059A| BC80                          CMP.L   D0,D6           ;CHECK IF AT UPPER LIMIT
059C| 66F2                          BNE.S   REMAP           ;LOOP IF NO
059E|
059E|                       ;  Now map remainder of regs for invalid access
059E|
059E| 4240                          CLR     D0              ;SET NEW BASE REG VALUE
05A0| 323C 0C00                     MOVE    #INVPAG,D1      ; AND LIMIT REG VALUE
05A4|                       MAPINV  BSRS4   WRTMMU          ;GO DO REWRITE
05A4| 49FA 0004            #          LEA      @1,A4
05A8| 6010                 #          BRA.S    WRTMMU
05AA|                      #@1
05AA| 5384                          SUBQ.L  #1,D4           ;DECR COUNT
05AC| 66F6                          BNE.S   MAPINV          ;LOOP UNTIL DONE
05AE|
05AE|                       ;  Finally reset video page to last page of memory
05AE|
05AE| EC8E                          LSR.L   #6,D6           ;compute address for video page
05B0| 5346                          SUBQ    #1,D6           ;decr to last page
05B2| 13C6 00FC E800                MOVE.B  D6,VIDLTCH      ;and set video latch
05B8|
05B8| 6066                          BRA.S   MEMTST1         ;SKIP TO NEXT TEST
05BA|                               .IF     EXTERNAL = 1
05BA|                               .ENDC
05BA|
05BA|                       ;-------------------------------------------------------------------------
05BA|                       ;  Subroutine to set MMU regs (context 0) - can also be called by external
05BA|                       ;  routines that provide the following register inputs:
05BA|                       ;
05BA|                       ;       A2 = base reg address           D0 = value for base reg
05BA|                       ;       A3 = limit reg address          D1 = value for limit reg
05BA|                       ;       A5 = reg address increment
05BA|                       ;-------------------------------------------------------------------------
05BA|
05BA| 4A39 00FC E010        WRTMMU  TST.B   SETUPON         ;TURN SETUP ON TO ENABLE MMU ACCESS
05C0| 3480                          MOVE    D0,(A2)         ;SET BASE REG
05C2| 3681                          MOVE    D1,(A3)         ;SET LIMIT REG
05C4| D5CD                          ADDA.L  A5,A2           ;BUMP MMU PTRS
05C6| D7CD                          ADDA.L  A5,A3
05C8| 4239 00FC E012                CLR.B   SETUP           ;BACK TO MAP LAND
05CE|                               RTS4                    ;AND BACK TO CALLER
05CE| 4ED4                 #          JMP      (A4)
05D0|
05D0|                               .IF  ROM16K = 1
05D0|                       ;-------------------------------------------------------------------------
05D0|                       ;  Subroutine to read MMU regs - for call by external routines.
05D0|                       ;  Inputs:
05D0|                       ;       D2 = context to read (0-3)
05D0|                       ;       A2 = base reg address
05D0|                       ;       A3 = limit reg address
05D0|                       ;       A4 = return address
05D0|                       ;       A5 = reg address increment
05D0|                       ;  Outputs:
05D0|                       ;       D0 = value of base reg
05D0|                       ;       D1 = value of limit reg
05D0|                       ;       A2,A3 incremented by value in A5
05D0|                       ;  Side Effects:
05D0|                       ;       D3 trashed
05D0|                       ;-------------------------------------------------------------------------
05D0|
05D0| 363C 0FFF             READMMU MOVE    #$0FFF,D3       ;set mask for result
05D4| 4A39 00FC E010                TST.B   SETUPON         ;turn setup on to enable MMU access
05DA|
05DA| 4A42                          TST     D2              ;check context
05DC| 6722                          BEQ.S   @9              ;skip if context 0
05DE| 0C02 0001                     CMP.B   #1,D2           ;context 1?
05E2| 6716                          BEQ.S   @2
05E4| 0C02 0002                     CMP.B   #2,D2           ;context 2?
05E8| 6708                          BEQ.S   @1
05EA| 4A39 00FC E00E                TST.B   SEG2ON          ;must be context 3
05F0| 6008                          BRA.S   @2              ;set both seg bits
05F2| 4A39 00FC E00E        @1      TST.B   SEG2ON          ;set for context 2
05F8| 6006                          BRA.S   @9
05FA| 4A39 00FC E00A        @2      TST.B   SEG1ON          ;set for context 1 and 3
0600|
0600|                       ;  read the regs
0600|
0600| 3012                  @9      MOVE    (A2),D0         ;read base reg
0602| C043                          AND     D3,D0           ;clear junk
0604| 3213                          MOVE    (A3),D1         ;read limit reg
0606| C243                          AND     D3,D1           ;clear junk
0608| D5CD                          ADDA.L  A5,A2           ;incr ptrs
060A| D7CD                          ADDA.L  A5,A3
060C| 4A39 00FC E008                TST.B   SEG1OFF         ;restore to context 0
0612| 4A39 00FC E00C                TST.B   SEG2OFF
0618| 4239 00FC E012                CLR.B   SETUP           ;back to map land
061E|                               RTS4                    ;and back to caller
061E| 4ED4                 #          JMP      (A4)
0620|
0620|                               .ENDC
0620|                               .IF     EXTERNAL = 1
0620|                               .ENDC
0620|
0620|                               .PAGE
0620|                       ;--------------------------------------------------------------------------
0620|                       ;  Begin memory testing by checking first 800 hex locations (2K).
0620|                       ;  If error here, abort other testing and go into loop since can't relay
0620|                       ;  meaningful results.
0620|                       ;--------------------------------------------------------------------------
0620|
0620| 2448                  MEMTST1 MOVEA.L A0,A2           ;save memory lo, hi addresses
0622| 2649                          MOVEA.L A1,A3
0624|
0624|                               .IF  DIAGS = 1
0624|
0624| 91C8                          SUBA.L  A0,A0           ;set test addresses
0626| 327C 0800                     MOVEA   #LOMEM,A1       ;upper address                                  RM000
062A|                               BSR4    RAMTEST         ;go do memory test
062A| 49FA 0006            #          LEA      @1,A4
062E| 6000 0880            #          BRA      RAMTEST
0632|                      #@1
0632| 6738                          BEQ.S   INITMEM         ;skip if OK
0634|
0634|                       ;  Error in low memory - reset video latch, beep speaker and go into R/W loop
0634|
0634| 200A                          MOVE.L  A2,D0           ;get low physical address
0636| E088                          LSR.L   #8,D0           ;convert to page value
0638| EE88                          LSR.L   #7,D0
063A| 13C0 00FC E800                MOVE.B  D0,VIDLTCH      ;set video latch to bad area
0640|                               BSR4    CONSET          ;ensure contrast on
0640| 49FA 0006            #          LEA      @1,A4
0644| 6000 01B4            #          BRA      CONSET
0648|                      #@1
0648|
0648|                               BSR2    LOTONE          ;beep speaker twice for low memory error
0648| 45FA 0006            #          LEA      @1,A2
064C| 6000 FF06            #          BRA      LOTONE
0650|                      #@1
0650| 303C 61A8                     MOVE    #TNTHSEC,D0     ;delay for about 1/10 sec                       RM000
0654| 5340                  TONEDLY SUBQ    #1,D0
0656| 66FC                          BNE.S   TONEDLY
0658|                               BSR2    LOTONE          ;do second beep
0658| 45FA 0006            #          LEA      @1,A2
065C| 6000 FEF6            #          BRA      LOTONE
0660|                      #@1
0660|
0662| 303C A55A                     MOVE    #PATRN2,D0      ;set pattern for usess
0666| 3080                  @2      MOVE    D0,(A0)
0668| 3210                          MOVE    (A0),D1
066A| 60FA                          BRA.S   @2              ;loop with random display on screen
066C|
066C|                               .ELSE
066C|                               .ENDC                   ;{DIAGS}
066C|
066C|                       ;  Now attempt to initialize status areas and save results
066C|
066C| 307C 0180             INITMEM MOVEA   #STATUS,A0      ;get ptr to start of status area                RM000
0670| 707F                          MOVEQ   #127,D0         ;set count
0672| 4298                  @2      CLR.L   (A0)+           ;clear it
0674| 51C8 FFFC                     DBF     D0,@2           ;until done
0678|
0678| 31C3 0186                     MOVE    D3,MEMRSLT      ;save test results
067C| 31CE 0184                     MOVE    A6,SIZRSLT      ;save sizing results
0680| 21CA 02A4                     MOVE.L  A2,MINMEM       ;save min memory address
0684| 21CB 0294                     MOVE.L  A3,MAXMEM       ;save max memory address
0688| 97CA                          SUBA.L  A2,A3           ;compute total memory
068A| 21CB 02A8                     MOVE.L  A3,TOTLMEM      ;and save also
068E|
068E| 207C 0000 8000                MOVE.L  #HEX32K,A0      ;compute base address for screen
0694| 97C8                          SUBA.L  A0,A3
0696| 21CB 0110                     MOVE.L  A3,SCRNBASE     ;and save
069A|
069A| 31C2 01B0                     MOVE    D2,MMURSLT      ;and save MMU results also
069E|
069E| 21FC 0000 02B0 0260           MOVE.L  #KBDQ,KBDQPTR   ;init COPS buffer pointer for later use
06A6|
06A6|                               .PAGE
06A6|                       ;------------------------------------------------------------------------
06A6|                       ; Initialize exception and trap vectors to catch unexpected errors
06A6|                       ;------------------------------------------------------------------------
06A6|
06A6| 6104                  INITVCT BSR.S   SETVCTRS        ;init vectors
06A8| 6000 00CA                     BRA     SCCSET          ;continue testing                               CHG027
06AC|
06AC|                       ;  Subroutine to set up default vectors
06AC|
06AC|                       SETVCTRS
06AC| 41FA 003E                     LEA     MISC,A0
06B0| 93C9                          SUBA.L  A1,A1
06B2| 7040                          MOVEQ   #64,D0
06B4| 22C8                  @1      MOVE.L  A0,(A1)+        ; fill with unknown ones
06B6| 5340                          SUBQ    #1,D0
06B8| 6EFA                          BGT     @1
06BA| 6126                          BSR.S   SETBUSVCT       ; then, with special ones                       RM000
06BC| 41FA 0090                     LEA     AERR,A0
06C0| 21C8 000C                     MOVE.L  A0,ADRVCTR
06C4| 41FA 0032                     LEA     IERR,A0
06C8| 21C8 0010                     MOVE.L  A0,ILLVCTR
06CC| 41FA 0036                     LEA     NMI,A0
06D0| 21C8 007C                     MOVE.L  A0,NMIVCT
06D4| 41FA 0060                     LEA     TRPERR,A0       ; same routine for line 1010 and 1111
06D8| 21C8 0028                     MOVE.L  A0,L10VCTR
06DC| 21C8 002C                     MOVE.L  A0,L11VCTR
06E0|
06E0|                               .IF  USERINT = 0
06E0|                               .ENDC
06E0|
06E0| 4E75                          RTS
06E2|                       ;-----------------------------------------------------------
06E2|                       ;  Subroutine to setup bus error vector                                         RM000
06E2|                       ;-----------------------------------------------------------
06E2|
06E2|                       SETBUSVCT
06E2| 47FA 005E                     LEA     BERR,A3         ;setup default vector                           RM000
06E6| 21CB 0008                     MOVE.L  A3,BUSVCTR      ;                                               RM000
06EA| 4E75                          RTS                     ;                                               RM000
06EC|
06EC|                       ;-----------------------------------------------------------
06EC|                       ;  Exception Handler routines
06EC|                       ;-----------------------------------------------------------
06EC|
06EC| 21C7 01AC             MISC    MOVE.L  D7,D7SAV        ;save incoming value
06F0| 7E00                          MOVEQ   #0,D7
06F2| 08C7 0007                     BSET    #MISEXCP,D7     ;set error indicator
06F6| 606C                          BRA.S   EXCP1
06F8|
06F8| 21C7 01AC             IERR    MOVE.L  D7,D7SAV        ;save incoming value
06FC| 7E00                          MOVEQ   #0,D7
06FE| 08C7 0008                     BSET    #ILLEXCP,D7     ;set error indicator
0702| 6060                          BRA.S   EXCP1
0704|
0704| 21C7 01AC             NMI     MOVE.L  D7,D7SAV        ;save incoming value
0708| 7E00                          MOVEQ   #0,D7
070A| 6100 085C                     BSR     TSTSTAT         ;check status reg for parity error              CHG015
070E| 6620                          BNE.S   NOTPE           ;skip if not
0710|
0710| 08C7 0016                     BSET    #MPAR,D7        ;set error indicator
0714| 6100 08DA                     BSR     GETPADDR        ;get and save error address                     CHG015
0718| 4A39 00FC E01C                TST.B   PAROFF          ;toggle to clear error bit
071E| 0801 0005                     BTST    #5,D1           ;video error?                                   CHG015
0722| 6706                          BEQ.S   @1              ;skip if not                                    CHG015
0724| 0281 FFFF 8000                ANDI.L  #VMSK,D1        ;mask if yes                                    CHG015
072A| 21C1 01A6             @1      MOVE.L  D1,PEADDR       ;save converted error address                   CHG015
072E| 6034                          BRA.S   EXCP1           ;go to exit
0730|
0730| 08C7 0004             NOTPE   BSET   #CPUINTR,D7      ;else set NMI code
0734| 602E                          BRA.S   EXCP1           ; and exit
0736|
0736| 21C7 01AC             TRPERR  MOVE.L  D7,D7SAV        ;save incoming value
073A| 7E00                          MOVEQ   #0,D7
073C| 08C7 0009                     BSET    #TRPEXCP,D7     ;set error indicator
0740| 6022                          BRA.S   EXCP1
0742|
0742| 21C7 01AC             BERR    MOVE.L  D7,D7SAV        ;save incoming value
0746| 7E00                          MOVEQ   #0,D7
0748| 08C7 0005                     BSET    #BUSEXCP,D7     ;set error indicator
074C| 600A                          BRA.S   EXCP0
074E| 21C7 01AC             AERR    MOVE.L  D7,D7SAV        ;save incoming value
0752| 7E00                          MOVEQ   #0,D7
0754| 08C7 0006                     BSET    #ADREXCP,D7     ;set error indicator
0758|
0758|                       EXCP0                           ; GROUP 0 EXCEPTIONS HERE
0758| 31DF 0280                     MOVE    (SP)+,EXCFC     ; SAVE THE EXTRA DATA
075C| 21DF 0282                     MOVE.L  (SP)+,EXCADR
0760| 31DF 0286                     MOVE    (SP)+,EXCIR
0764|
0764|                       EXCP1                           ; GROUP 1 EXCEPTIONS HERE
0764| 31DF 0288                     MOVE    (SP)+,EXCSR     ; SAVE COMMON INFO
0768| 21DF 028A                     MOVE.L  (SP)+,EXCPC
076C| 31C0 028E                     MOVE    D0,EXCTYPE      ; save error type
0770| 6000 0C28                     BRA     TSTCHK          ; and go display error
0774|
0774|                               .PAGE
0774|                       ;-------------------------------------------------------------------------
0774|                       ;  Initialize SCC chip for Applebus use.                                         CHG027
0774|                       ;  Bus error vector setup in case of problems.
0774|                       ;-------------------------------------------------------------------------
0774|
0774|                       SCCSET
0774| 47FA 03E4                     LEA     NOIO,A3               ;set bus error vector in case no IO board  CHG027
0778| 21CB 0008                     MOVE.L  A3,BUSVCTR            ;                                          CHG027
077C| 6100 0952                     BSR     RSTSCC                ;go do setup                               CHG027
0780|
0780|                       ;-------------------------------------------------------------------------
0780|                       ; Now test VIA for parallel port and contrast latch.
0780|                       ; A read/write test on the timer 1 latches is done, then contrast
0780|                       ; is set if OK.
0780|                       ;-------------------------------------------------------------------------
0780|
0780|                       VIA2TST
0780|                               .IF  DIAGS = 1
0780|                       VIA2CHK
0780|                               .IF  ROM16K = 1
0780| 47FA 002C                     LEA     VIA2VCT,A3      ;OK - set up special bus vector
0784| 21CB 0008                     MOVE.L  A3,BUSVCTR
0788|
0788| 207C 00FC D931                MOVE.L  #,A0  ;set base address of timer low latch
078E| 7008                          MOVEQ   #8,D0           ;set offset to high latch
0790|                               BSRS6   VIATST          ;and go do test
0790| 4DFA 0004            #          LEA      @1,A6
0794| 6022                 #          BRA.S    VIATST
0796|                      #@1
0796| 670A                          BEQ.S   @2              ;if OK, continue
0798| 08C7 000B                     BSET    #VIA2,D7        ;else set error bit
079C| 4A87                          TST.L   D7              ;check if in loop mode
079E| 6BE0                          BMI.S   VIA2CHK         ;restart if yes
07A0| 600A                          BRA.S   @3              ;else skip contrast setting
07A2|                               .ENDC
07A2|
07A2| 4A87                  @2      TST.L   D7              ;in loop mode?
07A4| 6BDA                          BMI.S   VIA2CHK         ;restart if yes
07A6|                               BSRS4    CONOFF         ;go turn off contrast
07A6| 49FA 0004            #          LEA      @1,A4
07AA| 6054                 #          BRA.S    CONOFF
07AC|                      #@1
07AC|
07AC|                               .ENDC                   ;{DIAGS}
07AC|
07AC| 6074                  @3      BRA.S   SCRNTST         ;else skip to next test
07AE|
07AE|                               .IF  DIAGS = 1
07AE|                       ;------------------------------------------------------------------------
07AE|                       ;  Bus error handler for VIA #2 use
07AE|                       ;------------------------------------------------------------------------
07AE|
07AE| 7033                  VIA2VCT MOVEQ   #EVIA2,D0       ;SET ERROR CODE
07B0| 08C7 000B                     BSET    #VIA2,D7        ;set indicator
07B4| 6000 0162                     BRA     IOVCT           ;AND GO HANDLE I/O EXCEPTION
07B8|                               .ENDC                   ;{DIAGS}
07B8|
07B8|                               .IF  ROM16K = 1
07B8|                               .PAGE
07B8|                       ;-------------------------------------------------------------------------
07B8|                       ;   Subroutine to do VIA testing
07B8|                       ;     A0 = address of first timer latch
07B8|                       ;     D0 = offset to other latch
07B8|                       ;-------------------------------------------------------------------------
07B8|
07B8| 2248                  VIATST  MOVE.L  A0,A1           ;set up address for second latch
07BA| D3C0                          ADDA.L  D0,A1
07BC| 7000                          MOVEQ   #0,D0           ;for error use
07BE| 4202                          CLR.B   D2              ;clear old data value
07C0| 4210                          MOVE.B   #0,(A0)        ;and the timer latches
07C2| 4211                          MOVE.B   #0,(A1)
07C4|
07C4| 363C 00FF                     MOVE    #$FF,D3         ;set up start value
07C8|                               BSRS4   VIARW           ;go do read/write test
07C8| 49FA 0004            #          LEA      @1,A4
07CC| 6002                 #          BRA.S    VIARW
07CE|                      #@1
07CE|                               RTS6                    ;and return
07CE| 4ED6                 #          JMP      (A6)
07D0|
07D0|                       ;  Subroutine to do read/write test - loops thru all 256 values
07D0|
07D0| B410                  VIARW   CMP.B   (A0),D2         ;check for old values first
07D2| 6620                          BNE.S   VIAFAIL
07D4| B411                          CMP.B   (A1),D2
07D6| 661C                          BNE.S   VIAFAIL
07D8|
07D8| 1083                          MOVE.B  D3,(A0)         ;set new value in low timer latch
07DA| B411                          CMP.B   (A1),D2         ;ensure high latch not affected
07DC| 6616                          BNE.S   VIAFAIL
07DE| B610                          CMP.B   (A0),D3         ;verify new low latch setting
07E0| 6612                          BNE.S   VIAFAIL
07E2|
07E2| 1283                          MOVE.B  D3,(A1)         ;set new value in high timer latch
07E4| B610                          CMP.B   (A0),D3         ;ensure low latch not affected
07E6| 660C                          BNE.S   VIAFAIL
07E8| B611                          CMP.B   (A1),D3         ;verify new high latch setting
07EA| 6608                          BNE.S   VIAFAIL
07EC|
07EC| 1403                          MOVE.B  D3,D2           ;the new value becomes the old
07EE| 51CB FFE0                     DBF     D3,VIARW        ;loop thru all 256 values
07F2| 6002                          BRA.S   VIARWEND
07F4|
07F4| 5240                  VIAFAIL ADDQ    #1,D0           ;set for error
07F6|
07F6| 4A40                  VIARWEND TST    D0              ;set zero bit indicator
07F8|                               RTS4
07F8| 4ED4                 #          JMP      (A4)
07FA|                               .ENDC
07FA|                               .PAGE
07FA|                       ;--------------------------------------------------------------------------
07FA|                       ;  Subroutine to set contrast latch - sets for default, off or value in D0
07FA|                       ;--------------------------------------------------------------------------
07FA|
07FA| 103C 0080             CONSET  MOVE.B  #$80,D0         ;set mid range value default
07FE| 6002                          BRA.S   CONSET2
0800|
0800| 70FF                  CONOFF  MOVEQ   #-1,D0          ;set for contrast off
0802|                       CONSET2                         ;for external entry
0802| 207C 00FC D901                MOVE.L  #VIA2BASE,A0    ;GET 6522 BASE ADDR
0808| 117C 0084 0010                MOVE.B  #$84,DDRB2(A0)  ;ENSURE NO STRAY DATA TO CONTRAST
080E| 10BC 0004                     MOVE.B  #4,ORB2(A0)     ; LATCH BY DISABLING DRIVERS
0812| 117C 00FF 0018                MOVE.B  #$FF,DDRA2(A0)  ;NOW SET PORT A AS OUTPUTS
0818| 1140 0008                     MOVE.B  D0,ORA2(A0)     ;set contrast value
081C| 08D0 0007                     BSET    #7,ORB2(A0)     ;AND STROBE IT
0820|
0820|                               RTS4                    ;RETURN TO CALLER
0820| 4ED4                 #          JMP      (A4)
0822|
0822|
0822|                               .PAGE
0822|                       ;-------------------------------------------------------------------------
0822|                       ;  Test memory to be used for screen.  The screen can then be
0822|                       ;  used for test icon display.  Default choice is last 32K of memory.
0822|                       ;  If this is invalid, do backwards scan through memory until a valid
0822|                       ;  area is found.
0822|                       ;  Assumes:  location SCRNBASE = base address of default screen (set by
0822|                       ;   sizing routine)
0822|                       ;-------------------------------------------------------------------------
0822|
0822|                       SCRNTST
0822|                               .IF  DIAGS = 1
0822|
0822| 2078 0110                     MOVE.L  SCRNBASE,A0     ;get base address of screen
0826| 2278 02A8                     MOVE.L  TOTLMEM,A1      ;set end address
082A|                               BSR4    RAMTEST         ;and go do test
082A| 49FA 0006            #          LEA      @1,A4
082E| 6000 0680            #          BRA      RAMTEST
0832|                      #@1
0832| 676E                          BEQ.S   INVTST          ;continue if no error
0834| 08C7 0015                     BSET    #MEM,D7         ;else set memory read/write error
0838|
0838|                       ;  save error results and then start search for good video page
0838|
0838| 6100 064A                     BSR     TSTINIT         ;initialize for further testing
083C| 6136                          BSR.S   SCRNSAV         ;save results
083E|
083E| 2278 0110                     MOVE.L  SCRNBASE,A1     ;set new search end address
0842| 2049                          MOVE.L  A1,A0
0844| 247C 0000 8000                MOVE.L  #HEX32K,A2      ;screen size is 32K
084A| 91CA                          SUBA.L  A2,A0           ;set new start addr (end-32K)
084C|
084C| 48E7 00E0             @1      MOVEM.L A0-A2,-(SP)     ;save search addresses
0850|                               BSR4    RAMTEST         ;go test
0850| 49FA 0006            #          LEA      @1,A4
0854| 6000 065A            #          BRA      RAMTEST
0858|                      #@1
0858| 4CDF 0700                     MOVEM.L (SP)+,A0-A2     ;restore addresses (no effect on CCR)
085C| 670E                          BEQ.S   SCRNOK          ;skip if OK (non-zero CCR if error)
085E| 2808                          MOVE.L  A0,D4           ;else go save results
0860| 6112                          BSR.S   SCRNSAV
0862| 2248                          MOVE.L  A0,A1           ;set next end
0864| 91CA                          SUBA.L  A2,A0           ; and start addresses
0866| 2008                          MOVE.L  A0,D0           ;continue thru all of memory if necessary
0868| 6EE2                          BGT.S   @1
086A|
086A| 6036                  SCRNERR BRA.S   INVTST          ;continue testing, leave screen at default
086C|
086C| 21C8 0110             SCRNOK  MOVE.L  A0,SCRNBASE     ;save new screen base
0870| 6114                          BSR.S   SETVLTCH        ;and go set video latch
0872| 602E                          BRA.S   INVTST          ;and exit to next test
0874|
0874|                       ;-------------------------------------------------------------------------
0874|                       ;  Subroutine to save error results from screen test routine
0874|                       ;  Inputs:
0874|                       ;       A3 = ptr to base of save result area
0874|                       ;       D4 = base address of test area
0874|                       ;  Outputs:
0874|                       ;       None
0874|                       ;  Side Effects:
0874|                       ;       D1/D3-D4 trashed
0874|                       ;-------------------------------------------------------------------------
0874|
0874| 7211                  SCRNSAV MOVEQ   #17,D1          ;divide base address by 128K
0876| E2AC                          LSR.L   D1,D4
0878| D844                          ADD     D4,D4           ;double for word index to save area
087A| 2203                          MOVE.L  D3,D1           ;combine error results
087C| 4843                          SWAP    D3
087E| 8641                          OR      D1,D3
0880| 8773 4000                     OR      D3,0(A3,D4)     ;save and exit
0884| 4E75                          RTS
0886|
0886|                       ;-------------------------------------------------------------------------
0886|                       ;  Subroutine to set the video latch
0886|                       ;  Inputs:
0886|                       ;       Location SCRNBASE = logical base address for screen
0886|                       ;  Outputs:
0886|                       ;       None
0886|                       ;  Side Effects:
0886|                       ;       D0-D1 trashed
0886|                       ;-------------------------------------------------------------------------
0886|
0886|                       SETVLTCH
0886| 2438 0110                     MOVE.L  SCRNBASE,D2     ;get logical screen base address
088A| 2238 02A8                     MOVE.L  TOTLMEM,D1      ;get physical amount of memory
088E| 9282                          SUB.L   D2,D1           ;compute screen base offset
0890| 2038 0294                     MOVE.L  MAXMEM,D0       ;get max physical address
0894| 9081                          SUB.L   D1,D0           ;compute physical screen base address
0896| E088                          LSR.L   #8,D0           ;convert to page value
0898| EE88                          LSR.L   #7,D0
089A| 13C0 00FC E800                MOVE.B  D0,VIDLTCH      ;set latch
08A0| 4E75                          RTS                     ;and exit
08A2|
08A2|                               .PAGE
08A2|                       ;-------------------------------------------------------------------------
08A2|                       ;  Now check state of INVID bit to see if inverse video is installed.
08A2|                       ;  If yes, rewrite last 4 words of screen page to avoid retrace line.
08A2|                       ;-------------------------------------------------------------------------
08A2|
08A2|                       INVTST
08A2|                               .IF  INVERTCK = 1       ;                                       CHG013
08A2|                               .ENDC                   ;{INVERTCK}                             CHG013
08A2|                               .ENDC                   ;{DIAGS}
08A2|
08A2|                       ;-------------------------------------------------------------------------
08A2|                       ; Continue testing by now doing COPS VIA test
08A2|                       ;-------------------------------------------------------------------------
08A2|
08A2|                       VIA1TST
08A2|                               .IF  USERINT = 1
08A2|
08A2|                       ;  Draw desktop on screen for test icon display
08A2|
08A2| 6100 2832                     BSR     DRAWDESK        ;draw the desk
08A6| 6134                          BSR.S   DSPCPURM        ;and CPU ROM id                 CHG001
08A8|
08A8|                               .ENDC
08A8|
08A8|                               BSR4    CONSET          ;set default contrast
08A8| 49FA 0006            #          LEA      @1,A4
08AC| 6000 FF4C            #          BRA      CONSET
08B0|                      #@1
08B0|
08B0|                               .IF  ROM16K = 1
08B0| 47FA 0546             VIA1CHK LEA     VIA1VCT,A3      ;first set up bus error vector
08B4| 21CB 0008                     MOVE.L  A3,BUSVCTR
08B8| 207C 00FC DD8D                MOVE.L  #,A0 ;set base address of timer low latch
08BE| 7002                          MOVEQ   #2,D0           ;set offset to high latch
08C0|                               BSR6    VIATST          ;go test
08C0| 4DFA 0006            #          LEA      @1,A6
08C4| 6000 FEF2            #          BRA      VIATST
08C8|                      #@1
08C8| 670C                          BEQ.S   @2              ;skip if OK
08CA| 08C7 000A                     BSET    #VIA1,D7        ;else set error bit
08CE| 4A87                          TST.L   D7              ;loop?
08D0| 6BDE                          BMI.S   VIA1CHK         ;yes - test again
08D2| 6000 0AC6                     BRA     TSTCHK          ;else abort further testing
08D6|
08D6| 4A87                  @2      TST.L   D7              ;check for loop mode
08D8| 6BD6                          BMI.S   VIA1CHK
08DA| 600E                          BRA.S   COPSENBL        ;else go test COPS
08DC|
08DC|                       ;------------------------------------------------------------------------
08DC|                       ;  Subroutine to display CPU ROM id
08DC|                       ;------------------------------------------------------------------------
08DC|
08DC|                       DSPCPURM
08DC| 103A 371F                     MOVE.B  REV,D0          ;read ROM rev                           CHG001
08E0| 7A03                          MOVEQ   #ROMIDROW,D5    ;setup cursor ptrs                      CHG001
08E2| 7C50                          MOVEQ   #ROMIDCOL,D6    ;                                       CHG001
08E4| 6100 2E54                     BSR     DSPVAL          ;do display                             CHG001
08E8| 4E75                          RTS                     ;                                       CHG001
08EA|
08EA|                               .ENDC
08EA|                               .PAGE
08EA|                       ;-------------------------------------------------------------------------
08EA|                       ;  Try turning COPS on so that keyboard commands can be received
08EA|                       ;-------------------------------------------------------------------------
08EA|
08EA|                       COPSENBL
08EA| 47FA 002A                     LEA     COPSVCT,A3      ;set up bus error vector first
08EE| 21CB 0008                     MOVE.L  A3,BUSVCTR
08F2| 612C                          BSR.S   CPSINIT         ;enable COPS
08F4| 6514                          BCS.S   COPSBAD         ;skip if error
08F6| 4A87                          TST.L   D7              ;looping desired?
08F8| 6BF0                          BMI.S   COPSENBL        ;go repeat test
08FA|
08FA| 2007                          MOVE.L  D7,D0           ;get error indicator
08FC| 0280 001F FFFF                ANDI.L  #CPIOMSK,D0     ;mask off don't care bits
0902| 6700 00BE                     BEQ     RSTSCAN         ;continue if OK to do reset scan
0906| 6000 0A92                     BRA     TSTCHK          ;else go report error
090A|
090A| 08C7 000C             COPSBAD BSET    #IOCOPS,D7      ;else set COPS error
090E| 4A87                          TST.L   D7              ;looping desired?
0910| 6BD8                          BMI.S   COPSENBL        ;go repeat test
0912| 6000 0A86                     BRA     TSTCHK          ;else abort further testing
0916|
0916|                       ;-----------------------------------------------------------------------------
0916|                       ;  Bus error handler for COPS testing with entry point for other I/O tests
0916|                       ;-----------------------------------------------------------------------------
0916|
0916| 7034                  COPSVCT MOVEQ   #EIOCOP,D0      ;SET ERROR CODE
0918| 08C7 0012             IOVCT   BSET    #IOEXCP,D7      ;SET I/O EXCEPTION ERROR
091C| 6000 FE3A                     BRA     EXCP0           ;AND GO HANDLE EXCEPTION
0920|
0920|                       ;-----------------------------------------------------------------------------
0920|                       ;  Subroutine to initiialize COPS interface for use
0920|                       ;-----------------------------------------------------------------------------
0920| 207C 00FC DD81        CPSINIT MOVEA.L #VIA1BASE,A0    ;GET VIA BASE ADDRESS
0926| 117C 0001 0016                MOVE.B  #$01,ACR1(A0)   ;SET PORT A LATCH ENABLE
092C| 0028 0009 0018                OR.B    #$09,PCR1(A0)   ;SET HANDSHAKE ENABLE
0932| 117C 007F 001C                MOVE.B  #$7F,IER1(A0)   ;CLEAR ALL INTRPT ENABLES
0938| 117C 007F 001A                MOVE.B  #$7F,IFR1(A0)   ;AND CLEAR FLAGS
093E|
093E|                       ;  Now turn COPS on, disabling mouse and NMI key
093E|
093E| 4240                  TURNON  CLR     D0              ;SET FOR PORT ON CMD
0940| 6114                          BSR.S   COPSCMD         ;SEND TO COPS
0942| 6510                          BCS.S   @1              ;EXIT IF TIMEOUT ERROR
0944|
0944| 7070                          MOVEQ   #$70,D0         ;DISABLE MOUSE
0946| 610E                          BSR.S   COPSCMD
0948| 650A                          BCS.S   @1
094A|
094A|                               .IF  DEBUG = 0
094A| 7050                          MOVEQ   #$50,D0         ;disable NMI key
094C| 6108                          BSR.S   COPSCMD
094E| 6504                          BCS.S   @1
0950| 7060                          MOVEQ   #$60,D0
0952| 6102                          BSR.S   COPSCMD
0954|                               .ENDC
0954|
0954| 4E75                  @1      RTS                     ;AND EXIT
0956|
0956|                               .PAGE
0956|                       ;-----------------------------------------------------------------------------
0956|                       ;  Subroutine to send cmd to COPS
0956|                       ;  Assumes registers:
0956|                       ;       D0 = cmd value
0956|                       ;  If COPS does not respond, timeout error indicated by setting carry bit.
0956|                       ;-----------------------------------------------------------------------------
0956|
0956|                       COPSCMD
0956| 48E7 F8E0                     MOVEM.L D0-D4/A0-A2,-(SP) ;save regs
095A|                               DISABLE                 ;disable all interrupts
095A| 40E7                 #          MOVE     SR,-(SP)
095C| 007C 0700            #          ORI      #$0700,SR
0960| 207C 00FC DD81                MOVEA.L #VIA1BASE,A0    ;set COPS VIA interface ptr
0966| 2248                          MOVEA.L A0,A1           ;save for use as port B output reg address
0968| 2448                          MOVEA.L A0,A2
096A| D4FC 0006                     ADDA    #DDRA1,A2       ;compute address for port A data direction reg
096E| 7440                          MOVEQ   #$40,D2         ;set up constants for later use
0970| 76FF                          MOVEQ   #-1,D3
0972| 7806                          MOVEQ   #6,D4
0974|
0974| 1140 001E                     MOVE.B  D0,PORTA1(A0)   ;set cmd in data reg (no handshake)
0978|
0978|                       ;---------------------------------------------------------------------------
0978|                       ;  First find a ready state (CRDY low)
0978|                       ;  Each of the following loops take about 32 machine cycles = 6.4 us plus
0978|                       ;  a variable amount of time for sync with 6522 (max = 2us)
0978|                       ;---------------------------------------------------------------------------
0978|
0978| 323C 061A                     MOVE    #$061A,D1       ;set timeout for about 10 ms
097C| 5341                  @3      SUBQ    #1,D1
097E| 6732                          BEQ.S   @1              ;exit if timeout
0980| 0911                          BTST    D4,(A1)         ;else wait for "ready" (bit 6 = CRDY)
0982| 66F8                          BNE.S   @3
0984|
0984|                       ;  Now find the next ready state to insure enough time available for data
0984|
0984| C0FC 0001                     MULU    #1,D0           ;kill some time (about 15.2 us) to get
0988|                                                       ; out of previous CRDY
0988| 323C 061A                     MOVE    #$061A,D1       ;reinit timeout count
098C| 5341                  @4      SUBQ    #1,D1
098E| 6722                          BEQ.S   @1              ;exit if timeout
0990| 0911                          BTST    D4,(A1)         ;wait for another "ready"
0992| 66F8                          BNE.S   @4
0994|
0994| 1483                          MOVE.B  D3,(A2)         ; ok, jam out the data
0996|
0996|                       ;  Now wait for CRDY high and then hold data for COPS to read
0996|
0996| 323C 061A                     MOVE    #$061A,D1       ;set timeout for about 10 ms
099A| 5341                  @5      SUBQ    #1,D1
099C| 6714                          BEQ.S   @1              ;exit if timeout
099E| 0911                          BTST    D4,(A1)         ;wait for "not-ready"
09A0| 67F8                          BEQ.S   @5
09A2|
09A2| 700A                          MOVEQ   #$A,D0          ; force about a 40 ms
09A4| 5340                  @6      SUBQ    #1,D0           ;  delay for COPS hold time
09A6| 6EFC                          BGT.S   @6
09A8|
09A8| 4212                          CLR.B   (A2)            ; reset direction reg now
09AA| 117C 0082 001C                MOVE.B  #$82,IER1(A0)   ;  and, enable CA1
09B0| 6008                          BRA.S   @2              ; go to normal exit
09B2|
09B2|                       ;  Timeout occurred - set error indicator
09B2|                       @1      ENABLE                  ;reenable
09B2| 46DF                 #          MOVE     (SP)+,SR
09B4| 003C 0001                     ORI.B   #$01,CCR        ;set carry bit
09B8| 6002                          BRA.S   @9              ;skip to exit
09BA|
09BA|                       @2      ENABLE                  ;restore interrupt levels
09BA| 46DF                 #          MOVE     (SP)+,SR
09BC| 4CDF 071F             @9      MOVEM.L (SP)+,D0-D4/A0-A2 ;restore regs
09C0| 4E75                          RTS                     ;and return to caller
09C2|
09C2|                               .PAGE
09C2|                       ;-------------------------------------------------------------------------
09C2|                       ;  Scan COPS for proper reset codes.  Delay added for normal COPS power-up
09C2|                       ;  time of about 1.7 seconds.
09C2|                       ;
09C2|                       ;  Send reset signal and then scan keyboard/mouse interface.  First "clears"
09C2|                       ;  COPS of any pending codes, and then issues reset.  Works via
09C2|                       ;  a "state machine" that checks codes received and sets flags as follows:
09C2|                       ;
09C2|                       ;       D1 = 0 - reset signal in place
09C2|                       ;          = 1 - reset signal removed
09C2|                       ;       D3 = 0 - no keyboard codes received => keyboard disconnected
09C2|                       ;          = 1 - keyboard disconnect code ($80/$FD) received
09C2|                       ;                 => ignore, may be old keyboard
09C2|                       ;          = 2 - keyboard disconnect/connect codes ($80/$FD/$80/id) received
09C2|                       ;                 => keyboard connected
09C2|                       ;
09C2|                       ;       D4 = 0 - no mouse codes received => mouse connected
09C2|                       ;          = 1 - only mouse connect code ($87) received => ignore, may be old sys
09C2|                       ;          = 2 - mouse connect/disconnect ($87/$07) codes received
09C2|                       ;                 => mouse disconnected
09C2|                       ;--------------------------------------------------------------------------
09C2|
09C2|                       RSTSCAN
09C2| 2278 0260                     MOVE.L  KBDQPTR,A1      ;setup buffer ptrs
09C6| 347C 02C0                     MOVEA   #QEND,A2
09CA| 616C                  @1      BSR.S   GETJMP          ;clear COPS queue, saving data
09CC| 64FC                          BCC.S   @1
09CE|
09CE| 6100 00DA                     BSR     RSTKBD          ;do reset of keyboard/mouse interfaces
09D2|
09D2|                               .IF  ROM4K = 0
09D2| 4281                          CLR.L   D1              ;init some flags
09D4| 4283                          CLR.L   D3
09D6| 4284                          CLR.L   D4
09D8| 615E                          BSR.S   GETJMP          ;check for data
09DA| 6560                          BCS.S   RSTXIT          ;exit if none (may be old keyboard)
09DC|
09DC|                       ;  State 0 - waiting for reset flag or mouse connect code
09DC| 0C00 0080             RST0    CMPI.B  #RSTCODE,D0     ;reset flag?
09E0| 6724                          BEQ.S   RST1            ;skip if yes to state 1
09E2| 0C00 0087                     CMPI.B  #MSPLG,D0       ;mouse connect code?
09E6| 670E                          BEQ.S   RST2            ;skip if yes to state 2
09E8| 0C00 0007                     CMPI.B  #MSUNPLG,D0     ;mouse disconnect code only?
09EC| 6602                          BNE.S   GET0
09EE| 7802                          MOVEQ   #2,D4           ;set flag for disconnect state
09F0| 6146                  GET0    BSR.S   GETJMP          ;go get next code
09F2| 6548                          BCS.S   RSTXIT          ;exit if no more codes
09F4| 60E6                          BRA.S   RST0            ;else continue scan loop
09F6|
09F6|                       ;  State 2 - waiting for mouse unplugged code
09F6|
09F6| 7801                  RST2    MOVEQ   #1,D4           ;set flag for mouse connect received
09F8| 613E                          BSR.S   GETJMP          ;go get next byte
09FA| 6540                          BCS.S   RSTXIT          ;exit if none or queue full
09FC| 0C00 0007                     CMPI.B  #MSUNPLG,D0     ;mouse disconnect code?
0A00| 66DA                          BNE.S   RST0            ;no - return to state 0
0A02| 7802                          MOVEQ   #2,D4           ;yes - set flag
0A04| 60EA                          BRA.S   GET0            ;and return to state 0
0A06|
0A06|                       ;  State 1 - waiting for reset code
0A06|
0A06| 6130                  RST1    BSR.S   GETJMP          ;go get next byte
0A08| 6532                          BCS.S   RSTXIT          ;exit if no more
0A0A| 0C00 00FD                     CMPI.B  #KUNPLG,D0      ;keyboard unplugged code?
0A0E| 6604                          BNE.S   @1              ;skip if not
0A10| 7601                          MOVEQ   #1,D3           ;else set flag
0A12| 60DC                          BRA.S   GET0            ;and return to state 0
0A14|
0A14| 0C00 00DF             @1      CMPI.B  #$DF,D0         ;id code?
0A18| 6208                          BHI.S   @2              ;skip if not
0A1A| 11C0 01B2                     MOVE.B  D0,KEYID        ;else save for later use
0A1E| 7602                          MOVEQ   #2,D3           ;update flag
0A20| 60CE                          BRA.S   GET0            ;and return to state 0
0A22| 0C00 00FF             @2      CMPI.B  #KCERR,D0       ;Keyboard COPS error?
0A26| 6604                          BNE.S   @3              ;skip if not
0A28| 08C7 000D                     BSET    #KBDCOPS,D7     ;else set error indicator
0A2C|
0A2C| 0C00 00FE             @3      CMPI.B  #ICERR,D0       ;I/O COPS error code?
0A30| 6604                          BNE.S   @4              ;skip if not
0A32| 08C7 000C                     BSET    #IOCOPS,D7      ;else set error indicator
0A36|
0A36| 60B8                  @4      BRA.S   GET0            ;continue scan from state 0
0A38|
0A38|                       ;  Insert to save code space
0A38|
0A38| 6144                  GETJMP  BSR.S   GETDATA         ;go get COPS data
0A3A| 4E75                          RTS                     ;and return to caller
0A3C|                       ;  Reset exit - analyze results
0A3C|
0A3C| 4A01                  RSTXIT  TST.B   D1              ;reset signal lifted?
0A3E| 660A                          BNE.S   @1              ;skip if yes
0A40| 6100 0082                     BSR     CLRRST          ;else remove reset signal
0A44| 7201                          MOVEQ   #1,D1           ;set "removed flag"
0A46| 6136                          BSR.S   GETDATA         ;any data?
0A48| 6492                          BCC.S   RST0            ;go decode if yes
0A4A|
0A4A|                       @1
0A4A|                               .IF  FINKBD = 1
0A4A| 4A03                          TST.B   D3              ;any keyboard data detected?
0A4C| 6604                          BNE.S   MSCHK           ;skip if yes - assume keybd connected
0A4E| 08C7 0017                     BSET    #KBDOUT,D7      ;if none, keyboard is disconnected
0A52|
0A52|                       MSCHK
0A52| 4A04                          TST.B   D4              ;any mouse data?
0A54| 6714                          BEQ.S   SCANXIT         ;skip if none - mouse connected
0A56|
0A56| 5344                  @1      SUBQ    #1,D4           ;flag = 1?
0A58| 6710                          BEQ.S   SCANXIT         ;ignore if yes
0A5A|
0A5A| 08C7 0018                     BSET    #MOUSOUT,D7     ;else mouse disconnected
0A5E| 600A                          BRA.S   SCANXIT         ;and go to exit
0A60|
0A60|                               .ELSE
0A60|                               .ENDC                   ;{FINKBD}
0A60|
0A60|                       ;  Error exits - set appropriate indicator
0A60|
0A60| 08C7 0014             SCANERR BSET    #IOKBD,D7       ;I/O or keyboard failure
0A64| 6004                          BRA.S   SCANXIT
0A66|
0A66| 08C7 000C             IOCERR  BSET    #IOCOPS,D7      ;I/O COPS error
0A6A|
0A6A|                               .ELSE
0A6A|                               .ENDC                   ;{ROM4K}
0A6A|
0A6A| 21C9 0260             SCANXIT MOVE.L  A1,KBDQPTR      ;save queue ptr for later use
0A6E|
0A6E|                               .IF  ROM4K = 0
0A6E| 2007                          MOVE.L  D7,D0           ;check error codes
0A70| 0280 0018 3000                ANDI.L  #SCANMSK,D0     ; for scan errors
0A76| 4A80                          TST.L   D0              ;any found?
0A78| 6600 0920                     BNE     TSTCHK          ;skip if yes
0A7C|                               .ENDC
0A7C|
0A7C| 606A                          BRA.S   BEEP            ;else continue testing
0A7E|
0A7E|                       ;-------------------------------------------------------------------------
0A7E|                       ;  Subroutine to get COPS data
0A7E|                       ;  Assumes registers:
0A7E|                       ;       D0 - scratch use        A0 - VIA address
0A7E|                       ;       D1 - unused             A1 - Ptr to data save area
0A7E|                       ;       D2 - scratch use        A2 - Ptr to end of data area
0A7E|                       ;  Puts data in save area and also leaves in register D0.
0A7E|                       ;  Carry bit set if timeout error or keyboard queue full.
0A7E|                       ;-------------------------------------------------------------------------
0A7E|
0A7E| B5C9                  GETDATA CMPA.L  A1,A2           ;check if at end of queue
0A80| 671A                          BEQ.S   @2              ;exit if yes
0A82| 243C 0000 01FF                MOVE.L  #$1FF,D2        ;else set timeout for about 5 ms
0A88| 207C 00FC DD81                MOVEA.L #VIA1BASE,A0    ;set COPS VIA interface ptr
0A8E| 1028 001A             @1      MOVE.B  IFR1(A0),D0     ;check if data avail
0A92| 0800 0001                     BTST    #1,D0
0A96| 660A                          BNE.S   GETIT           ;skip if yes
0A98| 5342                          SUBQ    #1,D2
0A9A| 66F2                          BNE.S   @1              ;else continue
0A9C| 003C 0001             @2      ORI.B   #$01,CCR        ;set timeout error
0AA0| 4E75                          RTS
0AA2|
0AA2| 1028 0002             GETIT   MOVE.B  ORA1(A0),D0     ;read data
0AA6| 12C0                          MOVE.B  D0,(A1)+        ;save it
0AA8| 4E75                          RTS                     ;and exit with results
0AAA|
0AAA|                               .PAGE
0AAA|                       ;-------------------------------------------------------------------------
0AAA|                       ;  Subroutine to do reset of keyboard and mouse interfaces
0AAA|                       ;  Inputs:
0AAA|                       ;       None
0AAA|                       ;  Outputs:
0AAA|                       ;       None
0AAA|                       ;  Side Effects:
0AAA|                       ;       D0/A0 trashed
0AAA|                       ;-------------------------------------------------------------------------
0AAA|
0AAA| 207C 00FC DD81        RSTKBD  MOVEA.L #VIA1BASE,A0    ;set VIA ptr
0AB0| 0890 0000                     BCLR    #0,ORB1(A0)     ;set reset signal
0AB4| 0028 0001 0004                ORI.B   #$01,DDRB1(A0)  ;send it
0ABA| 203C 0000 0BB8                MOVE.L  #3000,D0        ;do delay for 12 ms
0AC0| 6120                          BSR.S   DELAY
0AC2| 4E75                          RTS
0AC4|
0AC4|                       ;-------------------------------------------------------------------------
0AC4|                       ;  Subroutine to remove reset signal for keyboard and mouse interfaces
0AC4|                       ;  Inputs:
0AC4|                       ;       A0 = ptr to parallel port VIA (set in RSTKBD routine)
0AC4|                       ;  Outputs:
0AC4|                       ;       None
0AC4|                       ;  Side Effects:
0AC4|                       ;       D0 trashed
0AC4|                       ;-------------------------------------------------------------------------
0AC4|
0AC4| 08D0 0000             CLRRST  BSET    #0,ORB1(A0)     ;remove reset signal
0AC8| 6112                          BSR.S   KBDDELAY        ;delay for keyboard reset time
0ACA| 4E75                          RTS
0ACC|
0ACC|                       ;----------------------------------------------------------------------------
0ACC|                       ; Subroutine to delay for count in D0 (each count = 4 us).  Additional
0ACC|                       ; entry points set up for fixed delays.
0ACC|                       ;----------------------------------------------------------------------------
0ACC|
0ACC|                               .IF  ROM4K = 0
0ACC| 203C 0000 61A8        DELAY_1 MOVE.L  #TNTHSEC,D0     ;.1 second delay
0AD2| 600E                          BRA.S   DELAY
0AD4|
0AD4| 203C 0013 12D0        DELAY5  MOVE.L  #FIVESEC,D0     ;5 second delay
0ADA| 6006                          BRA.S   DELAY
0ADC|
0ADC|                       KBDDELAY
0ADC| 203C 0006 7C28                MOVE.L  #KBDDLY,D0      ;delay for COPS debounce loop
0AE2|                               .ENDC
0AE2|
0AE2| 5380                  DELAY   SUBQ.L  #1,D0           ;loop until count = 0
0AE4| 66FC                          BNE.S   DELAY
0AE6| 4E75                          RTS
0AE8|
0AE8|                               .PAGE
0AE8|                       ;-------------------------------------------------------------------------
0AE8|                       ; Sound starting "tone"
0AE8|                       ;-------------------------------------------------------------------------
0AE8|
0AE8|                       BEEP
0AE8| 6104                          BSR.S   CLICK           ;go click speaker
0AEA| 6000 00AA                     BRA     VIDTST          ;then go do video test
0AEE|
0AEE|                       ;-------------------------------------------------------------------------
0AEE|                       ; Subroutine to set parms for speaker "click"
0AEE|                       ;-------------------------------------------------------------------------
0AEE|
0AEE| 103C 00A0             CLICK   MOVE.B  #$A0,D0         ;set frequency
0AF2| 7200                          MOVEQ   #0,D1           ;and duration
0AF4| 7408                          MOVEQ   #8,D2           ;and volume (medium)                    RM000
0AF6|                                                       ;then fall thru to tone routine         RM000
0AF6|
0AF6|                       ;-------------------------------------------------------------------------
0AF6|                       ;  Routine to beep the speaker
0AF6|                       ;  Assumes regs set up as
0AF6|                       ;    D0 = desired frequency ($00 - $AA)
0AF6|                       ;    D1 = duration (0 = .5 msec)
0AF6|                       ;    D2 = volume (0,2,4,...,E)
0AF6|                       ;-------------------------------------------------------------------------
0AF6|
0AF6| 48E7 1088             TONE    MOVEM.L A0/A4/D3,-(SP)  ;save regs
0AFA|                               BSRS4   TONE2           ;go do tone
0AFA| 49FA 0004            #          LEA      @1,A4
0AFE| 6006                 #          BRA.S    TONE2
0B00|                      #@1
0B00| 4CDF 1108                     MOVEM.L (SP)+,A0/A4/D3  ;restore and exit
0B04| 4E75                          RTS
0B06|
0B06|                       ;  separate entry point for call without memory usage
0B06|
0B06| 207C 00FC DD81        TONE2   MOVEA.L #VIA1BASE,A0    ;set VIA ptr
0B0C| 0028 000E 0004                ORI.B   #$0E,DDRB1(A0)  ;set volume bits for output
0B12| 0210 00F1                     ANDI.B  #$F1,ORB1(A0)   ;clear and then
0B16| 8510                          OR.B    D2,ORB1(A0)     ; set volume bits
0B18| 0228 00E3 0016                ANDI.B  #$E3,ACR1(A0)   ;clear shift mode bits
0B1E| 0028 0010 0016                ORI.B   #$10,ACR1(A0)   ;set shift reg for continuous rotate
0B24|
0B24|                       ; check system type
0B24|
0B24| 4A39 00FC C031                TST.B   DISKROM         ;test for Lisa 1 board                  CHG014
0B2A| 6A10                          BPL.S   @3              ;no changes if yes                      CHG014
0B2C| 0839 0005 00FC C031           BTST    #SLOTMR,DISKROM ;else check if slow timers              CHG029
0B34| 6606                          BNE.S   @3              ;skip if yes                            CHG029
0B36| 1600                          MOVE.B  D0,D3           ;else adjust input parm                 CHG014
0B38| E40B                          LSR.B   #2,D3           ; by factor of .25                      CHG014
0B3A| D003                          ADD.B   D3,D0           ;                                       CHG014
0B3C|
0B3C| 1140 0010             @3      MOVE.B  D0,T2CL1(A0)    ;set frequency
0B40| 117C 000F 0014                MOVE.B  #$0F,SHR1(A0)   ;set for square wave and trigger
0B46|
0B46|                       ;  Do time delay -  enter with count in D1 (about .5 msec per count)
0B46|
0B46| 363C 00D0             @1      MOVE.W  #$00D0,D3       ;set delay constant
0B4A| 51CB FFFE             @2      DBF     D3,@2
0B4E| 51C9 FFF6                     DBF     D1,@1
0B52|
0B52| 0228 00E3 0016        SILENCE ANDI.B  #$E3,ACR1(A0)   ;disable tone
0B58|                               RTS4                    ;and return
0B58| 4ED4                 #          JMP      (A4)
0B5A|
0B5A|
0B5A|                               .IF  DIAGS = 1
0B5A|                       ;-------------------------------------------------------------------------
0B5A|                       ;   Routine to handle I/O board selection errors.  Does check for access
0B5A|                       ;   of other I/O board devices to try to pinpoint error.
0B5A|                       ;-------------------------------------------------------------------------
0B5A|
0B5A| 08C7 0010             NOIO    BSET    #RS232B,D7      ;set SCC port B access error            CHG027
0B5E| 3E7C 0480                     MOVE    #STKBASE,SP     ;restore stack pointer
0B62|                       ;  try access of other I/O board devices
0B62|
0B62| 47FA 0012                     LEA     NOIO2,A3        ;set up new bus error vector
0B66| 21CB 0008                     MOVE.L  A3,BUSVCTR
0B6A| 207C 00FC D901                MOVE.L  #VIA2BASE,A0    ;set base address                       CHG027
0B70| 4A10                          TST.B   (A0)            ;try access
0B72| 6000 FC0C                     BRA     VIA2TST         ;return to testing if OK                CHG027
0B76|
0B76| 08C7 000B             NOIO2   BSET    #VIA2,D7        ;set VIA #2 error also                  CHG027
0B7A| 47FA 0012                     LEA     NOIO3,A3        ;try final access to VIA #1             CHG027
0B7E| 21CB 0008                     MOVE.L  A3,BUSVCTR
0B82| 207C 00FC DD81                MOVE.L  #VIA1BASE,A0    ;set base address                       CHG027
0B88| 4A10                          TST.B   (A0)
0B8A| 6000 FC96                     BRA.S   SCRNTST         ;exit if OK                             CHG027
0B8E|
0B8E| 08C7 0001             NOIO3   BSET    #CPUSEL,D7      ;most likely CPU board error
0B92|
0B92| 6000 0806                     BRA     TSTCHK          ;go report errors                       CHG027
0B96|
0B96|                               .ENDC
0B96|
0B96|                               .INCLUDE RM248.S.TEXT
0B96|
0B96|                               .PAGE
0B96|                       ;----------------------------------------------------------------------------
0B96|                       ;  VIDEO CIRCUITRY TEST
0B96|                       ;  The following test checks the vertical retrace signal of the
0B96|                       ;  video circuitry to verify it is toggling.
0B96|                       ;  Register usage:
0B96|                       ;       D0 = timeout count      A0 = unused
0B96|                       ;       D1 = unused             A1 = unused
0B96|                       ;       D2 = bit pointer        A2 = unused
0B96|                       ;       D3 = unused             A3 = address to disable VTIR
0B96|                       ;       D4 = unused             A4 = address to enable VTIR
0B96|                       ;       D5 = unused             A5 = address of bus status register
0B96|                       ;----------------------------------------------------------------------------
0B96|
0B96|                       VIDTST
0B96|                               .IF     ROM4K = 0
0B96|
0B96|                               .IF  USERINT = 1
0B96| 6100 25E8                     BSR     MAKETEST        ;display test icons
0B9A| 327C 1DF6                     MOVEA   #CPUSTRT,A1     ;hilite CPU board icon
0B9E| 6100 29D4                     BSR     INVICON
0BA2|                               .ENDC
0BA2|                       VIDCHK
0BA2| 267C 00FC E018                MOVEA.L #VTIRDIS,A3     ;ADDRESS FOR DISABLING VTIR
0BA8| 287C 00FC E01A                MOVEA.L #VTIRENB,A4     ;ADDRESS FOR VTIR ENABLE
0BAE| 2A7C 00FC F801                MOVEA.L #STATREG,A5     ;STATUS REGISTER LOCATION FOR BYTE OPS
0BB4|
0BB4| 303C 0DF4                     MOVE    #$0DF4,D0       ;SET TIMEOUT COUNT FOR ABOUT 20 MS
0BB8| 7402                          MOVEQ   #VRBIT,D2       ;VR BIT LOCATION
0BBA|
0BBA| 4A53                          TST     (A3)            ;RESET THEN
0BBC| 4A54                          TST     (A4)            ; ENABLE VTIR
0BBE| 0515                  @1      BTST    D2,(A5)         ;WAIT FOR LOW
0BC0| 6706                          BEQ.S   @2              ;EXIT IF YES
0BC2| 51C8 FFFA                     DBF     D0,@1           ;ELSE LOOP (ABOUT 5.6 MS PER LOOP)
0BC6| 600C                          BRA.S   VIDERR          ;AND SET ERROR IF TIMEOUT
0BC8|
0BC8| 4A53                  @2      TST     (A3)            ;RESET VTIR
0BCA| 4A54                          TST     (A4)            ;THEN RENABLE
0BCC| 0515                          BTST    D2,(A5)         ;SHOULD BE HIGH BY NOW
0BCE| 6704                          BEQ.S   VIDERR          ;GO TO ERROR EXIT IF NOT
0BD0| 4A53                          TST     (A3)            ;DISABLE VTIR
0BD2| 600C                          BRA.S   VIDXIT          ;and go to exit
0BD4|
0BD4|                       ;  Error exit
0BD4|
0BD4| 08C7 0002             VIDERR  BSET    #VID,D7         ;SET ERROR INDICATOR
0BD8| 4A87                          TST.L   D7              ;in loop mode?
0BDA| 6BC6                          BMI.S   VIDCHK          ;restart test if yes
0BDC| 6000 07BC                     BRA     TSTCHK          ;else go to error msg routine
0BE0|
0BE0|                       ;  Normal exit
0BE0|
0BE0|                       VIDXIT
0BE0|
0BE0|                       ;----------------------------------------------------------------------------
0BE0|                       ;  Now, try reading of system serial number
0BE0|                       ;----------------------------------------------------------------------------
0BE0|
0BE0| 307C 0240                     MOVEA   #SERNUM,A0      ;ptr for save of serial #
0BE4| 6110                          BSR.S   RDSERN          ;go do read
0BE6| 64EC                          BCC.S   VIDERR          ;exit if error
0BE8| 4A79 00FC E018                TST     VTIRDIS         ;else disable vertical retrace
0BEE| 4A87                          TST.L   D7              ;check for loop mode
0BF0| 6BB0                          BMI.S   VIDCHK          ;if not, fall thru to next test
0BF2| 6000 0168                     BRA     PARTST          ;and go on to next test
0BF6|
0BF6|                               .PAGE
0BF6|                       ;--------------------------------------------------------------------------
0BF6|                       ;
0BF6|                       ;  Routine to read system serial # from video prom.
0BF6|                       ;  Written by Ken Schmal and Ron Hochsprung.
0BF6|                       ;
0BF6|                       ;       Register Usage:
0BF6|                       ;
0BF6|                       ;       temporary and iterative                  D0
0BF6|                       ;       temporary and iterative                  D1
0BF6|                       ;       temporary and iterative                  D2
0BF6|                       ;       temporary and iterative                  D3
0BF6|                       ;       boolean FOUND to be returned             D4
0BF6|                       ;       pointer to save area for serial #        A0
0BF6|                       ;       SN1 & SN2 pointer                        A1
0BF6|                       ;       STATUS REGISTER pointer                  A2
0BF6|                       ;       SCRACH array pointer                     A3
0BF6|                       ;       SCRACH END pointer                       A4
0BF6|                       ;       Tag const                                A5
0BF6|                       ;       static link and stack frame
0BF6|                       ;         base pointer register                  A6
0BF6|                       ;
0BF6|                       ;  Returns with carry bit set if all OK.
0BF6|                       ;  All registers except D7 and A0 trashed.
0BF6|                       ;
0BF6|                       ;--------------------------------------------------------------------------
0BF6|
0BF6|                       RDSERN
0BF6|
0BF6| 48E7 0180                     MOVEM.L         D7/A0,-(SP)             ;save regs
0BFA|
0BFA|                       ;       turn off all interrupts
0BFA| 40E7                          move            SR, -(sp)               ;save the present status register
0BFC| 007C 0700                     ori.w           #$0700, SR              ;set interrupt to level 7
0C00|
0C00|                       ;--------------------------------------------------------------------------
0C00|                       ;       now set up registers for the algorithm
0C00|                       ;--------------------------------------------------------------------------
0C00|
0C00| 227C 00FE 8000                move.l          #Snum, a1               ;location in MMU of SN1 & SN2
0C06| 247C 00FC F801                move.l          #Statreg,a2             ;Status Register pointer
0C0C| 4E56 FF18                     link            a6, #dStack             ;make room for SCRACH
0C10| 47EE FF18                     lea             dScrach(a6), a3         ;get pointer for SCRACH
0C14| 49FA 0142                     lea             Tag,a4
0C18| 2D48 FFF8                     move.l          a0,dSavArry(a6)
0C1C|
0C1C|                       ;--------------------------------------------------------------------------
0C1C|                       ;       first we get the block out of the vertical half
0C1C|                       ;--------------------------------------------------------------------------
0C1C|                       ;
0C1C|                       ;       sync up to the vertical retrace bit
0C1C|                       ;
0C1C|
0C1C|                       GetBits1:
0C1C|
0C1C| 7202                          moveq           #2, d1                  ;vertical retrace is bit #2
0C1E| 2D7C 0000 0007 FFFC           move.l          #BytesPerRead,dLcnt(a6) ;read this many bytes
0C26| 4279 00FC E018                clr             VTIRDIS                 ;clear vertical retrace bit
0C2C| 4279 00FC E01A                clr             VTIRENB                 ;set vertical retrace interrupt
0C32| 0312                  @1:     btst            d1, (a2)                ;wait until it's true
0C34| 66FC                          bne.s           @1
0C36|
0C36|                       ;
0C36|                       ;------ read the first block ------
0C36|                       ;
0C36|
0C36| 4C91 00FF             @3:     movem           (a1), d0-d7
0C3A| 4893 00FF                     movem           d0-d7, (a3)
0C3E| 508B                          addq.l          #8, a3
0C40| 508B                          addq.l          #8, a3
0C42| 4E71                          nop
0C44| 7008                          moveq           #dlycnst-1, d0
0C46| 53AE FFFC                     subq.l          #1, dLcnt(a6)
0C4A| 5FC8 FFFE             @4:     dble            d0, @4
0C4E| 6EE6                          bgt.s           @3
0C50|
0C50|                       ;--------------------------------------------------------------------------
0C50|                       ;       then we get the block out of the horizontal half
0C50|                       ;--------------------------------------------------------------------------
0C50|                       ;
0C50|                       ;       kill time until we're near the last vertical retrace line
0C50|                       ;
0C50|
0C50|                       GetBits2:
0C50| 2D7C 0000 0007 FFFC           move.l          #BytesPerRead, dLcnt(a6);get the last few bytes
0C58| 303C 00AB                     move.w          #TKiller-1, d0          ;time killer constant
0C5C| 51C8 FFFE             @1:     dbra            d0, @1                  ;loop
0C60|
0C60|                       ;
0C60|                       ;------ read the second or last block ------
0C60|                       ;
0C60|
0C60| 4C91 00FF             @2:     movem           (a1), d0-d7
0C64| 4893 00FF                     movem           d0-d7, (a3)
0C68| 508B                          addq.l          #8, a3
0C6A| 508B                          addq.l          #8, a3
0C6C| 4E71                          nop
0C6E| 7008                          moveq           #dlycnst-1, d0
0C70| 53AE FFFC                     subq.l          #1, dLcnt(a6)
0C74| 5FC8 FFFE             @3:     dble            d0, @3
0C78| 6EE6                          bgt.s           @2
0C7A|
0C7A|                       ;--------------------------------------------------------------------------
0C7A|                       ;       now we have to find sync bytes and extract the bit stream
0C7A|                       ;--------------------------------------------------------------------------
0C7A|
0C7A| 4279 00FC E018                clr             VTIRDIS                 ;turn off vertical retrace
0C80| 7801                          moveq           #1, d4                  ;initialize FOUND to true
0C82|
0C82|                       GetBytes:
0C82| 47EE FF18                     lea             dScrach(a6), a3         ;pointer to 1/2 Scrach Array pointer
0C86| 284B                          move.l          a3, a4
0C88| D8FC 0070                     adda            #HalfSize, a4           ;pointer to end of 1/2 Scrach Array     RM000
0C8C|                       ;
0C8C|                       ;       find the first sync byte
0C8C|                       ;
0C8C| 6100 007C                     bsr             FindSync
0C90| 4A44                          tst.w           d4
0C92| 6764                          beq.s           Exit                    ;exit if no sync byte found
0C94|                       ;
0C94|                       ;       now pull out the first block from the bit stream
0C94|                       ;
0C94| 6100 009E                     bsr             GetNibbles
0C98|                       ;       here we look for the second sync byte.
0C98|                       ;
0C98| 47EE FF18                     lea             dScrach(a6), a3
0C9C| D6FC 0070                     adda            #HalfSize, a3           ;pointer to 2/2 Scrach Array pointer    RM000
0CA0| 284B                          move.l          a3,a4
0CA2| D8FC 0070                     adda            #HalfSize,a4            ;pointer to end of 2/2 Scrach Array     RM000
0CA6|                       ;
0CA6| 6100 0062                     bsr             FindSync
0CAA| 4A44                          tst.w           d4
0CAE|                       ;       beq.s           Exit                    ;again, exit if no sync byte found
0CAE|                       ;       now pull out second block from the bit stream
0CAE|                       ;
0CAE| 6100 0084                     bsr             GetNibbles
0CB2|
0CB2|                       ;----------------------------------------------------------------------
0CB2|                       ;       Check the checksum of the read data
0CB2|                       ;----------------------------------------------------------------------
0CB2|
0CB2|                       CheckSum:
0CB2| 206E FFF8                     move.l          dSavArry(a6),a0
0CB6| 4240                          clr.w           d0
0CB8|
0CB8| 1028 0018                     move.b          24(a0),d0
0CBC| 343C 0064                     move.w          #100,d2
0CC0| C0C2                          mulu            d2,d0
0CC2|
0CC2| 1228 0019                     move.b          25(a0),d1
0CC6| 343C 000A                     move.w          #10,d2
0CCA| C2C2                          mulu            d2,d1
0CCC| D041                          add.w           d1,d0
0CCE|
0CCE| 1228 001A                     move.b          26(a0),d1
0CD2| D041                          add.w           d1,d0
0CD4|
0CD4| 4241                          clr.w           d1
0CD6| 4242                          clr.w           d2
0CD8| 4243                          clr.w           d3
0CDA| 1630 1000             @2:     move.b          0(a0,d1),d3
0CDE| D443                          add.w           d3,d2
0CE0| 5241                          addq.w          #1,d1
0CE2| 0C41 0018                     cmpi.w          #24,d1
0CE6| 66F2                          bne.s           @2
0CE8|
0CE8| 1628 001B                     move.b          27(a0), d3
0CEC| D443                          add.w           d3,d2
0CEE| 0442 003C                     subi.w          #4 * $F, d2
0CF2| B440                          cmp.w           d0,d2
0CF4| 6702                          beq.s           @3
0CF6| 4244                          clr.w           d4
0CF8|                       @3:
0CF8|                       ;---------------------------------------------------------------------------
0CF8|                       ;       job well done, lets go home
0CF8|                       ;---------------------------------------------------------------------------
0CF8|
0CF8|                       Exit:
0CF8| 4E5E                          unlk            a6
0CFA| 46DF                          move            (sp)+, SR               ;restore status reg
0CFC| 4CDF 0180                     MOVEM.L         (SP)+,D7/A0             ;and regs
0D00| 4279 00FC E01A                clr             VTIRENB                 ;re-enable interrupts
0D06| E24C                          LSR             #1,D4                   ;shift to set/reset error indicator
0D08| 4E75                  @1      RTS                                     ; and exit
0D0A|
0D0A|                               .PAGE
0D0A|                       ;---------------------------------------------------------------------------
0D0A|                       ;       subroutine to find a sync byte
0D0A|                       ;---------------------------------------------------------------------------
0D0A|
0D0A|                       FindSync:
0D0A| 4280                          clr.l           d0
0D0C| 7202                          moveq           #2, d1                  ;two passes to find the sync byte
0D0E| 341B                  @1:     move.w          (a3)+, d2               ;
0D10| E34A                          lsl.w           #1, d2                  ;
0D12| E310                          roxl.b          #1, d0                  ;get SN1
0D14| B9CB                          cmpa.l          a3, a4                  ;assure the buffer's circular
0D16| 660A                          bne.s           @2                      ;
0D18| D7FC FFFF FF90                adda.l          #-HalfSize, a3          ;if it's at the end then
0D1E| 5341                          subq            #1, d1                  ; check if it's the second try
0D20| 670E                          beq.s           @3                      ; and exit if so
0D22| 0C00 00FF             @2:     cmpi.b          #$0ff, d0               ;test here if it's a sync byte
0D26| 66E6                          bne.s           @1                      ;no: loop again
0D28| E948                          lsl.w           #4, d0                  ;yes: adjust the byte
0D2A| E808                          lsr.b           #4, d0                  ;
0D2C| 30C0                          move.w          d0, (a0)+               ;save it
0D2E| 4E75                          rts                                     ;and return
0D30|
0D30| 4244                  @3:     clr.w           d4                      ;uh, oh. No sync byte.
0D32| 4E75                          rts                                     ;clear FOUND and return
0D34|                       ;--------------------------------------------------------------------------
0D34|                       ;       subroutine to pull out a 14 nibble block from the bit stream
0D34|                       ;--------------------------------------------------------------------------
0D34|
0D34|                       GetNibbles:
0D34| 7406                          moveq           #BytesPerRead-1, d2     ;
0D36| 7208                  @1:     moveq           #8, d1                  ;8 bits/byte
0D38| 4280                          clr.l           d0                      ;
0D3A| E3DB                  @2:     lsl             (a3)+                   ;get SN1 in the next scrach word
0D3C| E310                          roxl.b          #1, d0                  ;shift it into the save buffer
0D3E| B9CB                          cmpa.l          a3, a4                  ;assure a circular bufer
0D40| 6606                          bne.s           @3                      ;
0D42| D7FC FFFF FF90                adda.l          #-HalfSize, a3          ;
0D48| 5341                  @3      subq            #1, d1                  ;decrement bit/byte counter
0D4A| 66EE                          bne.s           @2                      ;loop again if still in byte
0D4C| E948                          lsl.w           #4, d0                  ;separate the nibbles
0D4E| E808                          lsr.b           #4, d0                  ;
0D50| 30C0                          move            d0, (a0)+               ;save these nibbles
0D52| 5342                          subq            #1, d2                  ;decrement byte/SN counter
0D54| 66E0                          bne.s           @1                      ;loop again if still more to go
0D56| 4E75                          rts
0D58|
0D58| 4B41 5300             Tag     .word           $4b41,$5300
0D5C|
0D5C|
0D5C|                               .PAGE
0D5C|                       ;----------------------------------------------------------------------------
0D5C|                       ;  PARITY CIRCUITRY TEST
0D5C|                       ;  The purpose of this test is to verify the operation of the parity checking
0D5C|                       ;  logic by forcing a parity error and ensuring it is caught.
0D5C|                       ;  Register usage:
0D5C|                       ;       D0 = pattern written            A0 = logical address used for test
0D5C|                       ;       D1 = read results               A1 = corresponding physical address
0D5C|                       ;       D2 = NMI indicator              A2 = save for NMI vector
0D5C|                       ;       D3 = save of memory contents    A3 = scratch
0D5C|                       ;       D4 = save of error addr latch   A4 = unused
0D5C|                       ;       D5 = unused                     A5 = address of bus status register
0D5C|                       ;       D6 = unused                     A6 = unused
0D5C|                       ;----------------------------------------------------------------------------
0D5C|
0D5C|                       PARTST
0D5C|                               .ENDC
0D5C|                               .IF  ROM16K = 1
0D5C|
0D5C| 2478 007C                     MOVE.L  NMIVCT,A2       ;SAVE STANDARD NMI VECTOR
0D60| 47FA 0092                     LEA     WWPERR,A3       ;THEN SET UP NEW PARITY ERROR (NMI) VECTOR
0D64| 21CB 007C                     MOVE.L  A3,NMIVCT
0D68| 2A7C 00FC F801                MOVEA.L #STATREG,A5     ;setup status reg ptr for byte ops
0D6E| 4A39 00FC E01C                TST.B   PAROFF          ;disable parity initially
0D74| 4282                          CLR.L   D2              ;clear regs for result use
0D76| 4284                          CLR.L   D4
0D78| 303C 01FF                     MOVE    #$01FF,D0       ;SET UP PATTERN FOR WRITE
0D7C| 307C 0300                     MOVEA   #$300,A0        ;SET UP ADDRESS FOR USE (in already verified mem)       RM000
0D80| 3610                          MOVE    (A0),D3         ;SAVE ITS CONTENTS
0D82| 2248                          MOVEA.L A0,A1           ;COMPUTE CORRESPONDING
0D84| D3F8 02A4                     ADDA.L  MINMEM,A1       ; PHYSICAL ADDRESS
0D88|
0D88| 4A39 00FC E006                TST.B   DG2ON           ;ENABLE WRITE WRONG PARITY FUNCTION
0D8E| 3080                          MOVE    D0,(A0)         ;DO WRITE TO CREATE BAD PARITY
0D90| 4A39 00FC E004                TST.B   DG2OFF          ;DISABLE WWP
0D96|
0D96| 4A39 00FC E01E                TST.B   PARON           ;ENABLE PARITY ERROR DETECTION
0D9C| 4A42                          TST     D2              ;SHOULDN'T HAVE INTERRUPT YET
0D9E| 6632                          BNE.S   PARERR          ;EXIT IF ERROR
0DA0|
0DA0| 3210                          MOVE    (A0),D1         ;DO READ - PARITY ERROR SHOULD OCCUR
0DA2| 4E71                          NOP                     ;GIVE A LITTLE EXTRA TIME
0DA4| 4A42                          TST     D2              ;NMI RECEIVED?
0DA6| 672A                          BEQ.S   PARERR          ;ERROR IF NO
0DA8|                       ;  Check that parity error and failing address correctly caught
0DA8| 0815 0001                     BTST    #PBIT,(A5)      ;PARITY ERROR BIT SET?
0DAC| 6624                          BNE.S   PARERR          ;EXIT IF NOT
0DAE| 3839 00FC F000                MOVE    MEALTCH,D4      ;GET ERROR ADDRESS
0DB4| 4A39 00FC E01C                TST.B   PAROFF          ;disable parity to clear error bit
0DBA| EB8C                          LSL.L   #5,D4           ;NORMALIZE THE ADDRESS
0DBC| B3C4                          CMPA.L  D4,A1           ;SAME ADDRESS AS WRITTEN TO?
0DBE| 6612                          BNE.S   PARERR          ;EXIT IF ERROR
0DC0| 21CA 007C                     MOVE.L  A2,NMIVCT       ;ELSE RESTORE NMI VECTOR
0DC4| 4240                          CLR     D0
0DC6| 4640                          NOT     D0
0DC8| 3080                          MOVE    D0,(A0)         ;"clear" bad parity
0DCA| 4A39 00FC E01E                TST.B   PARON           ;reenable parity
0DD0| 6016                          BRA.S   PARXIT          ;and skip to exit
0DD2|
0DD2|                       ;  Error exit
0DD2| 08C7 0003             PARERR  BSET    #PAR,D7         ;SET INDICATOR
0DD6| 4A87                          TST.L   D7              ;in loop mode?
0DD8| 6B82                          BMI.S   PARTST          ;restart if yes
0DDA| 4A39 00FC E01C                TST.B   PAROFF          ;else ensure parity disabled
0DE0| 21CA 007C                     MOVE.L  A2,NMIVCT       ;RESTORE NMI VECTOR
0DE4| 6000 05B4                     BRA     TSTCHK          ;AND ABORT FURTHER TESTING
0DE8|
0DE8|                       ;  Normal exit
0DE8|
0DE8| 4A87                  PARXIT  TST.L   D7              ;check for loop mode
0DEA| 6B00 FF70                     BMI.S   PARTST          ;restart test if yes
0DEE| 6100 27C6                     BSR     CHKCPU          ;place check over CPU (all tests OK)
0DF2| 600E                          BRA.S   MEMTST2         ;else go do memory test
0DF4|
0DF4|                       ;  NMI routine for parity error checking
0DF4|
0DF4| 7401                  WWPERR  MOVEQ   #1,D2           ;SET INDICATOR
0DF6| 4E73                          RTE                     ;AND RETURN
0DF8|
0DF8|                       ;------------------------------------------------------------------------
0DF8|                       ;  Bus error handler for VIA #1 use
0DF8|                       ;------------------------------------------------------------------------
0DF8|
0DF8| 7032                  VIA1VCT MOVEQ   #EVIA1,D0       ;SET ERROR CODE
0DFA| 08C7 000A                     BSET    #VIA1,D7        ;set indicator
0DFE| 6000 FB18                     BRA     IOVCT           ;AND GO HANDLE I/O EXCEPTION
0E02|
0E02|                               .ENDC                   ;(ROM16K)
0E02|                               .PAGE
0E02|                       ;-------------------------------------------------------------------------
0E02|                       ;  Now do full memory test with and without parity enabled.  If parameter
0E02|                       ;  memory bit set for extended memory testing, memory tests executed in
0E02|                       ;  twice.  If warm-start, execute only one pass with parity enabled.
0E02|                       ;  Uses registers:
0E02|                       ;       A0 = starting address to test   D0 = used to consolidate test results
0E02|                       ;       A1 = ending address to test     D1 = scratch
0E02|                       ;       A2 = unused                     D2 = address increment
0E02|                       ;       A3 = save address for results   D3 = test results for each 128K
0E02|                       ;       A4 = return address             D4 = max test address
0E02|                       ;       A5 = unused                     D5 = pass count
0E02|                       ;-------------------------------------------------------------------------
0E02|
0E02|                       MEMTST2
0E02|                               .IF  ROM4K = 0
0E02|
0E02|                               .IF  USERINT = 1
0E02| 327C 1E04                     MOVEA   #MEMSTRT,A1     ;hilite memory board test icon
0E06| 6100 276C                     BSR     INVICON
0E0A|                               .ENDC
0E0A|
0E0A| 6100 F8D6                     BSR     SETBUSVCT       ;restore normal bus error vector                RM000
0E0E|                       MEMLOOP
0E0E| 43FA 0104                     LEA     PRTYINT1,A1     ;setup up vector for parity intrpt              CHG015
0E12| 21C9 007C                     MOVE.L  A1,NMIVCT       ;                                               CHG015
0E16|
0E16|                               .IF  ROM16K = 1
0E16|                       ;  First check if this is a warm-start                                          CHG006
0E16|
0E16| 0807 001E                     BTST    #WRMSTRT,D7     ;warm-start?                                    CHG006
0E1A| 6704                          BEQ.S   @0              ;skip if not                                    CHG015
0E1C| 7A01                          MOVEQ   #1,D5           ;else set count for one pass                    CHG015
0E1E| 6020                          BRA.S   @3              ;skip to do it                                  CHG015
0E20|
0E20|                       ;  Next check parameter memory to see if extended testing desired
0E20|
0E20| 6100 0A14             @0      BSR     CHKPM           ;go check parameter memory
0E24| 650E                          BCS.S   @1              ;skip if not valid to do only one pass
0E26| 0839 0006 00FC C18D           BTST    #6,MEMCODE      ;else check extended memory test indicator
0E2E| 6704                          BEQ.S   @1              ;exit if not set
0E30|
0E30| 7A02                          MOVEQ   #2,D5           ;run two passes for extended mode               CHG015
0E32| 6002                          BRA.S   @2              ;go do it                                       CHG015
0E34| 7A01                  @1      MOVEQ   #1,D5           ;run one pass for normal mode                   CHG015
0E36|
0E36|                       ;  Run the memory tests
0E36|
0E36| 4A39 00FC E01C        @2      TST.B   PAROFF          ;first run with parity off                      CHG015
0E3C| 612C                          BSR.S   RUNTESTS        ;run test pass                                  CHG015
0E3E| 660E                          BNE.S   TSTDONE         ;skip if error                                  CHG015
0E40| 4A39 00FC E01E        @3      TST.B   PARON           ;then run pass with parity on                   CHG015
0E46| 6122                          BSR.S   RUNTESTS        ;run test pass                                  CHG015
0E48| 6604                          BNE.S   TSTDONE         ;exit if error                                  CHG015
0E4A| 5345                          SUBQ    #1,D5           ;decr pass count                                CHG015
0E4C| 66E8                          BNE.S   @2              ;continue testing until done                    CHG015
0E4E|
0E4E| 4A87                  TSTDONE TST.L   D7              ;in loop mode?
0E50| 6BBC                          BMI.S   MEMLOOP         ;restart if yes
0E52| 0807 0015                     BTST    #MEM,D7         ;memory error?
0E56| 6600 0542                     BNE     TSTCHK          ;abort if yes
0E5A| 6100 2762                     BSR     CHKMBRD         ;else signal memory OK
0E5E| 47FA F8A4                     LEA     NMI,A3          ;restore NMI vector                             CHG015
0E62| 21CB 007C                     MOVE.L  A3,NMIVCT       ;                                               CHG015
0E66| 6000 0198                     BRA     IOTST           ;go on to next test
0E6A|
0E6A|
0E6A|                       ;-----------------------------------------------------------------------
0E6A|                       ;  Subroutine to run the memory tests - saves results as test proceeds
0E6A|                       ;  Zero condition code bit set if no errors.
0E6A|                       ;-----------------------------------------------------------------------
0E6A|
0E6A|                       RUNTESTS
0E6A|
0E6A|                       ;  Do the basic test
0E6A|
0E6A|                       BASICTST
0E6A| 6118                          BSR.S   TSTINIT         ;init for new test
0E6C|                       CALL3
0E6C|                               BSR4    RAMTEST
0E6C| 49FA 0006            #          LEA      @1,A4
0E70| 6000 003E            #          BRA      RAMTEST
0E74|                      #@1
0E74| 6704                          BEQ.S   @1              ;skip if no errors
0E76| 08C7 0015                     BSET    #MEM,D7         ;else set error indicator
0E7A| 611C                  @1      BSR.S   SAVRSLT         ;save results
0E7C| 66EE                          BNE.S   CALL3           ;loop until done                                CHG021
0E7E| 0807 0015                     BTST    #MEM,D7         ;set condition code                             CHG015
0E82| 4E75                          RTS                     ;and exit
0E84|
0E84|                               .ELSE
0E84|                               .ENDC                   ;{ROM16K}
0E84|
0E84|                               .PAGE
0E84|                       ;----------------------------------------------------------------------
0E84|                       ;  Subroutine to do initialization for memory tests
0E84|                       ;----------------------------------------------------------------------
0E84|
0E84| 7402                          MOVEQ   #2,D2           ;test in 128K increments                        RM000
0E86| 4842                          SWAP    D2              ; (sets D2 = $20000)                            RM000
0E88| 2838 0110                     MOVE.L  SCRNBASE,D4     ;get max test address (base of screen)
0E8C| 307C 0800                     MOVEA   #LOMEM,A0       ;set initial start
0E90| 2242                          MOVE.L  D2,A1           ; and ending address
0E92| 367C 0186                     MOVEA   #MEMRSLT,A3     ;set address of result area                     RM000
0E96| 4E75                          RTS
0E98|
0E98|                       ;----------------------------------------------------------------------
0E98|                       ;  Subroutine to save results and update ptrs.
0E98|                       ;----------------------------------------------------------------------
0E98|
0E98| 3003                  SAVRSLT MOVE    D3,D0           ;get low results
0E9A| 4843                          SWAP    D3              ;get high results
0E9C| 8640                          OR      D0,D3           ;combine
0E9E| 875B                          OR      D3,(A3)+        ; and save
0EA0| B889                          CMP.L   A1,D4           ;at max test address?
0EA2| 670A                          BEQ.S   @1              ;exit if yes
0EA4| 2049                          MOVEA.L A1,A0           ;else set new addresses
0EA6| D3C2                          ADDA.L  D2,A1           ; to check next row of memory
0EA8| B889                          CMP.L   A1,D4           ;in last segment?
0EAA| 6C02                          BGE.S   @1
0EAC| 2244                          MOVE.L  D4,A1           ;set at base of video page
0EAE| 4E75                  @1      RTS
0EB0|
0EB0|                               .PAGE
0EB0|                       ;-----------------------------------------------------------------------------
0EB0|                       ; BASIC MEMORY TEST - writes pattern and its complement in memory location,
0EB0|                       ;                     then verifies by reading.  Also does second scan as
0EB0|                       ;                     addressing check.  Uses long word operations for speed.
0EB0|                       ; Inputs:
0EB0|                       ;       A0 - Starting address to test
0EB0|                       ;       A1 - Ending address
0EB0|                       ;       A4 - Return address
0EB0|                       ; Outputs:
0EB0|                       ;       CCR zero bit set if no error
0EB0|                       ;       D3 = OR mask of errors
0EB0|                       ; Uses registers:
0EB0|                       ;       A0 = current test address       D0 = current test pattern
0EB0|                       ;       A1 = ending test address        D1 = scratch
0EB0|                       ;       A2 = unused                     D2 = unused
0EB0|                       ;       A3 = unused                     D3 = OR mask of errors
0EB0|                       ;       A4 = return address             D4 = unused
0EB0|                       ;       A5 = saved start address        D5 = unused
0EB0|                       ;       A6 = used for return address    D6 = unused
0EB0|                       ;-----------------------------------------------------------------------------
0EB0|
0EB0| 2A48                  RAMTEST MOVE.L  A0,A5           ;save start address
0EB2| 203C AA55 A55A                MOVE.L  #PATRN,D0       ;get pattern
0EB8| 4680                          NOT.L   D0              ;use complement first
0EBA| 7600                          MOVEQ   #0,D3           ;clear for result use
0EBC| 007C 0010                     ORI     #$0010,SR       ;set extend bit for use with pattern rotate
0EC0|
0EC0| 2080                  RAMRW   MOVE.L  D0,(A0)         ;do write
0EC2| B090                          CMP.L   (A0),D0         ;verify
0EC4| 6706                          BEQ.S   RAMCHK2         ;skip if OK
0EC6|                               BSRS6   RDERR           ;else save error bits
0EC6| 4DFA 0004            #          LEA      @1,A6
0ECA| 6040                 #          BRA.S    RDERR
0ECC|                      #@1
0ECC|
0ECC| 4680                  RAMCHK2 NOT.L   D0              ;now use inverse
0ECE| 2080                          MOVE.L  D0,(A0)         ;write to check for stuck bits
0ED0| B098                          CMP.L   (A0)+,D0        ;verify and bump address
0ED2| 670A                          BEQ.S   RAMNXT          ;skip if OK
0ED4| 5988                          SUBQ.L  #4,A0           ;else get error address
0ED6|                               BSRS6   RDERR           ;go save error bits
0ED6| 4DFA 0004            #          LEA      @1,A6
0EDA| 6030                 #          BRA.S    RDERR
0EDC|                      #@1
0EDC| 5888                          ADDQ.L  #4,A0           ;and restore next test address
0EDE|
0EDE| E390                  RAMNXT  ROXL.L  #1,D0           ;create new pattern
0EE0| 4680                          NOT.L   D0              ;invert for test
0EE2| B3C8                          CMPA.L  A0,A1           ;done?
0EE4| 66DA                          BNE.S   RAMRW           ;loop if not
0EE6|
0EE6|                       ;  Now do address check - writes memory as all F's during scan
0EE6| 203C AA55 A55A        ADRTST  MOVE.L  #PATRN,D0       ;reinitialize
0EEC| 204D                          MOVE.L  A5,A0           ;get start address
0EEE| 7200                          MOVEQ   #0,D1
0EF0| 4681                          NOT.L   D1              ;final pattern for write
0EF2| 007C 0010                     ORI     #$0010,SR       ;set extend
0EF6|
0EF6| B090                  ADRCHK  CMP.L   (A0),D0         ;check contents
0EF8| 6706                          BEQ.S   ADRCLR          ;skip if OK
0EFA|                               BSRS6   RDERR           ;else save errors
0EFA| 4DFA 0004            #          LEA      @1,A6
0EFE| 600C                 #          BRA.S    RDERR
0F00|                      #@1
0F00| 20C1                  ADRCLR  MOVE.L  D1,(A0)+        ;'clear' and go to next location
0F02| E390                          ROXL.L  #1,D0           ;create next pattern
0F04| B3C8                          CMPA.L  A0,A1           ;done?
0F06| 66EE                          BNE.S   ADRCHK          ;loop if not
0F08|
0F08|                       ; Check results
0F08|
0F08| 4A83                          TST.L   D3              ;set condition codes
0F0A|                               RTS4
0F0A| 4ED4                 #          JMP      (A4)
0F0C|
0F0C|                       ; Failure routine - save results and continue testing
0F0C|
0F0C| 2210                  RDERR  MOVE.L  (A0),D1         ;do read again
0F0E| B181                         EOR.L   D0,D1           ;isolate bad bits
0F10| 8681                         OR.L    D1,D3           ;save result
0F12|                              RTS6                    ;and return
0F12| 4ED6                 #         JMP      (A6)
0F14|
0F14|                               .PAGE
0F14|                       ;------------------------------------------------------------------------------
0F14|                       ;  Phase 1 Parity error handler for memory tests.  Objective for handler is to
0F14|                       ;  isolate parity error to chip level.
0F14|                       ;  Assumes:
0F14|                       ;       D0 = expected data pattern
0F14|                       ;       A0 = error address or address + 4
0F14|                       ;  Uses registers:
0F14|                       ;       D1 = parity error address
0F14|                       ;       D2 = search size for byte in error
0F14|                       ;       D3 = low memory address
0F14|                       ;       A1 = search address
0F14|                       ;------------------------------------------------------------------------------
0F14|
0F14|                       PRTYINT1
0F14| 6152                          BSR.S   TSTSTAT         ;check if parity error                  CHG015
0F16| 6600 F7EC                     BNE     NMI             ;skip if not                            CHG015
0F1A| 08C7 0016                     BSET    #MPAR,D7        ;set error indicator                    CHG015
0F1E| 21C0 026C                     MOVE.L  D0,XPCTDATA     ;save data and address                  CHG015
0F22| 21C8 0268                     MOVE.L  A0,XPCTADDR     ;                                       CHG015
0F26| 2638 02A4                     MOVE.L  MINMEM,D3       ;get low memory address                 CHG015
0F2A| 6100 00C4                     BSR     GETPADDR        ;read and convert parity address        CHG015
0F2E| 0801 0005                     BTST    #5,D1           ;main mem error?                        CHG015
0F32| 6604                          BNE.S   @1              ;skip if not                            CHG015
0F34|
0F34| 743F                          MOVEQ   #MSRCHSZ-1,D2   ;setup up search size for main mem      CHG015
0F36| 600A                          BRA.S   @2              ;skip to do it                          CHG015
0F38| 343C 7FFF             @1      MOVE    #VSRCHSZ-1,D2   ;setup for video memory search          CHG015
0F3C| 0281 FFFF 8000                ANDI.L  #VMSK,D1        ;mask off undefined info                CHG015
0F42| 21C1 01A6             @2      MOVE.L  D1,PEADDR       ;save error address                     CHG015
0F46|
0F46|                       ;  Reset NMI vector and start search for exact address                  CHG015
0F46|
0F46| 43FA 002A                     LEA     PRTYINT2,A1     ;setup new vector                       CHG015
0F4A| 21C9 007C                     MOVE.L  A1,NMIVCT       ;                                       CHG015
0F4E| 9283                          SUB.L   D3,D1           ;convert to logical address             CHG015
0F50| 2241                          MOVE.L  D1,A1           ;setup for use                          CHG015
0F52| 4A39 00FC E01C                TST.B   PAROFF          ;clear parity bit                       CHG015
0F58| 4A39 00FC E01E                TST.B   PARON           ;                                       CHG015
0F5E| 4284                          CLR.L   D4              ;clear for use                          CHG015
0F60|
0F60| 1819                  @3      MOVE.B  (A1)+,D4        ;search for parity error by byte        CHG015
0F62| 51CA FFFC                     DBRA    D2,@3           ;loop until found                       CHG015
0F66|
0F66|                       ;  Error did not repeat                                                 CHG015
0F66| 605E                          BRA.S   PRIXIT          ;go save error info and exit            CHG015
0F68|
0F68|                       ;-----------------------------------------------------------------------------
0F68|                       ;  Subroutine to check for parity error
0F68|                       ;-----------------------------------------------------------------------------
0F68|
0F68| 0839 0001 00FC F801   TSTSTAT BTST    #1,STATREG      ;check for parity error                 CHG015
0F70| 4E75                          RTS                     ;return with condition code set         CHG015
0F72|
0F72|                       ;-----------------------------------------------------------------------------
0F72|                       ;  Parity error handler, phase 2.
0F72|                       ;  Assumes:
0F72|                       ;       A1 = error address + 1
0F72|                       ;       D0 = expected data (long)
0F72|                       ;       D4 = error data (byte)
0F72|                       ;  Uses registers:
0F72|                       ;       D1 = error address
0F72|                       ;       D2 = scratch
0F72|                       ;-----------------------------------------------------------------------------
0F72|
0F72|                       PRTYINT2
0F72| 61F4                          BSR.S   TSTSTAT         ;parity error?                          CHG015
0F74| 6600 F78E                     BNE     NMI             ;skip if not to handle NMI              CHG015
0F78| 6100 0076                     BSR     GETPADDR        ;get error address                      CHG015
0F7C| 21C1 0278                     MOVE.L  D1,PEADR2       ;save it                                CHG015
0F80| 93FC 0000 0001                SUBA.L  #1,A1           ;get actual address                     CHG015
0F86| 21C9 0270                     MOVE.L  A1,ACTADDR      ;save address and data                  CHG015
0F8A| 21C4 0274                     MOVE.L  D4,ACTDATA      ;                                       CHG015
0F8E| 0801 0005                     BTST    #5,D1           ;video error?                           CHG015
0F92| 6632                          BNE.S   PRIXIT          ;skip if yes                            CHG015
0F94|
0F94| 2209                          MOVE.L  A1,D1           ;get error address                      CHG015
0F96| 0281 0000 0003                ANDI.L  #ADRMSK,D1      ;setup up rotate count                  CHG015
0F9C| 2401                          MOVE.L  D1,D2           ;save it                                CHG015
0F9E| 6706                          BEQ.S   @2              ;skip if pre-rotate not needed          CHG015
0FA0|
0FA0| E188                  @1      LSL.L   #8,D0           ;shift expected data to high byte       CHG015
0FA2| 5341                          SUBQ    #1,D1           ;                                       CHG015
0FA4| 66FA                          BNE.S   @1              ;                                       CHG015
0FA6|
0FA6| E198                  @2      ROL.L   #8,D0           ;shift to low byte                      CHG015
0FA8| 0280 0000 00FF                ANDI.L  #$FF,D0         ;strip unneeded info                    CHG015
0FAE| B900                          EOR.B   D4,D0           ;isolate bad bits                       CHG015
0FB0| 671E                          BEQ.S   PCERR           ;skip if no data error                  CHG015
0FB2| 0802 0000                     BTST    #0,D2           ;check if high or low byte error        CHG015
0FB6| 6602                          BNE.S   @3              ;skip if low byte                       CHG015
0FB8| E148                          LSL     #8,D0           ;else shift to high byte                CHG015
0FBA|
0FBA| 367C 0186             @3      MOVEA   #MEMRSLT,A3     ;set ptr to save area                   CHG015
0FBE| 2809                          MOVE.L  A1,D4           ;set error address                      CHG015
0FC0| 2600                          MOVE.L  D0,D3           ;and error bits                         CHG015
0FC2| 6100 F8B0                     BSR     SCRNSAV         ;then go save data                      CHG015
0FC6|
0FC6| 4A39 00FC E01C        PRIXIT  TST.B   PAROFF          ;disable parity                         CHG015
0FCC| 6000 F796                     BRA     EXCP1           ;and go to exit                         CHG015
0FD0|
0FD0|                       ;  no data error - must be parity chip failure; decode to chip id       CHG015
0FD0|
0FD0| 2209                  PCERR   MOVE.L  A1,D1           ;get error address                      CHG015
0FD2| 0801 0000                     BTST    #0,D1           ;check if odd or even                   CHG015
0FD6| 6708                          BEQ.S   @1              ;skip if even                           CHG015
0FD8| 11FC 0014 027D                MOVE.B  #$14,PCHIP      ;bad parity chip in low word            CHG015
0FDE| 6006                          BRA.S   @2              ;                                       CHG015
0FE0| 11FC 0009 027D        @1      MOVE.B  #9,PCHIP        ;bad chip in high word                  CHG015
0FE6|
0FE6| 7411                  @2      MOVEQ   #17,D2          ;calculate row address                  CHG015
0FE8| E4A9                          LSR.L   D2,D1           ; for parity error                      CHG015
0FEA| 11C1 027C                     MOVE.B  D1,PCHPROW      ;save row info                          CHG015
0FEE| 60D6                          BRA.S   PRIXIT          ;and exit                               CHG015
0FF0|
0FF0|                       ;-----------------------------------------------------------------------------
0FF0|                       ;  Subroutine to get parity error address
0FF0|                       ;  Returns D1 = error address
0FF0|                       ;-----------------------------------------------------------------------------
0FF0|
0FF0|                       GETPADDR
0FF0| 4281                          CLR.L   D1              ;clear for use                          CHG015
0FF2| 3239 00FC F000                MOVE    MEALTCH,D1      ;read error latch                       CHG015
0FF8| 31C1 01AA                     MOVE    D1,ADRLTCH      ;save it                                CHG015
0FFC| EB89                          LSL.L   #5,D1           ;convert to physical address            CHG015
0FFE| 4E75                          RTS                     ;                                       CHG015
1000|
1000|                               .PAGE
1000|                       ;-----------------------------------------------------------------------------
1000|                       ;  Continue with I/O board testing
1000|                       ;-----------------------------------------------------------------------------
1000|
1000|                       IOTST
1000|                               .ELSE                   ;{ROM4K}
1000|                               .ENDC                   ;{ROM4K}
1000|
1000|                               .IF  USERINT = 1
1000| 327C 1E12                     MOVEA   #IOSTRT,A1      ;hilite I/O board test icon
1004| 6100 256E                     BSR     INVICON
1008|                               .ENDC
1008|
1008|                               .IF  FULLSCC = 1
1008|                       ;-------------------------------------------------------------------------------;
1008|                       ; SCC Test  (Checks RS232 port controller)
1008|                       ;
1008|                       ;  The SCC interrupt vector is written and read with all 8 bit patterns
1008|                       ;  to check SCC addressing.  An internal loopback test is then done on
1008|                       ;  channel B.                                                                           RM014
1008|                       ;
1008|                       ;  The chip is always left in an initial state as follows:
1008|                       ;       both channels are reset
1008|                       ;       master interrupt enable is reset
1008|                       ;       DTR, RTS outputs set high on channel B                                          CHG011
1008|                       ;
1008|                       ;  Runs with interrupts off, uses stack.  Uses registers:
1008|                       ;
1008|                       ;  A0 = SCC address                     D0 = error indicator
1008|                       ;  A2 = scratch                         D1 = scratch
1008|                       ;                                       D2 = scratch
1008|                       ;                                       D3 = scratch
1008|                       ;
1008|                       ;  Errors saved in D0 and stored in low memory as follows:
1008|                       ;
1008|                       ;        0000 0001 -> SCC vector read/write error (accessed via channel A)              RM014
1008|                       ;        0000 0010 -> channel B transmit buffer empty timeout                           RM014
1008|                       ;        0000 0100 -> channel B receive buffer full timeout                             RM014
1008|                       ;        0000 1000 -> channel B data compare error                                      RM014
1008|                       ;
1008|                       ;-------------------------------------------------------------------------------;
1008|
1008| 47FA 00E4             SCCTEST LEA     SCCVCT,A3       ;set up bus error vector
100C| 21CB 0008                     MOVE.L  A3,BUSVCTR
1010| 6100 00BE                     BSR     RSTSCC          ;reset and set up A0 for SCC
1014| 5488                          ADDQ.L  #ACTL,A0        ;adjust SCC address for channel A
1016| 7200                          MOVEQ   #0,D1           ;SCC interrupt vector starts out 0
1018| 7000                          MOVEQ   #0,D0           ;no errors
101A|
101A|                       VECTLOOP
101A| 10BC 0002                     MOVE.B  #2,(A0)         ;test scc write register 2 (interrupt vector)
101E|                                                       ; via channel A                                         RM014
101E| 3E97                          MOVE    (SP),(SP)       ;delay
1020| 1410                          MOVE.B  (A0),D2         ;read unmodified vector
1022| B401                          CMP.B   D1,D2           ;ok?
1024| 6704                          BEQ.S   @1              ;branch if so
1026| 7001                          MOVEQ   #1,D0           ;otherwise set error code
1028| 6064                          BRA.S   SCCEXIT         ;and exit
102A| 3E97                  @1      MOVE    (SP),(SP)
102C| 10BC 0002                     MOVE.B  #2,(A0)         ;write next vector value
1030| 5281                          ADDQ.L  #1,D1           ;increment and delay
1032| 1081                          MOVE.B  D1,(A0)         ;write it
1034| 66E4                          BNE.S   VECTLOOP        ;go through 256 values
1036| 6010                          BRA.S   SETSCC          ;now go do loopback init
1038|
1038|                       ;-----------------------------------------------------------------------
1038|                       ;  Now init channel B for max baud rate and internal loopback.
1038|                       ;  External transmit is inhibited by setting DTR low.
1038|                       ;-----------------------------------------------------------------------
1038|
1038|                       ; Initialization data for SCC: max baud RS-232 async communication
1038|
1038|                       b96data:
1038| 09 00                         .byte   9,$00           ;disable all interupts                                  RM014
103A| 04 4D                         .byte   4,$4D           ;x16 clk, 2 stop bits, odd parity
103C| 0B 50                         .byte  11,$50           ;baud rate gen clk to receiver, transmitter
103E| 0C 00                         .byte  12,$00           ;set baud rate to max
1040| 0D 00                         .byte  13,$00
1042| 0E 13                         .byte  14,$13           ;enable baud rate gen, BR=PCLK, loopback
1044| 03 C1                         .byte   3,$C1           ;8 bits/char recv, enable receiver
1046| 05 EA                         .byte   5,$EA           ;DTR low, 8 bits/char xmit, enable xmit, CRC            RM014
1048| 0000 0010             b96lth  .equ    *-b96data
1048|
1048| 45FA FFEE             SETSCC  LEA     B96DATA,A2      ;setup channel B                                        RM014
104C| 323C 0010                     MOVE.W  #B96LTH,D1
1050| 5588                          SUBQ.L  #ACTL,A0        ;set address for channel B
1052| 616A                          BSR.S   WRITESCC        ;                                                       RM000
1054|                       ;  do the loopback test
1054|                                                       ;                                                       RM014
1054| 7200                  LPTEST  MOVEQ   #0,D1           ;go thru 256 bytes
1056| 76FF                          MOVEQ   #-1,D3          ;set up timeout count
1058|                       SCCLOOP
1058| 0810 0002                     BTST    #TXBE,(A0)      ;wait for transmit buffer empty
105C| 6608                          BNE.S   SCCOUT
105E| 51CB FFF8                     DBRA    D3,SCCLOOP
1062| 5440                          ADDQ    #2,D0
1064| 6024                          BRA.S   SCCLXIT         ;report timeout error
1066| 3E97                  SCCOUT  MOVE    (SP),(SP)
1068| 1141 0004                     MOVE.B  D1,SCCDATA(A0)
106C|
106C|                       SCCLOOP2
106C| 0810 0000                     BTST    #RXBF,(A0)      ;wait for data byte to come in
1070| 6608                          BNE.S   SCCIN
1072| 51CB FFF8                     DBRA    D3,SCCLOOP2
1076| 5840                          ADDQ    #4,D0
1078| 6010                          BRA.S   SCCLXIT
107A| 3E97                  SCCIN   MOVE    (SP),(SP)
107C| 1428 0004                     MOVE.B  SCCDATA(A0),D2
1080| B401                          CMP.B   D1,D2
1082| 6608                          BNE.S   SCCLERR
1084| 76FF                          MOVEQ   #-1,D3          ;update timeout count
1086| 5201                          ADDQ.B  #1,D1           ;increment data
1088| 66CE                          BNE.S   SCCLOOP         ;just do it 256 times
108A|
108A| 6002                  SCCLXIT BRA.S   SCCEXIT
108C|
108C| 5040                  SCCLERR ADDQ    #8,D0
108E|
108E|                       ;  exit, saving errors
108E|
108E| 11C0 02AC             SCCEXIT MOVE.B  D0,SCCRSLT      ;save results
1092| 6720                          BEQ.S   @3              ;continue if OK
1094| 0800 0000                     BTST    #0,D0           ;check for chan A error                                 RM014
1098| 6704                          BEQ.S   @1
109A| 08C7 000F                     BSET    #RS232A,D7
109E| E248                  @1      LSR     #1,D0           ;check for chan B error                                 RM014
10A0| 4A00                          TST.B   D0
10A2| 6704                          BEQ.S   @2
10A4| 08C7 0010                     BSET    #RS232B,D7
10A8| 6126                  @2      BSR.S   RSTSCC          ;leave SCC at initial condition
10AA| 4A87                          TST.L   D7              ;looping required?
10AC| 6B00 FF5A                     BMI.S   SCCTEST         ;restart test if yes
10B0| 6000 02E8                     BRA     TSTCHK          ;else go report error
10B4|
10B4| 611A                  @3      BSR.S   RSTSCC          ;leave SCC at initial condition
10B6| 4A87                          TST.L   D7              ;in loop mode?
10B8| 6B00 FF4E                     BMI.S   SCCTEST         ;restart test if yes
10BC| 604E                          BRA.S   DSKTST          ;else continue to next test                             RM014
10BE|
10BE|                               .PAGE
10BE|                       ;------------------------------------------------------------------------
10BE|                       ; WRITESCC: used to initialize a series of SCC registers.
10BE|                       ;
10BE|                       ;       A0 = SCC address for channel to be initialized
10BE|                       ;       A2 = pointer to an initialization data block as above
10BE|                       ;       A4 = return address
10BE|                       ;       D1 = initialization data block size in bytes
10BE|                       ;
10BE|                       ;       A2, D1, D2 are modified.
10BE|                       ;
10BE|                       ;------------------------------------------------------------------------
10BE|
10BE|                       WRITESCC
10BE| 1410                          MOVE.B  (A0),D2         ;read to make sure SCC is sync'ed up
10C0| 6002                          BRA.S   @2              ;delay for timing, too
10C2| 109A                  @1      MOVE.B  (A2)+,(A0)
10C4| 51C9 FFFC             @2      DBRA    D1,@1
10C8| 4E75                          RTS
10CA|
10CA|                       ;------------------------------------------------------------------------
10CA|                       ; Subroutine to initialize SCC.  Does reset and zeroes interrupt vector.
10CA|                       ;------------------------------------------------------------------------
10CA|
10CA|                       INITBDATA
10CA| 02 00                         .BYTE   2,$00           ;zero interrupt vector
10CC| 09 C0                         .BYTE   9,$C0           ;reset both channels
10CE| 0000 0004             INITBLTH .EQU    4              ;                                       CHG011
10CE|
10CE| 05 82                 INITB2  .BYTE   5,$82           ;set DTR, RTS high for Applebus         CHG011
10D0| 0000 0002             INITB2L .EQU    2               ;                                       CHG011
10D0|
10D0|                       RSTSCC
10D0| 207C 00FC D241                MOVE.L  #SCCBCTL,A0     ;point to SCC base address (chan B)
10D6| 45FA FFF2                     LEA     INITBDATA,A2    ;point to channel B init data
10DA| 7204                          MOVEQ   #INITBLTH,D1    ; and set up the length                 CHG011
10DC| 61E0                          BSR.S   WRITESCC        ;then init channel B
10DE| 700C                          MOVEQ   #12,D0          ;delay for SCC reset
10E0| 6100 FA00                     BSR     DELAY
10E4|
10E4| 45FA FFE8                     LEA     INITB2,A2       ;setup DTR, RTS outputs                 CHG011
10E8| 7202                          MOVEQ   #INITB2L,D1     ;                                       CHG011
10EA| 61D2                          BSR.S   WRITESCC        ;                                       CHG011
10EC| 4E75                          RTS                     ;and return
10EE|
10EE|                       ;-----------------------------------------------------------------------------
10EE|                       ;  Bus error routine for SCC testing
10EE|                       ;-----------------------------------------------------------------------------
10EE|
10EE| B1FC 00FC D241        SCCVCT  CMPA.L  #SCCBCTL,A0     ;accessing channel B?
10F4| 6604                          BNE.S   @1              ;skip if no
10F6| 7038                          MOVEQ   #ERS232B,D0     ;set error code for chan B
10F8| 6002                          BRA.S   @2
10FA| 7037                  @1      MOVEQ   #ERS232A,D0     ;set error code for chan A
10FC| 4A87                  @2      TST.L   D7              ;check if in loop mode
10FE| 6A08                          BPL.S   @3              ;skip if not
1100| 3E7C 0480                     MOVEA   #STKBASE,SP     ;else restore stack ptr                 RM000
1104| 6000 FF02                     BRA     SCCTEST         ;and restart test
1108| 6000 F80E             @3      BRA     IOVCT           ;and go handle I/O card bus error
110C|
110C|
110C|                               .ENDC
110C|                               .PAGE
110C|                       ;----------------------------------------------------------------------------
110C|                       ;  Test of disk interface - ensure R/W capability to shared RAM, then
110C|                       ;  try disable interrupts command.  This test will also verify
110C|                       ;  the results of the disk controller's own self-test (ROM and RAM test).
110C|                       ;----------------------------------------------------------------------------
110C|
110C|                       DSKTST
110C|                               .IF  DIAGS = 1
110C|
110C| 47FA 0078                     LEA     DSKVCT,A3       ;set up vector in case of bus timeout
1110| 21CB 0008                     MOVE.L  A3,BUSVCTR
1114| 207C 00FC C001                MOVE.L  #DISKMEM,A0     ;set ptr for shared memory
111A|
111A|                       ;  Display ROM id                                                       CHG001
111A|
111A| 7A03                          MOVEQ   #ROMIDROW,D5    ;set cursor ptrs                        CHG001
111C| 3C3C 0051                     MOVE    #ROMIDCOL+1,D6  ;                                       CHG001
1120| 702F                          MOVEQ   #'/',D0         ;preceed with / char                    CHG001
1122| 6100 2616                     BSR     DSPVAL          ;display it                             CHG001
1126| 1028 0030                     MOVE.B  ROMV(A0),D0     ;read id                                CHG001
112A| 11C0 02A1                     MOVE.B  D0,IOROM        ;save in low memory                     CHG010
112E| 7202                          MOVEQ   #2,D1           ;                                       CHG001
1130| 6100 0546                     BSR     OUTCH           ;                                       CHG001
1134|
1134|                       ;  Read system type                                                     CHG009
1134|
1134| 6162                          BSR.S   SETTYPE         ;determine system type                  CHG029
1136|
1136|                       ;  Check disk alive indicator
1136|
1136| 4282                          CLR.L   D2              ;clear for use                          CHG022
1138| 227C 00FC D901                MOVE.L  #VIA2BASE,A1    ;set ptr to parallel port 6522
113E| 0229 00BF 0010                ANDI.B  #$BF,DDRB2(A1)  ;ensure bit 6 is input
1144| 203C 001C 8000                MOVE.L  #DSKTMOUT,D0    ;set up timeout count for 15 secs
114A| 0811 0006             @2      BTST    #DSKDIAG,IRB2(A1) ;check indicator
114E| 6606                          BNE.S   @3              ;skip if set
1150| 5380                          SUBQ.L  #1,D0           ;else loop until timeout (about 8 us per loop)
1152| 66F6                          BNE.S   @2
1154| 7439                          MOVEQ   #EDISK,D2       ;error if not set                       CHG022
1156|
1156|                       ;  Try read operation and check results of self-test
1156|
1156|                       @3
1156|                               .IF  DIAGS = 1
1156| 11E8 0016 02AE                MOVE.B  STST(A0),DSKRSLT ;get results of disk self-test         CHG022
115C| 6616                          BNE.S   INTERR           ;exit if error                         CHG022
115E|
115E| 4A02                  @4      TST.B   D2              ;previous error?                        CHG022
1160| 6612                          BNE.S   INTERR          ;exit if yes                            CHG022
1162|
1162|                       ;  Then try simple write operation to shared RAM
1162|
1162| 7055                          MOVEQ   #$55,D0         ;set up pattern                         RM000
1164| 1140 0002                     MOVE.B  D0,CMD(A0)      ;try write
1168| B028 0002                     CMP.B   CMD(A0),D0      ;verify
116C| 6606                          BNE.S   INTERR          ;exit if error
116E|
116E|                       ;  Finally try a command to disable interrupts
116E|
116E| 6100 0BD6                     BSR     DSABLDSK        ;go issue disable cmd
1172| 640C                          BCC.S   DSKXIT          ;skip if OK
1174|                               .ELSE
1174|                               .ENDC
1174|
1174| 08C7 0011             INTERR  BSET    #DISK,D7        ;else set disk error
1178| 4A87                          TST.L   D7              ;restart if in loop mode
117A| 6B90                          BMI.S   DSKTST
117C| 6000 021C                     BRA     TSTCHK          ;and abort further testing
1180|
1180| 4A87                  DSKXIT  TST.L   D7              ;restart if in loop mode
1182| 6B88                          BMI.S   DSKTST
1184|                               .ENDC
1184|
1184| 603A                          BRA.S   COPSCHK         ;else go to next test
1186|                       ;-----------------------------------------------------------------------------
1186|                       ;  Bus error routine for disk testing
1186|                       ;-----------------------------------------------------------------------------
1186| 7039                  DSKVCT  MOVEQ   #EDISK,D0       ;SET ERROR CODE
1188|
1188|                               .IF  ROM4K = 0
1188| 4A87                          TST.L   D7              ;check if in loop mode
118A| 6A08                          BPL.S   @3              ;skip if not
118C|                               .ENDC
118C|
118C| 3E7C 0480                     MOVEA   #STKBASE,SP     ;else restore stack ptr                 RM000
1190| 6000 FF7A                     BRA     DSKTST          ;and restart test
1194| 6000 F782             @3      BRA     IOVCT           ;GO HANDLE I/O CARD BUS ERROR
1198|
1198|                       ;-------------------------------------------------------------------------
1198|                       ;  Subroutine for determining system type
1198|                       ;  Returns type value in D0 and sets SYSTYPE location in memory
1198|                       ;    D0 = 0 - Lisa 1
1198|                       ;         1 - Lisa 2/external disk with slow timers
1198|                       ;         2 - Lisa 2/external disk with fast timers
1198|                       ;         3 - Lisa 2/internal disk (Pepsi) with fast timers
1198|                       ;-------------------------------------------------------------------------
1198|
1198| 4280                  SETTYPE CLR.L   D0              ;clear for type usage                   CHG029
119A| 1239 00FC C031                MOVE.B  DISKROM,D1      ;read disk id                           CHG029
11A0| 4A01                          TST.B   D1              ;check for Lisa 1                       CHG029
11A2| 6A16                          BPL.S   @9              ;skip if yes                            CHG029
11A4| 0801 0005                     BTST    #SLOTMR,D1      ;Lisa 2 with slow timers?               CHG029
11A8| 6704                          BEQ.S   @1              ;skip if not                            CHG029
11AA| 7001                          MOVEQ   #1,D0           ;else set type                          CHG029
11AC| 600C                          BRA.S   @9              ;                                       CHG029
11AE| 0801 0006             @1      BTST    #FASTMR,D1      ;Lisa 2 with fast timers?               CHG029
11B2| 6704                          BEQ.S   @2              ;skip if not                            CHG029
11B4| 7002                          MOVEQ   #2,D0           ;else set type                          CHG029
11B6| 6002                          BRA.S   @9              ;                                       CHG029
11B8| 7003                  @2      MOVEQ   #3,D0           ;else must be Pepsi with fast timers    CHG029
11BA| 11C0 02AF             @9      MOVE.B  D0,SYSTYPE      ;save system type                       CHG029
11BE| 4E75                          RTS                     ;                                       CHG029
11C0|
11C0|                                .PAGE
11C0|                       ;-------------------------------------------------------------------------
11C0|                       ;  Scan the keyboard for user commands. Click speaker first to alert user.
11C0|                       ;-------------------------------------------------------------------------
11C0|
11C0| 47FA F754             COPSCHK LEA     COPSVCT,A3      ;set up bus error vector
11C4| 21CB 0008                     MOVE.L  A3,BUSVCTR
11C8| 6100 F924                     BSR     CLICK           ;notify user that keyboard about to be scanned
11CC| 6100 F8FE                     BSR     DELAY_1         ;delay for 1/10 sec
11D0| 207C 00FC DD81                MOVEA.L #VIA1BASE,A0    ;set up VIA address
11D6| 117C 00C9 0018                MOVE.B  #$C9,PCR1(A0)   ;set intrpt control for later use
11DC|                                                       ; also causes second "click"
11DC|
11DC| 6104                          BSR.S   SCANCPS         ;go check for keyboard input
11DE| 6000 00AC                     BRA     CLKTST          ;and continue on
11E2|
11E2|                       ;--------------------------------------------------------------------------
11E2|                       ;  Subroutine to do scan of keyboard COPS
11E2|                       ;--------------------------------------------------------------------------
11E2|
11E2|                       SCANCPS
11E2| 2278 0260                     MOVE.L  KBDQPTR,A1      ;set up queue ptrs
11E6| 347C 02C0                     MOVEA   #QEND,A2
11EA|
11EA|                       ;  Scan for keyboard data
11EA|
11EA| 6100 F892             KEYSCAN BSR     GETDATA         ;go check for keyboard input
11EE| 6568                          BCS.S   @9              ;exit if no data or queue full
11F0| 0C00 00FF                     CMPI.B  #CMDKEY,D0      ;is it the command key?
11F4| 6624                          BNE.S   @1              ;skip if no
11F6| 6100 F886                     BSR     GETDATA         ;yes - get next char to see if boot cmd
11FA| 655C                          BCS.S   @9              ;exit if queue full or no more data
11FC|
11FC| 0C00 00FE                     CMPI.B  #SHFTKEY,D0     ;check for shift key
1200| 6636                          BNE.S   @2              ;skip if no - go save as boot code
1202| 6100 F87A                     BSR     GETDATA         ;else keep checking for command sequence
1206| 6550                          BCS.S   @9              ;skip if Q full or no data
1208| 0C00 00C4                     CMPI.B  #PKEY,D0        ;'P' key for power-cycling
120C| 660C                          BNE.S   @1              ;skip if not
120E| 11FC 000F 01B3                MOVE.B  #PC,BOOTDVCE    ;set for power-cycle mode
1214| 08C7 001C                     BSET    #ALTBOOT,D7     ;set alternate boot
1218| 60D0                          BRA.S   KEYSCAN         ;and continue scan
121A|
121A|                       @1
121A|                               .IF  USERINT = 1
121A|
121A|                       ;  do test for downstroke or mouse button (used for burnin cycling)
121A|
121A| 4A00                          TST.B   D0              ;check keycode
121C| 6A1E                          BPL.S   @4              ;skip if not downstroke
121E| 0C00 00FD                     CMPI.B  #ALPHKEY,D0     ;ignore alpha lock key
1222| 67C6                          BEQ.S   KEYSCAN
1224|                               .ENDC
1224|
1224|                               .IF  BURNIN = 1
1224| 0C00 0086                     CMP.B   #MOUSDWN,D0      ;mouse button?
1228| 6608                          BNE.S   @3               ;skip if not
122A| 08F8 0002 02A2                BSET    #MSBUTN,STATFLGS ;else set flag for later use
1230| 60B8                          BRA.S   KEYSCAN          ;and continue scan
1232|                               .ENDC
1232|
1232|                       @3
1232|                               .IF  USERINT = 1
1232| 08C7 001D                     BSET    #BTMENU,D7      ;set indicator for boot menu
1236|                               .ENDC
1236|
1236| 60B2                          BRA.S   KEYSCAN         ;and continue scan
1238|
1238|                       ;  Save code as possible boot id and set indicator
1238|
1238| 6124                  @2      BSR.S   XLATE           ;translate to boot id code and save
123A| 60AE                          BRA.S   KEYSCAN         ;and continue keyboard scan
123C|
123C|                       ;  Check if release of mouse or COMMAND key (in case continuing after error)
123C|
123C| 0C00 0006             @4      CMP.B   #MOUSUP,D0      ;mouse release?
1240| 6608                          BNE.S   @5
1242| 08B8 0004 02A2                BCLR    #MOUSE,STATFLGS ;clear marker if yes
1248| 60A0                          BRA.S   KEYSCAN         ;and continue scan
124A|
124A| 0C00 007F             @5      CMP.B   #CMDUP,D0        ;Left CMD key release?
124E| 6606                          BNE.S   @6
1250| 08B8 0003 02A2                BCLR    #CMDFLG,STATFLGS ;clear marker if yes
1256|
1256| 6092                  @6      BRA.S   KEYSCAN         ;continue scan
1258|
1258| 21C9 0260             @9      MOVE.L  A1,KBDQPTR      ;save buffer ptr
125C| 4E75                          RTS                     ;and return to caller
125E|
125E|                       ;---------------------------------------------------------------------
125E|                       ;  Subroutine to translate keycodes to boot device codes.  Returns
125E|                       ;  with boot code in D2 if match found, else D2 = $F for no match.
125E|                       ;  Also saves boot id in memory, and sets alternate boot indicator.
125E|                       ;  Destroys A3 and D2.
125E|                       ;---------------------------------------------------------------------
125E|
125E| 47FA 001A             XLATE   LEA     KEYTBL,A3       ;get ptr to keycode table
1262| 4282                          CLR.L   D2              ;clear for counter
1264| B01B                  @1      CMP.B   (A3)+,D0        ;do search until match
1266| 6708                          BEQ.S   @2              ;skip if match
1268| 5242                          ADDQ    #1,D2           ;else bump cntr
126A| 4A13                          TST.B   (A3)            ;at end?
126C| 66F6                          BNE.S   @1              ;if not continue scan
126E| 747F                          MOVEQ   #$7F,D2         ;else set for invalid code
1270|                       @2
1270| 11C2 01B3                     MOVE.B  D2,BOOTDVCE     ;save as boot device code
1274| 08C7 001C                     BSET    #ALTBOOT,D7     ;set indicator
1278| 4E75                          RTS                     ;and exit
127A|
127A| F4 F1 F2              KEYTBL  .BYTE   KEY1,KEY2,KEY3            ;1,2,3
127D| F3 E4 01                      .BYTE   KEY4,KEY5,01              ;4,5,reserved (01 is invalid keycode)
1280| E1 E2 01                      .BYTE   KEY6,KEY7,01              ;6,7,reserved
1283| E3 D0 01                      .BYTE   KEY8,KEY9,01              ;8,9,reserved
1286| 01 01 01                      .BYTE   01,01,01                  ;reserved
1289| 01                            .BYTE   01                        ;reserved for power-cycle mode
128A| AF                            .BYTE   ENTRKEY                   ;Enter on numeric key pad
128B|                                                                 ;  (for Monitor access)
128B| 00                    TBLEND  .BYTE   0                         ;ensure on word boundary
128C|
128C|                               .PAGE
128C|                       ;------------------------------------------------------------------------------
128C|                       ;  Try initial clock read and save data for later use
128C|                       ;------------------------------------------------------------------------------
128C|
128C|                       CLKTST
128C|                               .IF     NEWLISA = 1
128C|                               .IF     DIAGS = 1
128C| 6112                          BSR.S   READCLK         ;go read clock
128E| 4A87                          TST.L   D7              ;restart if in loop mode
1290| 6BFA                          BMI.S   CLKTST
1292| 0807 000E                     BTST    #CLK,D7         ;any errors?
1296| 6600 0102                     BNE     TSTCHK          ;abort if yes
129A| 6100 232A                     BSR     CHKIOBRD        ;else mark I/O board OK
129E| 604E                          BRA.S   CONFIG          ;and exit to next test
12A0|
12A0|                       ;  Subroutine to read clock - destroys regs A0-A2, D0-D1
12A0|
12A0|                       READCLK DISABLE                 ;disable all interrupts
12A0| 40E7                 #          MOVE     SR,-(SP)
12A2| 007C 0700            #          ORI      #$0700,SR
12A6| 7002                          MOVEQ   #$02,D0         ;set up read clock cmd
12A8| 6100 F6AC                     BSR     COPSCMD         ;and send to COPS
12AC| 6534                          BCS.S   CLKERR          ;exit if error
12AE| 347C 01C0                     MOVEA   #DATARGS,A2     ;set ptr to end of save area                    RM000
12B2| 327C 01B9             RDCLK0  MOVEA   #CLKDATA-1,A1   ;set ptr to start of save area                  RM000
12B6| 6100 F7C6                     BSR.S   GETDATA         ;go get clock reset code
12BA| 6526                          BCS.S   CLKERR          ;exit if timeout error
12BC| 0C00 0080                     CMP.B   #$80,D0         ;is it the reset code?
12C0| 66F0                          BNE.S   RDCLK0          ;skip if no to continue wait
12C2| 6100 F7BA                     BSR.S   GETDATA         ;go check if clock data
12C6| 651A                          BCS.S   CLKERR
12C8| 0200 00F0                     ANDI.B  #$F0,D0         ;mask to check if clock flag
12CC| 0C00 00E0                     CMP.B   #$E0,D0         ;clock data?
12D0| 66E0                          BNE.S   RDCLK0          ;continue wait if no
12D2|
12D2| 7205                          MOVEQ   #5,D1           ;set expected byte count
12D4| 6100 F7A8             RDCLK1  BSR     GETDATA         ;go read clock data
12D8| 6508                          BCS.S   CLKERR          ;exit if error
12DA| 5341                          SUBQ    #1,D1           ;else loop until all data received
12DC| 66F6                          BNE.S   RDCLK1
12DE|                               ENABLE                  ;restore interrupt mask
12DE| 46DF                 #          MOVE     (SP)+,SR
12E0| 4E75                          RTS
12E2|
12E2|                       ;  Error exit - set indicator and return
12E2|
12E2| 08C7 000E             CLKERR  BSET    #CLK,D7
12E6|                               ENABLE                  ;restore interrupt mask
12E6| 46DF                 #          MOVE     (SP)+,SR
12E8| 003C 0001                     ORI.B   #$01,CCR        ;leave carry bit set
12EC| 4E75                          RTS
12EE|
12EE|                               .ENDC
12EE|                               .ENDC
12EE|                               .PAGE
12EE|                       ;-------------------------------------------------------------------------
12EE|                       ;  Scan I/O slots to determine what cards, if any, are installed and save
12EE|                       ;  id's of installed cards.
12EE|                       ;-------------------------------------------------------------------------
12EE|
12EE|                       CONFIG
12EE|                               .IF  USERINT = 1
12EE| 327C 1E20                     MOVEA   #XCRDSTRT,A1    ;hilite I/O slot test icon
12F2| 6100 2280                     BSR     INVICON
12F6|                               .ENDC
12F6|
12F6| 7801                  CONFIG2 MOVEQ   #1,D4           ;set flag for status check
12F8| 610C                          BSR.S   RDSLOTS         ; and go scan the slots
12FA|
12FA|                               .IF  DIAGS = 1
12FA| 4A87                          TST.L   D7              ;restart if in loop mode
12FC| 6BF8                          BMI.S   CONFIG2
12FE|                               .ENDC
12FE|
12FE| 6100 22CE                     BSR     CHKXCRD         ;mark I/O slots OK
1302| 6000 0096                     BRA     TSTCHK          ;exit to check overall results
1306|
1306|                       ;-------------------------------------------------------------------------
1306|                       ;  Subroutine to scan I/O expansion slots
1306|                       ;  Inputs:
1306|                       ;       D4 = non-zero if status check to be done, else 0 for no check
1306|                       ;  Outputs:
1306|                       ;       Saves card id's in locations $298-$29C
1306|                       ;       Error bits set in D7 if slot card errors encountered
1306|                       ;       Error code saved in location BOOTDATA+1
1306|                       ;  Side Effects:
1306|                       ;       A5,A6 trashed
1306|                       ;-------------------------------------------------------------------------
1306|
1306| 48E7 4070             RDSLOTS MOVEM.L D1/A1-A3,-(SP)  ;save regs
130A| 2C4F                          MOVE.L  SP,A6           ;save stack ptr
130C| 4281                          CLR.L   D1              ;for result use
130E| 327C 0298                     MOVEA   #IO1ID,A1       ;get ptr to id save area                RM000
1312|
1312| 247C 00FC 0001                MOVE.L  #SLOT1L,A2      ;get slot 1 address
1318|
1318| 2A78 0008                     MOVE.L  BUSVCTR,A5      ;save current bus vector value
131C| 47FA 0014                     LEA     NOCRD1,A3       ;init bus error vector
1320| 21CB 0008                     MOVE.L  A3,BUSVCTR      ; in case no card installed
1324| 030A 0000                     MOVEP   (A2),D1         ;read id for slot 1
1328| 6156                          BSR.S   CHKID           ;go check id
132A| 6408                          BCC.S   SLOT2           ;skip if OK
132C| 08C7 0019                     BSET    #IO1ERR,D7      ;else set error indicator
1330| 6002                          BRA.S   SLOT2           ;and continue
1332|
1332| 4259                  NOCRD1  CLR     (A1)+           ;set id for no card
1334|
1334| 247C 00FC 4001        SLOT2   MOVE.L  #SLOT2L,A2      ;do same for slot 2
133A| 47FA 0014                     LEA     NOCRD2,A3
133E| 21CB 0008                     MOVE.L  A3,BUSVCTR
1342| 030A 0000                     MOVEP   (A2),D1         ;read and check id
1346| 6138                          BSR.S   CHKID
1348| 6408                          BCC.S   SLOT3           ;skip if OK
134A| 08C7 001A                     BSET    #IO2ERR,D7      ;else set error indicator
134E| 6002                          BRA.S   SLOT3           ;and continue
1350|
1350| 4259                  NOCRD2  CLR     (A1)+           ;set id for no card
1352|
1352| 247C 00FC 8001        SLOT3   MOVE.L  #SLOT3L,A2      ;and finally for slot 3
1358| 47FA 0014                     LEA     NOCRD3,A3
135C| 21CB 0008                     MOVE.L  A3,BUSVCTR
1360| 030A 0000                     MOVEP   (A2),D1         ;read and check id
1364| 611A                          BSR.S   CHKID
1366| 6408                          BCC.S   CFGEXIT         ;skip if OK
1368| 08C7 001B                     BSET    #IO3ERR,D7      ;else set error indicator
136C| 6002                          BRA.S   CFGEXIT         ;go to exit
136E|
136E| 4259                  NOCRD3  CLR     (A1)+           ;set id for no card
1370|
1370|                       ;  Restore default bus error vector and SP and continue
1370|
1370| 007C 0700             CFGEXIT ORI     #$0700,SR       ;ensure interrupts off
1374| 21CD 0008                     MOVE.L  A5,BUSVCTR      ;restore from previous saves
1378| 2E4E                          MOVE.L  A6,SP
137A| 4CDF 0E02                     MOVEM.L (SP)+,D1/A1-A3  ;and restore regs
137E| 4E75                          RTS                     ;then exit
1380|
1380|                       ;-------------------------------------------------------------------------
1380|                       ;  Subroutine to do I/O slot card id check.
1380|                       ;  Requires D1 = card id
1380|                       ;-------------------------------------------------------------------------
1380|
1380|                       CHKID
1380| 0C41 FFFF                     CMP     #$FFFF,D1       ;check for prototype card
1384| 6710                          BEQ.S   @9              ;skip if not - treat as no card
1386| 32C1                          MOVE    D1,(A1)+        ;else save id
1388| 6B06                          BMI.S   @7              ;if bootable go do check
138A| 0801 000E                     BTST    #STBIT,D1       ; or do if status routine exists
138E| 6704                          BEQ.S   @8              ;skip if not
1390| 6100 0E3A             @7      BSR     RDIOSLT         ;else go check for good board
1394| 4E75                  @8      RTS
1396|
1396| 4259                  @9      CLR     (A1)+           ;set id for no card
1398| 4E75                          RTS
139A|
139A|                               .PAGE
139A|                       ;-------------------------------------------------------------------------
139A|                       ; Check test results by checking error indicators in reg D7.
139A|                       ; Output greeting message if system contains memory and all is OK.
139A|                       ; Else output appropriate error messages.
139A|                       ;-------------------------------------------------------------------------
139A|
139A| 6100 EC9E             TSTCHK  BSR     SAVEREGS        ;save regs first
139E|
139E| 47FA 000A                     LEA     TST2,A3         ;setup bus error vector for type check  CHG032
13A2| 21CB 0008                     MOVE.L  A3,BUSVCTR      ;                                       CHG032
13A6| 6100 FDF0                     BSR     SETTYPE         ;go set system type                     CHG032
13AA|
13AA| 6100 F336             TST2    BSR     SETBUSVCT       ;restore default bus error vector       RM000
13AE| 3E7C 0480                     MOVEA   #STKBASE,SP     ; and default stack
13B2| 6100 F4D2                     BSR     SETVLTCH        ;and set video latch                    CHG020
13B6|
13B6|                               .IF  USERINT = 0
13B6|                               .ELSE
13B6| 6100 1D22                     BSR     CLRDESK         ;clear desktop
13BA|                               .ENDC
13BA|
13BA| 2007                          MOVE.L  D7,D0           ;GET ERROR INDICATORS
13BC| 0280 0E7F FFFF                ANDI.L  #ERRMSK,D0      ;MASK OFF NON-FATAL ERRORS
13C2| 4A80                          TST.L   D0              ;OK?
13C4| 6700 0220                     BEQ     OTHER           ;SKIP IF YES
13C8|
13C8|                               .IF  ROM4K = 0
13C8|                       ;---------------------------------------------------------------------------
13C8|                       ;  Errors detected - scan D7 for CPU error indicators
13C8|                       ;---------------------------------------------------------------------------
13C8|
13C8| 2007                          MOVE.L  D7,D0           ;get error indicators
13CA| 0280 0000 000F                ANDI.L  #CPUMSK,D0      ;mask off no-CPU errors
13D0| 4A80                          TST.L   D0              ;any?
13D2| 673A                          BEQ.S   EXCHK           ;skip if none to check for exception errors
13D4|
13D4|                               .IF  USERINT = 0
13D4|                               .ELSE
13D4| 45FA 25B5                     LEA     CPUBRD,A2       ;set ptr for CPU board icon
13D8|
13D8|                               .ENDC
13D8|
13D8|                       ;  Check for specific error
13D8|
13D8|                               .IF  DIAGS = 1
13D8|
13D8| 0807 0001                     BTST    #CPUSEL,D7      ;check for CPU selection error
13DC| 670A                          BEQ.S   @1              ;skip if not
13DE| 7029                          MOVEQ   #ECPUSEL,D0     ;else get error code
13E0| 6100 0108                     BSR     ERRDISP         ;display it
13E4| 6000 F39A                     BRA     VIA2TST         ;and loop on parallel port VIA test
13E8|
13E8|                       ;  Sound error tones if not selection error (controls path to speaker)
13E8|
13E8| 6100 02E2             @1      BSR     LOPTCH          ;CPU error causes lo,lo,hi tones
13EC| 6100 02DE                     BSR     LOPTCH
13F0| 6100 02D6                     BSR     HIPTCH
13F4|
13F4|                       ;  Continue check for specific error
13F4|
13F4| 0807 0000                     BTST    #MMU,D7         ;CHECK IF MMU ERROR
13F8| 6704                          BEQ.S   @2              ;SKIP IF NO
13FA| 7028                          MOVEQ   #EMMU,D0        ;ELSE GET ERROR CODE
13FC| 600C                          BRA.S   @9              ;and go output it
13FE|
13FE|                       @2
13FE|                               .IF     NEWLISA = 1
13FE|                               .IF     ROM16K = 1
13FE| 0807 0002                     BTST    #VID,D7         ;CHECK IF VIDEO ERROR
1402| 6704                          BEQ.S   @3              ;SKIP IF NO
1404| 702A                          MOVEQ   #EVID,D0        ;ELSE GET ERROR CODE
1406| 6002                          BRA.S   @9              ;and go output it
1408|
1408| 702B                  @3      MOVEQ   #ECPAR,D0       ;else must be parity ckt error
140A|
140A|                               .ENDC                   ;{ROM16K}
140A|                               .ENDC                   ;{NEWLISA}
140A|                               .ENDC                   ;{DIAGS}
140A|
140A| 6000 01B4             @9      BRA     TSTXIT          ;go to exit
140E|
140E|                               .ENDC                   ;{ROM4K}
140E|
140E|                       ;----------------------------------------------------------------------------
140E|                       ;  Scan for exception errors
140E|                       ;----------------------------------------------------------------------------
140E|
140E| 2007                  EXCHK   MOVE.L  D7,D0           ;mask off non-exception errors
1410| 0280 0000 03F0                ANDI.L  #EXMSK,D0
1416| 4A80                          TST.L   D0              ;OK?
1418| 6744                          BEQ.S   IOCHK           ;skip if yes to next check
141A|
141A|                               .IF  USERINT = 0
141A|                               .ELSE
141A|
141A|                       ;  Sound error tones
141A|
141A| 6100 02B0                     BSR     LOPTCH          ;general logic failure causes lo,hi tones
141E| 6100 02A8                     BSR     HIPTCH
1422| 45FA 2930                     LEA     LISA,A2         ;set ptr for general LISA error
1426|                               .ENDC
1426|                       ;  Scan for details on exception errors
1426|
1426| 0807 0004                     BTST    #CPUINTR,D7     ;NMI?
142A| 6704                          BEQ.S   @1
142C| 702C                          MOVEQ   #ECPUINTR,D0    ;set error code
142E| 602A                          BRA.S   @9              ;and go display
1430|
1430| 0807 0005             @1      BTST    #BUSEXCP,D7     ;bus error?
1434| 6704                          BEQ.S   @2
1436| 702D                          MOVEQ   #EBUSEXCP,D0    ;set error code
1438| 6020                          BRA.S   @9
143A|
143A| 0807 0006             @2      BTST    #ADREXCP,D7     ;address error?
143E| 6704                          BEQ.S   @3
1440| 702E                          MOVEQ   #EADREXCP,D0    ;set error code
1442| 6016                          BRA.S   @9
1444|
1444| 0807 0007             @3      BTST    #MISEXCP,D7     ;miscellaneous error?
1448| 6704                          BEQ.S   @4
144A| 702F                          MOVEQ   #EMISEXCP,D0    ;set error code
144C| 600C                          BRA.S   @9
144E|
144E| 0807 0008             @4      BTST    #ILLEXCP,D7     ;illegal instruction error?
1452| 6704                          BEQ.S   @5
1454| 7030                          MOVEQ   #EILLEXCP,D0    ;set error code
1456| 6002                          BRA.S   @9
1458|
1458| 7031                  @5      MOVEQ   #ETRPEXCP,D0    ;must be a trap error
145A|
145A| 6000 0164             @9      BRA     TSTXIT          ;and go to exit
145E|
145E|                       ;-------------------------------------------------------------------------
145E|                       ;  Check for I/O errors
145E|                       ;-------------------------------------------------------------------------
145E|
145E| 2007                  IOCHK   MOVE.L  D7,D0           ;GET ERRORS
1460| 0280 001F DC00                ANDI.L  #IOMSK,D0       ;MASK OFF NON-IO ERRORS
1466| 4A80                          TST.L   D0              ;OK?
1468| 6700 008E                     BEQ     KBDCHK          ;SKIP IF YES TO NEXT CHECK
146C|
146C|                               .IF  USERINT = 0
146C|                               .ELSE
146C| 45FA 24DD                     LEA     IOBRD,A2        ;set ptr for I/O board icon
1470|                               .ENDC
1470|
1470|                               .IF  ROM4K = 0
1470|                       ;  Scan for details on I/O errors
1470|
1470|                               .IF     ROM16K = 1
1470| 0807 000A                     BTST    #VIA1,D7        ;check for keyboard VIA errors
1474| 6708                          BEQ.S   @1              ;skip if OK
1476| 7032                          MOVEQ   #EVIA1,D0       ;else set error code
1478| 6170                          BSR.S   ERRDISP         ;display the error
147A| 6000 F434                     BRA     VIA1CHK         ;and loop on VIA #1 test
147E|
147E|                       ;  Sound error tones if not VIA #1 error (controls the speaker)
147E| 6100 024C             @1      BSR     LOPTCH          ;I/O errors cause lo,hi,lo tones
1482| 6100 0244                     BSR     HIPTCH
1486| 6100 0244                     BSR     LOPTCH
148A|                       ;  Continue scan for detailed errors
148A|
148A| 0807 000B                     BTST    #VIA2,D7        ;parallel port VIA error?
148E| 6704                          BEQ.S   @2
1490| 7033                          MOVEQ   #EVIA2,D0       ;set error code
1492| 6052                          BRA.S   @19
1494|                               .ENDC
1494|
1494| 0807 000C             @2      BTST    #IOCOPS,D7
1498| 6708                          BEQ.S   @3
149A| 7034                          MOVEQ   #EIOCOP,D0      ;get error code
149C| 614C                          BSR.S   ERRDISP         ;display error
149E| 6000 F44A                     BRA     COPSENBL        ;and go do loop on COPS test
14A2|
14A2|                       @3
14A2|                               .IF  DIAGS = 1
14A2| 0807 000E                     BTST    #CLK,D7
14A6| 6704                          BEQ.S   @4
14A8| 7036                          MOVEQ   #ECLK,D0        ;ELSE GET ERROR CODE
14AA| 603A                          BRA.S   @19
14AC|                               .ENDC
14AC|
14AC|                       @4
14AC|                               .IF  FULLSCC = 1
14AC| 0807 000F                     BTST    #RS232A,D7
14B0| 6704                          BEQ.S   @6
14B2| 7037                          MOVEQ   #ERS232A,D0     ;ELSE GET ERROR CODE
14B4| 6030                          BRA.S   @19
14B6|
14B6| 0807 0010             @6      BTST    #RS232B,D7
14BA| 6704                          BEQ.S   @7
14BC| 7038                          MOVEQ   #ERS232B,D0     ;ELSE GET ERROR CODE
14BE| 6026                          BRA.S   @19
14C0|                               .ENDC
14C0|
14C0| 0807 0011             @7      BTST    #DISK,D7
14C4| 6704                          BEQ.S   @8
14C6| 7039                          MOVEQ   #EDISK,D0       ;ELSE GET ERROR CODE
14C8| 601C                          BRA.S   @19
14CA|
14CA| 0807 0012             @8      BTST    #IOEXCP,D7
14CE| 6704                          BEQ.S   @9
14D0| 703A                          MOVEQ   #EIOEXCP,D0     ;ELSE GET ERROR CODE
14D2| 6012                          BRA.S   @19
14D4|
14D4| 0807 0013             @9      BTST    #IOCOPS2,D7     ;COPS code error?
14D8| 6704                          BEQ.S   @10
14DA| 703B                          MOVEQ   #EIOCOP2,D0     ;get error code
14DC| 6008                          BRA.S   @19
14DE|
14DE| 0807 0014             @10     BTST    #IOKBD,D7       ;I/O or keyboard error?
14E2| 6702                          BEQ.S   @19
14E4| 703C                          MOVEQ   #EIOKBD,D0      ;get error code
14E6|
14E6|                               .ENDC                   ;{ROM4K}
14E6|
14E6| 6000 00D8             @19     BRA     TSTXIT
14EA|
14EA|                       ;--------------------------------------------------------------------------
14EA|                       ;  Subroutine to do display for fatal errors
14EA|                       ;--------------------------------------------------------------------------
14EA|
14EA|                       ERRDISP
14EA|                               .IF  USERINT = 1
14EA| 6100 1FEE                     BSR     DSPERRICON      ;display error
14EE|                               .ENDC
14EE|
14EE| 6100 0132                     BSR     DSPCODE         ;output error code
14F2| 08C7 001F                     BSET    #LOOP,D7        ;set for looping operation
14F6| 4E75                          RTS
14F8|
14F8|                       ;--------------------------------------------------------------------------
14F8|                       ;  Check for keyboard error
14F8|                       ;--------------------------------------------------------------------------
14F8|
14F8| 0807 000D             KBDCHK  BTST    #KBDCOPS,D7     ;Keyboard error?
14FC| 6716                          BEQ.S   MEMCHK          ;skip to next check if not
14FE|
14FE|                               .IF  USERINT = 1
14FE|
14FE|                       ;  Sound error tones
14FE|
14FE| 6100 01C8                     BSR     HIPTCH          ;Keyboard error causes hi,lo,hi tones
1502| 6100 01C8                     BSR     LOPTCH
1506| 6100 01C0                     BSR     HIPTCH
150A| 45FA 2699                     LEA     KEYBDOUT,A2     ;set ptr for keyboard icon
150E|                               .ENDC
150E|
150E| 7035                          MOVEQ   #EKBDCOP,D0     ;set error code
1510| 6000 00AE                     BRA     TSTXIT          ;and go to exit
1514|
1514|
1514|                       ;--------------------------------------------------------------------------
1514|                       ;  Check for memory errors
1514|                       ;--------------------------------------------------------------------------
1514|
1514|                       MEMCHK
1514| 2007                          MOVE.L  D7,D0           ;GET ERRORS
1516| 0280 0060 0000                ANDI.L  #MEMMSK,D0      ;MASK OFF NON-memory ERRORS
151C| 4A80                          TST.L   D0              ;any errors?
151E| 6700 0070                     BEQ     IOSCHK          ;skip if no - must be I/O slot error
1522|
1522|                               .IF  USERINT = 0
1522|                               .ELSE
1522|
1522|                       ;  Sound memory error tones
1522|
1522| 6100 01A8                     BSR     LOPTCH          ;memory error causes lo,hi,hi tones
1526| 6100 01A0                     BSR     HIPTCH
152A| 6100 019C                     BSR     HIPTCH
152E|
152E|                       ;  determine which memory card in error if more than one
152E|
152E| 0CB8 0008 0000 02A8           CMPI.L  #HEX512K,TOTLMEM ;more than 1 memory card?
1536| 6E14                          BGT.S   SCNRSLTS         ;skip if yes
1538|
1538|                       ;  only one card - check memory addresses to determine slot
1538|
1538| 2038 02A4                     MOVE.L  MINMEM,D0       ;get low physical address
153C| 0C80 0010 0000        CHKMADR CMPI.L  #ONEMEG,D0      ;address in slot 1?
1542| 6D04                          BLT.S   @2              ;skip if not
1544| 7201                          MOVEQ   #1,D1           ;set board id for slot 1
1546| 6002                          BRA.S   @3
1548| 7202                  @2      MOVEQ   #2,D1           ;set board id for slot 2
154A| 6026                  @3      BRA.S   MERRCHK         ;and go scan for details
154C|
154C|                       ;  more than one memory card - scan memory test results to determine which card
154C|
154C|                       SCNRSLTS
154C| 0807 0016                     BTST    #MPAR,D7        ;parity error?
1550| 6706                          BEQ.S   @1              ;skip if not
1552| 2038 01A6                     MOVE.L  PEADDR,D0       ;go get error address                   CHG015
1556| 60E4                          BRA.S   CHKMADR         ;and check it
1558|
1558|                       ;  Check for R/W error
1558|
1558| 307C 0186             @1      MOVEA   #MEMRSLT,A0     ;set ptr to OR masks                    RM000
155C| 7008                          MOVEQ   #8,D0           ;and set counter
155E| 4A58                  @4      TST     (A0)+           ;check the rows
1560| 6604                          BNE.S   @5              ;skip if error detected
1562| 5340                          SUBQ    #1,D0           ;else check all masks
1564| 66F8                          BNE.S   @4              ;until done
1566|
1566| 0C00 0004             @5      CMP.B   #4,D0           ;check where error found
156A| 6E04                          BGT.S   @6              ;skip if low memory error
156C| 7201                          MOVEQ   #1,D1           ;high memory on card 1
156E| 6002                          BRA.S   MERRCHK
1570| 7202                  @6      MOVEQ   #2,D1           ;low memory on card 2
1572|
1572|                               .ENDC                   ;{USERINT}
1572|
1572|                               .IF  ROM4K = 0
1572|
1572|                       ;  scan for error details
1572|
1572| 0807 0015             MERRCHK BTST    #MEM,D7         ;check for main memory R/W error
1576| 6708                          BEQ.S   @2              ;exit if not
1578| 7046                          MOVEQ   #EMEM,D0        ;else display error code
157A| 11C1 02AD                     MOVE.B  D1,MEMSLOT      ;save slot # for board in error
157E| 6002                          BRA.S   MEMERR
1580|
1580| 7047                  @2      MOVEQ   #EPAR,D0        ;must be parity error
1582|
1582|                               .ENDC                   ;{ROM4K}
1582|
1582|                       MEMERR
1582|                               .IF  USERINT = 1
1582|
1582| 21C7 0180                     MOVE.L  D7,STATUS       ;save power-up status
1586| 45FA 2446                     LEA     MEMBRD,A2       ;set ptr for memory board icon
158A| 6100 1EC4                     BSR     DSPNUMICON      ;display icon and board slot #
158E| 6034                          BRA.S   TSTXIT2         ;finally exit to monitor
1590|
1590|                               .ELSE
1590|                               .ENDC                   ;{USERINT}
1590|
1590|                       ;--------------------------------------------------------------------------
1590|                       ;--------------------------------------------------------------------------
1590|                       IOSCHK
1590|                               .IF  ROM4K = 0
1590|                               .IF  USERINT = 0
1590|                               .ELSE
1590|
1590|                       ;  Sound error tones
1590|
1590| 6100 0136                     BSR     HIPTCH          ;I/O slot error causes hi,lo,lo tones
1594| 6100 0136                     BSR     LOPTCH
1598| 6100 0132                     BSR     LOPTCH
159C| 45FA 2476                     LEA     Xcard,A2        ;set ptr for I/O slot board icon
15A0|                               .ENDC
15A0|
15A0| 0807 001B             @1      BTST    #IO3ERR,D7      ;check for slot 3 error
15A4| 6704                          BEQ.S   @2              ;exit if not
15A6| 7203                          MOVEQ   #3,D1           ;else set slot #
15A8| 600C                          BRA.S   @4
15AA|
15AA| 0807 001A             @2      BTST    #IO2ERR,D7      ;slot 2 error?
15AE| 6704                          BEQ.S   @3
15B0| 7202                          MOVEQ   #2,D1           ;set slot #
15B2| 6002                          BRA.S   @4
15B4|
15B4| 7201                  @3      MOVEQ   #1,D1           ;must be slot 1 error
15B6|
15B6| 1038 01B4             @4      MOVE.B  BOOTDATA,D0     ;get error code
15BA| 6100 1E94                     BSR     DSPNUMICON      ;display error icon and slot #
15BE| 6004                          BRA.S   TSTXIT2         ;and exit to monitor
15C0|
15C0|                               .ENDC                   ;{ROM4K}
15C0|
15C0|                       TSTXIT
15C0|                               .IF  USERINT = 0
15C0|                               .ELSE
15C0| 6100 1F18                     BSR     DSPERRICON      ;display error icon
15C4|
15C4|                       TSTXIT2
15C4| 21C7 0180                     MOVE.L  D7,STATUS       ;save status
15C8| 6100 0058                     BSR     DSPCODE         ;display the error code
15CC|
15CC|                       ;  Save error data in special parameter memory area, then exit to monitor
15CC|
15CC|                       ;****************************
15CC|                       ;  Delete for LISA 2                                                             CHG034
15CC|                       ;****************************
15CC|
15CC|                       ;        LEA     PMVCT,A3        ;setup bus error vector for PM                  RM013
15CC|                       ;        MOVE.L  A3,BUSVCTR      ;                                               RM013
15CC|                       ;        BSR.S   CHKSTATPM       ;check if error already saved
15CC|                       ;        BCC.S   GOTOMON         ;skip if yes
15CC|                       ;        MOVEA.L #STATSTRT,A0    ;set starting ptr
15CC|                       ;        MOVE.B  D0,(A0)         ;save error code
15CC|                       ;        MOVE    ADRLTCH,D0      ;save error address latch contents
15CC|                       ;        MOVEP   D0,2(A0)
15CC|                       ;        MOVE.B  MEMSLOT,6(A0)   ;save memory slot #
15CC|                       ;        MOVE.L  CLKDATA,D0      ;save clock data
15CC|                       ;        MOVEP.L D0,8(A0)
15CC|                       ;        MOVE    CLKDATA+4,D0
15CC|                       ;        MOVEP   D0,16(A0)
15CC|                       ;        CLR.L   D0              ;clear remaining area
15CC|                       ;        MOVEP.L D0,20(A0)
15CC|
15CC|                       ;        MOVEQ   #STATWRDS-2,D0  ;validate save area
15CC|                       ;        BSR     WRTSUM
15CC|
15CC| 6100 FC14             GOTOMON BSR     SCANCPS         ;clear COPS queue
15D0| 6100 F34E                     BSR     CPSINIT         ;reinit interface
15D4| 6100 19F6                     BSR     CURSORINIT      ;init cursor and mouse
15D8| 6000 0FC2                     BRA     MONITOR         ;then jump to monitor
15DC|
15DC|                       ;-------------------------------------------------------------------------
15DC|                       ;  Parameter memory bus error handler           RM013
15DC|                       ;-------------------------------------------------------------------------
15DC|
15DC| 3E7C 0480             PMVCT   MOVEA   #STKBASE,SP     ;reset stack                                    RM013
15E0| 6100 F100                     BSR     SETBUSVCT       ;restore bus error vector                       RM013
15E4| 60E6                          BRA.S   GOTOMON         ;and exit to monitor                            RM013
15E6|
15E6|                       ;-------------------------------------------------------------------------
15E6|                       ;  Subroutine to check special parameter memory validity.
15E6|                       ;  Verify checksum routine sets carry bit if checksum not valid.
15E6|                       ;-------------------------------------------------------------------------
15E6|
15E6|                       ;CHKSTATPM                                                                      CHG034
15E6|                       ;        MOVEM.L D0-D1/A0,-(SP)  ;save regs
15E6|                       ;        MOVEA.L #STATSTRT,A0    ;set starting ptr
15E6|                       ;        MOVEQ   #STATWRDS-1,D0  ;and # of words to check
15E6|                       ;        MOVE    D0,D1           ;set for shared memory
15E6|                       ;        BSR     VFYCHKSM        ;and go do checksum
15E6|                       ;@1      MOVEM.L (SP)+,D0-D1/A0  ;restore regs
15E6|                       ;        RTS
15E6|
15E6|                               .ENDC
15E6|                       ;------------------------------------------------------------------------
15E6|                       ;  Scan for non-fatal errors
15E6|                       ;------------------------------------------------------------------------
15E6|
15E6|                       OTHER
15E6|                               .IF  ROM16K = 1
15E6| 2007                          MOVE.L  D7,D0           ;get errors
15E8| 0280 0180 0000                ANDI.L  #OTHRMSK,D0     ;isolate to non-fatal errors
15EE| 4A80                          TST.L   D0              ;OK?
15F0| 672C                          BEQ.S   @9              ;skip if no errors
15F2| 0807 0017                     BTST    #KBDOUT,D7      ;Keyboard disconnected?
15F6| 6706                          BEQ.S   @1              ;skip if no
15F8|
15F8|                               .IF  USERINT = 0
15F8|                               .ELSE
15FC| 6014                          BRA.S   @2              ;with question markcon
15FE|                               .ENDC
15FE|
15FE|                       @1                              ;must be mouse
15FE|                               .IF  USERINT = 0
15FE|                               .ELSE
15FE| 6100 0236                     BSR     CHKPM           ;check parameter memory before notify
1602|                                                       ; of mouse disconnect
1602| 6516                          BCS.S   @8              ;ignore error if invalid
1604| 0839 0007 00FC C18D           BTST    #MOUSEON,MEMCODE ;check if should be installed
160C| 670C                          BEQ.S   @8              ;skip if not
160E| 45FA 261B                     LEA     MOUSEOUT,A2     ;else display mouse icon
1612| 6100 1F42             @2      BSR     DSPQICON        ;with question mark
1616|                               .ENDC
1616|
1616| 6000 00A0                     BRA     NOTIFY          ;alert user
161A|
161A|                               .ENDC                   ;{ROM16K}
161A|
161A| 0887 0018             @8      BCLR    #MOUSOUT,D7     ;ignore mouse disconnected error
161E|
161E| 6000 00BE             @9      BRA     SYSOK           ;system must be OK
1622|                               .PAGE
1622|                       ;-------------------------------------------------------------------------
1622|                       ;  Subroutine to output error code
1622|                       ;-------------------------------------------------------------------------
1622|
1622| 48E7 F000             DSPCODE MOVEM.L D0-D3,-(SP)     ;save regs
1626|
1626|                               .IF  USERINT = 0
1626|                               .ENDC
1626|                               .IF  NEWTWIG = 0
1626|                               .ENDC
1626|
1626|                               .IF USERINT = 1
1626| 3A3C 0097                     MOVE    #CODEROW,D5     ;set screen ptrs for display
162A| 3C3C 0012                     MOVE    #CODECOL,D6
162E|                               .ENDC
162E|
162E| 6004                          BRA.S   GETDIG          ;go do display
1630|                               .IF  NEWTWIG = 1
1630|
1630|                       ;  Translate up to 4 digit hex error code to decimal
1630|                       ;  Second entry point for routine
1630|
1630|                       DSPDEC
1630| 48E7 F000                     MOVEM.L D0-D3,-(SP)     ;save regs
1634| 0280 0000 FFFF        GETDIG  ANDI.L  #$0FFFF,D0      ;clear other digits
163A| 7201                          MOVEQ   #1,D1           ;display 1 char at a time
163C| 4A40                          TST     D0              ;is it 0?
163E| 6726                          BEQ.S   @9              ;exit if yes to display it
1640| 4282                          CLR.L   D2              ;clear working regs
1642| 4283                          CLR.L   D3
1644|
1644|                       ;  display all non-zero digits
1644|
1644| 80FC 000A             @1      DIVU    #$A,D0          ;converting to decimal
1648| 4840                          SWAP    D0              ;get remainder
164A| 1400                          MOVE.B  D0,D2           ;save for display
164C| E89A                          ROR.L   #4,D2
164E| 5243                          ADDQ    #1,D3           ;set count
1650|
1650| 4240                          CLR     D0              ;clear remainder
1652| 4840                          SWAP    D0              ;get new quotient
1654| 4A40                          TST     D0              ;quit when =0
1656| 6702                          BEQ.S   @2              ;skip to do display
1658| 60EA                          BRA.S   @1
165A|
165A| E99A                  @2      ROL.L   #4,D2           ;get char for output
165C| 1002                          MOVE.B  D2,D0
165E| 5343                          SUBQ    #1,D3           ;decr digit count
1660| 6704                          BEQ.S   @9              ;skip to display last digit
1662| 6114                          BSR.S   OUTCH           ;display a digit
1664| 60F4                          BRA.S   @2              ;and loop until done
1666|
1666|                               .ENDC
1666|
1666| 6106                  @9      BSR.S   OUTCHR          ;do output and CR
1668|
1668| 4CDF 000F             DSPCXIT MOVEM.L (SP)+,D0-D3     ;restore regs
166C| 4E75                          RTS                     ;and return
166E|
166E|                       ;-------------------------------------------------------------------------
166E|                       ;  Subroutine to invoke code display routine, then do CR
166E|                       ;-------------------------------------------------------------------------
166E|
166E| 6108                  OUTCHR  BSR.S   OUTCH           ;output digits
1670|
1670|                               .IF  USERINT = 0
1670|                               .ELSE
1670| 0645 000A                     ADD     #CHRSPC,D5      ;bump to next char row
1674|                               .ENDC
1674|
1674| 7C01                          MOVEQ   #1,D6           ;and do CR
1676| 4E75                          RTS
1678|
1678|                               .PAGE
1678|                       ;-------------------------------------------------------------------------
1678|                       ;  Subroutines to enable display of hex codes
1678|                       ;  Requires  D0 = value to display
1678|                       ;            D1 = # of digits to display
1678|                       ;-------------------------------------------------------------------------
1678|
1678| 48E7 E000             OUTCH   MOVEM.L D0-D2,-(SP)     ;save regs
167C| 7408                          MOVEQ   #8,D2           ;set max digits to display
167E| B401                  @1      CMP.B   D1,D2           ;check digits desired
1680| 6706                          BEQ.S   @2              ;and skip if match
1682| E998                          ROL.L   #4,D0           ;else skip over digit
1684| 5342                          SUBQ    #1,D2           ;update count
1686| 60F6                          BRA.S   @1              ;and loop until match
1688|
1688| E998                  @2      ROL.L   #4,D0           ;rotate to next digit
168A| 610A                          BSR.S   OUTNIB          ;go output one digit
168C| 5341                          SUBQ    #1,D1           ;decr count
168E| 66F8                          BNE.S   @2              ;loop until done
1690|
1690| 4CDF 0007                     MOVEM.L (SP)+,D0-D2     ;restore and exit
1694| 4E75                          RTS
1696|
1696|                       ;  The following routine does conversion to ASCII to enable display
1696|
1696| 2F00                  OUTNIB  MOVE.L  D0,-(SP)        ;SAVE REG
1698| 0240 000F                     ANDI    #$000F,D0       ;ISOLATE DIGIT TO DISPLAY
169C| 0C00 0009                     CMPI.B  #9,D0           ;CHECK IF NUMERIC
16A0| 6206                          BHI.S   ALPHA           ;SKIP IF NOT
16A2| 0000 0030                     ORI.B   #$30,D0         ;CONVERT TO ASCII
16A6| 6008                          BRA.S   DSPCH           ;AND GO DISPLAY
16A8|
16A8| 0400 0009             ALPHA   SUBI.B  #9,D0           ;CONVERT FOR
16AC| 0000 0040                     ORI.B   #$40,D0         ; ASCII
16B0|
16B0| 6100 2088             DSPCH   BSR     DSPVAL          ;OUTPUT IT
16B4| 201F                          MOVE.L  (SP)+,D0        ;RESTORE REG
16B6| 4E75                          RTS
16B8|
16B8|                               .PAGE
16B8|                       ;-------------------------------------------------------------------------
16B8|                       ;  Routine to notify user of non-fatal error.  Beep speaker and pause
16B8|                       ;  for 5 seconds.
16B8|                       ;-------------------------------------------------------------------------
16B8|
16B8|                       NOTIFY
16B8|                               .IF  ROM16K = 1
16B8| 610E                          BSR.S   HIPTCH          ;beep at high pitch twice
16BA| 610C                          BSR.S   HIPTCH
16BC| 610E                          BSR.S   LOPTCH          ;beep at low pitch
16BE| 6100 F414                     BSR     DELAY5          ;delay 5 seconds
16C2| 6100 1A16                     BSR     CLRDESK         ;clear desktop                          CHG033
16C6| 601A                          BRA.S   DOBOOT          ;then go attempt boot
16C8|
16C8|                       ;-------------------------------------------------------------------------
16C8|                       ;  Subroutine to beep speaker at high pitch
16C8|                       ;-------------------------------------------------------------------------
16C8| 7020                  HIPTCH  MOVEQ   #$20,D0         ; set frequency
16CA| 6002                          BRA.S   SETDUR          ; and go do it
16CC|
16CC|                       ;-------------------------------------------------------------------------
16CC|                       ;  Subroutine to beep speaker at low pitch
16CC|                       ;-------------------------------------------------------------------------
16CC|
16CC| 7060                  LOPTCH  MOVEQ   #$60,D0         ; set frequency
16CE| 323C 00FA             SETDUR  MOVE    #250,D1         ; 1/8 sec duration
16D2| 7404                          MOVEQ   #4,D2           ; low volume
16D4| 6100 F420                     BSR     TONE            ; and go do it
16D8| 6100 F3F2                     BSR     DELAY_1         ; delay for .1 sec
16DC| 4E75                          RTS
16DE|
16DE|                               .ENDC
16DE|                               .PAGE
16DE|                       ;-------------------------------------------------------------------------
16DE|                       ;  No errors detected - output greeting message
16DE|                       ;-------------------------------------------------------------------------
16DE|
16DE| 42B8 0180             SYSOK   CLR.L   STATUS          ;set status
16E2|                               .IF  ROM16K = 1
16E2|                       ;        BSR     CHKSTATPM       ;check special save area                       CHG034
16E2|                       ;        BCC.S   DOBOOT          ;skip if valid data saved
16E2|                       ;        CLR.B   STATSAV         ;else set status to 0
16E2|                               .ENDC
16E2|
16E2|                               .IF  ROM4K = 0
16E2|                               .IF  USERINT = 0
16E2|                               .ENDC                   ;{USERINT}
16E2|                               .ENDC                   ;{ROM4K}
16E2|                               .IF  ROM4K = 0
16E2|                               .IF  USERINT = 0
16E2|                               .ENDC                   ;{USERINT}
16E2|                               .ENDC                   ;{ROM4K}
16E2|
16E2|                               .INCLUDE RM248.B.TEXT
16E2|
16E2|                               .PAGE
16E2|                               .LIST
16E2|                       ;-------------------------------------------------------------------------
16E2|                       ;  All is OK - check for boot device and then do bootstrap
16E2|                       ;-------------------------------------------------------------------------
16E2|
16E2| 6100 18E8             DOBOOT  BSR     CURSORINIT      ;init cursor/mouse
16E6|
16E6|                       BOOTCHK
16E6| 4280                          CLR.L   D0              ;clear for use
16E8| 0807 001C                     BTST    #ALTBOOT,D7     ;check if alternate boot command rcvd
16EC| 6710                          BEQ.S   @1              ;skip if no
16EE| 1038 01B3                     MOVE.B  BOOTDVCE,D0     ;get alternate boot code
16F2|
16F2|                              .IF     BURNIN = 1
16F2| 0C00 000F                     CMP.B   #PC,D0          ;power-cycle mode?
16F6| 665C                          BNE.S   DVCECHK         ;if no, go determine device
16F8| 6100 0154                     BSR     SAV2PM          ;if yes, save in parameter memory
16FC|                              .ENDC
16FC|
16FC| 6056                          BRA.S   DVCECHK         ;and go determine device
16FE|
16FE|                       @1
16FE|                               .IF USERINT = 1
16FE| 0807 001D                     BTST    #BTMENU,D7      ;boot menu wanted?
1702| 6600 01F4                     BNE     BOOTMENU        ;skip if yes
1706|                               .ENDC
1706|
1706| 6100 012E                     BSR     CHKPM           ;next step is to check parameter memory
170A|
170A|                               .IF  AAPL = 1
170A|                               .ELSE
170A| 6416                          BCC.S   @2              ;skip if valid
170C|
170C|                       ;  set default boot
170C|
170C| 4A38 02AF                     TST.B   SYSTYPE         ;else check if Lisa 1                           CHG030
1710| 670C                          BEQ.S   @5              ;skip if yes                                    CHG030
1712| 7401                          MOVEQ   #1,D2           ;else set wait flag                             CHG030
1714| 6100 0320                     BSR     CHKPROFILE      ;and go check if hard disk attached             CHG030
1718| 6704                          BEQ.S   @5              ;skip if yes to do boot from hard disk          CHG030
171A| 7001                          MOVEQ   #TWIG2,D0       ;else set for boot from floppy                  CHG030
171C| 600E                          BRA.S   @3              ;                                               CHG030
171E|
171E| 7002                  @5      MOVEQ   #PROFILE,D0     ;else if not valid do default boot from Profile
1720| 600A                          BRA.S   @3
1722|                               .ENDC
1722|
1722| 1039 00FC C189        @2      MOVE.B  DVCCODE,D0      ;else read device code
1728| E808                          LSR.B   #4,D0           ;rotate to low nibble
172A| 6028                          BRA.S   DVCECHK
172C|
172C|                               .IF  NEWTWIG = 0
172C|                               .ENDC
172C|
172C|                       @3
172C|                               .IF  ROM16K = 1
172C|                       ;  Do special check for Applenet and I/O test cards
172C|
172C| 323C 1000                     MOVE    #TSTCRD,D1      ;search first for a bootable test card
1730| 383C 1800                     MOVE    #TSTQUAL,D4
1734| 6100 01A0                     BSR     SEARCH          ;go do search
1738| 661A                          BNE.S   DVCECHK         ;skip if not found
173A| 3602                          MOVE    D2,D3           ;else save its id
173C| 323C 8001                     MOVE    #APPLENET,D1    ;next search for an Applenet card
1740| 383C 9FFF                     MOVE    #APPLQUAL,D4
1744| 6100 0190                     BSR     SEARCH
1748| 6704                          BEQ.S   @4              ;skip if found to boot from it (DMT need)
174A| 3403                          MOVE    D3,D2           ;else do boot from I/O test card (DIAG need)
174C| 6A06                          BPL.S   DVCECHK         ; unless card boot bit not set                  CHG012
174E|                       @4
174E| C4FC 0003                     MULU    #3,D2           ;convert to boot id
1752| 3002                          MOVE    D2,D0           ;and set boot id for appropriate slot
1754|                               .ENDC
1754|
1754|                       ;  Alternate boot desired - check which
1754|
1758|                       DVCECHK MOVE.B  D0,BOOTDVCE     ;save for later reference
1758|                               .IF TWIGGY = 1
1758| 4A00                          TST.B   D0              ;boot from upper drive?                 CHG009
175A| 660E                          BNE.S   @1              ;no - go to next check
175C| 4A38 02AF                     TST.B   SYSTYPE         ;check system type                      CHG009
1760| 6704                          BEQ.S   @11             ;skip if Lisa 1.0                       CHG009
1762| 6000 076A             @10     BRA     PROBOOT         ;else do Pepsi boot                     CHG009
1766|
1766| 4200                  @11     MOVE.B  #DRV1,D0        ;else set drive #                       CHG009
1768| 600A                          BRA.S   @2              ;and go do boot
176A|
176A| 0C00 0001             @1      CMP.B   #TWIG2,D0       ;boot from lower drive?                 CHG009
176E| 6608                          BNE.S   @3              ;skip if no
1770| 103C 0080                     MOVE.B  #DRV2,D0        ;else set drive #
1774| 6000 0456             @2      BRA     TWGBOOT         ;and go boot
1778|                               .ENDC
1778|
1778|                       @3
1778|                               .IF PROFLE = 1
1778| 0C00 0002                     CMP.B   #PROFILE,D0     ;boot from Profile?
177C| 67E4                          BEQ.S   @10             ;yes - go do it                         CHG009
177E|                               .ENDC
177E|
177E| 0C00 0004                     CMP.B   #IO1PORT2,D0    ;boot from slot 1, ports 1-2?
1782| 6E08                          BGT.S   @4              ;skip if not
1784| 227C 00FC 0001                MOVE.L  #SLOT1L,A1      ;set slot address
178A| 601A                          BRA.S   @9              ;and go do boot
178C|
178C| 0C00 0007             @4      CMP.B   #IO2PORT2,D0    ;boot from slot 2, ports 1-2?
1790| 6E08                          BGT.S   @5              ;skip if not
1792| 227C 00FC 4001                MOVE.L  #SLOT2L,A1      ;set slot address
1798| 600C                          BRA.S   @9              ;and go do boot
179A|
179A| 0C00 000A             @5      CMP.B   #IO3PORT2,D0    ;boot from slot 3, ports 1-2?
179E| 6E0A                          BGT.S   @6              ;skip if not
17A0| 227C 00FC 8001                MOVE.L  #SLOT3L,A1      ;set slot address
17A6|
17A6| 6000 09B6             @9      BRA     IOSBOOT         ;and go do boot
17AA|
17AA|                       @6
17AA|                               .IF     BURNIN = 1
17AA| 0C00 000F                     CMP.B   #PC,D0          ;power-cycle?
17AE| 6700 0A8A                     BEQ     CHKPASS         ;go do cycling
17B2|                               .ENDC
17B2|
17B2|                               .IF  ROM4K = 0
17B2| 0C00 0010             @7      CMP.B   #MON,D0         ;abort boot?
17B6| 6676                          BNE.S   LSTCHK          ;skip if no match
17B8|
17B8|                               .IF  USERINT = 1
17B8| 08B8 0000 02A2                BCLR    #NORSTRT,STATFLGS ;allow restart option but
17BE| 08F8 0001 02A2                BSET    #NOCONT,STATFLGS  ; no CONTINUE button for direct to monitor jump
17C4| 6100 194E                     BSR     CLRMENU           ;clear menu bar and
17C8| 6100 199A                     BSR     MAKEPCALRT        ; open alert box for monitor or power cycling
17CC|                               .ENDC
17CC|
17CC|                               .IF  BURNIN = 1
17CC|
17CC|                       ;  Check if completing power-cycling operation
17CC|
17CC|                               .IF  DEBUG = 0
17CC| 47FA 0052                     LEA     PMERR,A3        ;set vector for parameter mem error
17D0| 21CB 0008                     MOVE.L  A3,BUSVCTR
17D4|                               .ENDC
17D4|
17D4| 6100 0060                     BSR     CHKPM           ;check validity of parameter memory
17D8| 653E                          BCS.S   PMEXIT          ;skip if not
17DA| 1039 00FC C189                MOVE.B  DVCCODE,D0      ;get boot code
17E0| E808                          LSR.B   #4,D0           ;shift to lower nibble
17E2|
17E2|                               .IF     NEWTWIG = 0
17E2|                               .ENDC
17E2|
17E2| 0C00 000F                     CMPI.B  #PC,D0          ;exiting from power-cycling?
17E6| 6630                          BNE.S   PMEXIT          ;skip if no
17E8| 4239 00FC C189                CLR.B   DVCCODE         ;else reset boot and
17EE| 08B9 0006 00FC C18D           BCLR    #6,MEMCODE      ; memory test indicators
17F6|
17F6| 47FA 25FC                     LEA     LOOPMSG,A3      ;display loop count
17FA| 6100 1F04                     BSR     DSPMSG
17FE| 207C 00FC C195                MOVE.L  #LCNTHI,A0      ;set ptr to loop count
1804| 0108 0000                     MOVEP   (A0),D0         ;get it
1808| 7204                          MOVEQ   #4,D1           ;set # of digits to display
180A| 6100 FE62                     BSR     OUTCHR          ;and do display
180E| 7C0C                          MOVEQ   #PCCOL,D6       ;reset col for proper left margin
1810|
1810| 6100 0CB8                     BSR     DSPCLK          ;display final clock value
1814| 6100 0CFA                     BSR     TWGDSP          ;and display Twiggy error count
1818|
1818|                       ;  Normal exit
1818|                       PMEXIT
1818|                               .IF  DEBUG = 0
1818| 6100 EEC8                     BSR     SETBUSVCT       ;restore normal bus error vector        RM000
181C|                               .ENDC                   ;{debug}
181C|
181C|                               .ENDC                   ;{BURNIN}
181C|
181C| 6000 0D7E                     BRA     MONITOR         ;and go to monitor
1820|
1820|                               .IF  BURNIN = 1
1820|                       ;  Bus error handler for parameter memory error
1820|
1820| 47FA 25E1             PMERR   LEA     PMMSG,A3        ;setup error message
1824| 45FA 2125                     LEA     IOBRD,A2        ;and icon
1828| 4280                          CLR.L   D0              ;no error code
182A| 6000 0D08                     BRA     INITMON         ;exit to monitor
182E|
182E|                               .ENDC                   ;{BURNIN}
182E|                               .ENDC                   ;{ROM4K}
182E|                       LSTCHK
182E|                               .IF  AAPL = 1
182E|                               .ENDC
182E|
182E|                               .IF  USERINT = 0
182E|                               .ELSE
182E| 6100 0EDC                     BSR     SQUAWK          ;else sound error tone
1832| 6000 00C4                     BRA     BOOTMENU        ;and go to boot menu
1836|                               .ENDC
1836|
1836|                               .PAGE
1836|                       ;-------------------------------------------------------------------------
1836|                       ;  Subroutine to check parameter memory validity.  Calls generalized
1836|                       ;  verify checksum routine.
1836|                       ;-------------------------------------------------------------------------
1836|
1836| 48E7 C080             CHKPM   MOVEM.L D0-D1/A0,-(SP)  ;save regs
183A| 207C 00FC C181                MOVEA.L #PMSTRT,A0      ;set starting ptr
1840| 303C 001F                     MOVE    #PMWRDS-1,D0    ;and # of words to check
1844| 3200                          MOVE    D0,D1           ;set for shared memory
1846| 6144                          BSR.S   VFYCHKSM        ;and go do checksum
1848| 4CDF 0103             @1      MOVEM.L (SP)+,D0-D1/A0  ;restore regs
184C| 4E75                          RTS
184E|                               .IF BURNIN = 1
184E|                       ;-------------------------------------------------------------------------
184E|                       ;  Subroutine to save boot device code to parameter memory.
184E|                       ;-------------------------------------------------------------------------
184E| 48E7 C080             SAV2PM  MOVEM.L D0-D1/A0,-(SP)  ;save regs
1852|                               .IF     NEWTWIG = 0
1852|                               .ENDC
1852| E908                          LSL.B   #4,D0           ;rotate device code to upper nibble
1854| 1239 00FC C189                MOVE.B  DVCCODE,D1      ;read current setting
185A| 0201 000F                     ANDI.B  #$0F,D1         ;clear device indicator
185E| 8001                          OR.B    D1,D0           ;save other data
1860| 13C0 00FC C189                MOVE.B  D0,DVCCODE      ;and write new device code
1866|
1866|                       ;  also set for full memory test
1866| 08F9 0006 00FC C18D           BSET    #6,MEMCODE      ;ensure memory test indicator set
186E|
186E|                       ;  then compute new checksum
186E|
186E| 207C 00FC C181                MOVEA.L #PMSTRT,A0      ;compute new checksum
1874| 701E                          MOVEQ   #PMWRDS-2,D0    ;leaving out checksum word
1876| 6106                          BSR.S   WRTSUM
1878| 4CDF 0103             @2      MOVEM.L (SP)+,D0-D1/A0  ;restore regs
187C| 4E75                          RTS
187E|
187E|                       ;----------------------------------------------------------------------
187E|                       ;  Subroutine to write new checksum to parameter memory area
187E|                       ;----------------------------------------------------------------------
187E| 3200                  WRTSUM  MOVE    D0,D1           ;set for shared memory
1880| 610A                          BSR.S   VFYCHKSM
1882| 4643                          NOT     D3              ;compute 2's complement
1884| 5243                          ADDQ    #1,D3
1886| 0788 0000                     MOVEP   D3,(A0)         ;write as new checksum
188A| 4E75                          RTS
188C|
188C|                               .ENDC
188C|
188C|                       ;-------------------------------------------------------------------------
188C|                       ;  Subroutine to verify 16 bit checksum validity for memory contents.
188C|                       ;
188C|                       ;  Inputs Required:  A0 = starting address for verify
188C|                       ;                    D0 = # of words-1 to read
188C|                       ;                    D1 = 0 for regular memory (uses MOVE.W)
188C|                       ;                       = nonzero for shared memory (uses MOVEP)
188C|                       ;
188C|                       ;  Outputs:          Carry bit set if computed checksum not 0.
188C|                       ;                    D2 = expected checksum  (last word read)
188C|                       ;                    D3 = computed checksum
188C|                       ;-------------------------------------------------------------------------
188C|
188C|                       VFYCHKSM
188C| 4282                          CLR.L   D2              ;clear regs for use
188E| 4283                          CLR.L   D3
1890| 4A41                  CKLOOP  TST     D1              ;shared memory?
1892| 6708                          BEQ.S   @1              ;skip if no
1894| 0508 0000                     MOVEP   (A0),D2         ;else read alternate bytes
1898| 5888                          ADDQ.L  #4,A0           ;bump address
189A| 6002                          BRA.S   @2              ;skip to do checksum
189C| 3418                  @1      MOVE    (A0)+,D2        ;read words
189E| D642                  @2      ADD     D2,D3           ;add to computed checksum
18A0| E35B                          ROL     #1,D3           ;rotate for better effectiveness
18A2| 51C8 FFEC                     DBF     D0,CKLOOP       ;loop until done
18A6| 4A43                          TST     D3              ;expected result = 0
18A8| 6704                          BEQ.S   CKXIT
18AA| 003C 0001                     ORI.B   #$01,CCR        ;else set error indicator
18AE| 4E75                  CKXIT   RTS
18B0|
18B0|                               .IF     NEWTWIG = 0
18B0|                               .ENDC
18B0|                               .IF  USERINT = 1
18B0|                       ;-------------------------------------------------------------------------
18B0|                       ;  Subroutine to expand boot id read from parameter memory to keycode
18B0|                       ;  Returns with keycode in D0.
18B0|                       ;-------------------------------------------------------------------------
18B0|
18B0| 48E7 2030             EXPAND  MOVEM.L D2/A2-A3,-(SP)  ;save regs
18B4| 45FA F9C4                     LEA     KEYTBL,A2       ;set ptrs to keycode table
18B8| 47FA F9D1                     LEA     TBLEND,A3
18BC| 4282                          CLR.L   D2              ;use for search id
18BE| B002                  @1      CMP.B   D2,D0           ;check for match
18C0| 670C                          BEQ.S   @2              ;skip if yes
18C2| 5242                          ADDQ    #1,D2           ;incr search id
18C4| 528A                          ADDQ.L  #1,A2           ;bump table ptr
18C6| B7CA                          CMPA.L  A2,A3           ;at end?
18C8| 66F4                          BNE.S   @1              ;loop if not
18CA| 7002                          MOVEQ   #PROFILE,D0     ;else set for default boot
18CC| 6002                          BRA.S   @3              ;and go to exit
18CE| 1012                  @2      MOVE.B  (A2),D0         ;get keycode
18D0| 4CDF 0C04             @3      MOVEM.L (SP)+,D2/A2-A3  ;restore regs
18D4| 4E75                          RTS
18D6|
18D6|                       ;-------------------------------------------------------------------------
18D6|                       ;  Routine to search I/O slots for specific card
18D6|                       ;  Expects  D1 = card id to search for
18D6|                       ;           D4 = qualifier for search (mask)
18D6|                       ;  Returns  CC = 0 if card found and
18D6|                       ;           D2 = slot #
18D6|                       ;-------------------------------------------------------------------------
18D6|
18D6| 48E7 9000             SEARCH  MOVEM.L D0/D3,-(SP)     ;save regs
18DA| 7400                          MOVEQ   #0,D2           ;setup as slot counter
18DC| 7602                          MOVEQ   #2,D3           ;set # of slots - 1 to check
18DE| 41F8 0298                     LEA     IO1ID,A0        ;get location of saved slot id's
18E2| 5242                  @1      ADDQ    #1,D2           ;bump slot #
18E4| 3018                          MOVE    (A0)+,D0        ;read slot id
18E6| C044                          AND     D4,D0           ;mask it
18E8| B041                          CMP     D1,D0           ;match?
18EA| 6706                          BEQ.S   @2              ;skip if yes
18EC| 51CB FFF4                     DBF     D3,@1
18F0| 4A42                          TST     D2              ;set nonzero status if no match
18F2| 4CDF 0009             @2      MOVEM.L (SP)+,D0/D3     ;restore regs
18F6| 4E75                          RTS                     ;exit
18F8|
18F8|                               .PAGE
18F8|                       ;-------------------------------------------------------------------------
18F8|                       ;  Routines to display boot icon menu
18F8|                       ;-------------------------------------------------------------------------
18F8|
18F8|                       BOOTMENU
18F8| 0238 000F 02A2                ANDI.B  #$0F,STATFLGS   ;initialize flags
18FE| 4278 053A                     CLR     RectCnt         ;clear active rectangle counter
1902| 7C01                          MOVEQ   #1,D6           ;set min # of boot alternates           CHG009
1904|                                                       ; i.e., at least have lower drive
1904|                                                       ;  to boot from
1904| 4A38 02AF                     TST.B   SYSTYPE         ;check system type                      CHG009
1908| 6602                          BNE.S   @10             ;Skip if Lisa 2                         CHG009
190A| 5246                          ADDQ    #1,D6           ;else incr count for upper floppy drive CHG009
190C|
190C| 7401                  @10     MOVEQ   #1,D2           ;set flag to do wait if needed          RM011
190E| 6100 0126                     BSR     CHKPROFILE      ;go check for attached Profile
1912| 6602                          BNE.S   @1              ;skip if not there
1914| 5246                          ADDQ    #1,D6           ;else bump boot count
1916|
1916| 4284                  @1      CLR.L   D4              ;set flag for no status check
1918| 6100 F9EC                     BSR     RDSLOTS         ;go scan the I/O slots
191C| 41F8 0298                     LEA     IO1ID,A0        ;check results
1920| 3018                          MOVE    (A0)+,D0        ;read first ID
1922| 6A12                          BPL.S   @2              ;skip if not bootable or not there
1924| 247C 00FC 0001                MOVE.L  #SLOT1L,A2      ;set slot address
192A| 6100 026E                     BSR     RDSLT           ;go check if any icons
192E| 6506                          BCS.S   @2              ;skip if any error
1930| 0243 0003                     ANDI    #$03,D3         ;else clear don't care bits (max count = 2)
1934| DC43                          ADD     D3,D6           ;and add to icon count
1936|
1936| 3018                  @2      MOVE    (A0)+,D0        ;check slot 2
1938| 6A12                          BPL.S   @3              ;skip if not bootable
193A| 247C 00FC 4001                MOVE.L  #SLOT2L,A2      ;set slot address
1940| 6100 0258                     BSR     RDSLT           ;go check if any icons
1944| 6506                          BCS.S   @3              ;skip if any error
1946| 0243 0003                     ANDI    #$03,D3         ;else clear don't care bits (max count = 2)
194A| DC43                          ADD     D3,D6           ;and add to icon count
194C|
194C| 3018                  @3      MOVE    (A0)+,D0        ;check final slot
194E| 6A12                          BPL.S   @4
1950| 247C 00FC 8001                MOVE.L  #SLOT3L,A2      ;set slot address
1956| 6100 0242                     BSR     RDSLT           ;go check if any icons
195A| 6506                          BCS.S   @4              ;skip if any error
195C| 0243 0003                     ANDI    #$03,D3         ;else clear don't care bits (max count = 2)
1960| DC43                          ADD     D3,D6           ;and add to icon count
1962|
1962|                       ;  set starting icon display address according to boot count
1962|
1962| 0C06 000A             @4      CMP.B   #10,D6          ;max of 10 icons in menu
1966| 6F02                          BLE.S   @5              ;skip if OK
1968| 7C0A                          MOVEQ   #10,D6          ;else set max count
196A|
196A|                       ;  now display blank boot icon menu
196A| 7012                  @5      MOVEQ   #BMENUWIDTH,D0  ;set menu parameters
196C| 2206                          MOVE.L  D6,D1           ;get count of entries
196E| C2FC 0022                     MULU    #BMENULEN,D1    ;length depends on number of entries
1972| 47FA 2524                     LEA     STRTMSG,A3      ;set menu heading
1976| 6100 0E58                     BSR     DSPMENUBOX      ;and go display the menu
197A| 31FC 05A2 0530                MOVE    #MENUSTRT,MenuBase ;setup base menu address
1980| 31FC 0658 0532                MOVE    #MENU1MSG,IconAddr ;and display pt for first entry
1986|
1986|                       ;  next fill in the menu entries with icons and alternate keycodes
1986|                       ;  D0 set with system type
1986|                       ICONCHK
1986| 1038 02AF                     MOVE.B  SYSTYPE,D0      ;read system type               CHG009/CHG029
198A| 6714                          BEQ.S   @1              ;skip if Lisa 1.0               CHG009
198C| 0C00 0003                     CMP.B   #3,D0           ;else check if internal disk    CHG009/CHG029
1990| 661C                          BNE.S   @2              ;skip if not - no upper icon    CHG009/CHG029
1992|
1992| 4282                          CLR.L   D2              ;else set for no wait           CHG009
1994| 6100 00A0                     BSR     CHKPROFILE      ; and check if integral disk    CHG009
1998|                                                       ; installed                     CHG009
1998| 6614                          BNE.S   @2              ;skip if not                    CHG009
199A| 45FA 213E                     LEA     UPPER,A2        ;set icon ptr for integral disk CHG009
199E| 6006                          BRA.S   @3              ;and go display                 CHG009
19A0|
19A0| 45FA 217C             @1      LEA     DRIVEN,A2       ;set icon ptr for drive         CHG009
19A4| 7201                          MOVEQ   #1,D1           ;set drive id #                 CHG009
19A6| 7400                  @3      MOVEQ   #TWIG1,D2       ;set id code                    CHG009
19A8| 76FF                          MOVEQ   #-1,D3          ;set compressed icon indicator
19AA| 6100 00E8                     BSR     DSPMNTRY        ;display the entry
19AE|
19AE| 45FA 216E             @2      LEA     DRIVEN,A2       ;set icon ptr for drive         CHG009
19B2| 7202                          MOVEQ   #2,D1           ; and drive id #                CHG009
19B4| 7401                          MOVEQ   #TWIG2,D2       ;set id code
19B6| 76FF                          MOVEQ   #-1,D3          ;set compressed indicator
19B8| 6100 00DA                     BSR     DSPMNTRY        ;display the entry
19BC|
19BC| 4282                          CLR.L   D2              ;set flag for no wait           RM011
19BE| 0C00 0003                     CMP.B   #3,D0           ;skip check if internal disk    CHG009/CHG029
19C2| 6712                          BEQ.S   SCNSLTS         ;                               CHG009/CHG029
19C4|
19C4| 6100 0070                     BSR     CHKPROFILE      ;else check if external disk attached
19C8| 660C                          BNE.S   SCNSLTS         ;skip if not
19CA| 45FA 20D3                     LEA     PROICON,A2      ;else set icon ptr for Profile
19CE| 7402                          MOVEQ   #PROFILE,D2     ;set id code
19D0| 76FF                          MOVEQ   #-1,D3          ;set compressed indicator
19D2| 6100 00C0                     BSR     DSPMNTRY        ;display the entry
19D6|
19D6|                       ;  check for bootable devices in slots (what a pain!)
19D6|
19D6| 4280                  SCNSLTS CLR.L   D0              ;clear for use
19D8| 41F8 0298                     LEA     IO1ID,A0        ;set ptr for slot id
19DC| 3018                          MOVE    (A0)+,D0        ;get id
19DE| 6A0E                          BPL.S   CHKS2           ;skip if not bootable or not there
19E0| 247C 00FC 0001                MOVE.L  #SLOT1L,A2      ;else set slot address
19E6| 7201                          MOVEQ   #1,D1           ;set slot # for generic display if no ROM icon
19E8| 7403                          MOVEQ   #IO1PORT1,D2    ;set base boot id for slot
19EA| 6100 0158                     BSR     CHKSLOT         ;go check slot and display icons
19EE|
19EE| 3018                  CHKS2   MOVE    (A0)+,D0        ;read next id
19F0| 6A0E                          BPL.S   CHKS3           ;skip if not bootable or not there
19F2| 247C 00FC 4001                MOVE.L  #SLOT2L,A2      ;else set slot address
19F8| 7202                          MOVEQ   #2,D1           ;set slot # for generic display
19FA| 7406                          MOVEQ   #IO2PORT1,D2    ;set base boot id for slot
19FC| 6100 0146                     BSR     CHKSLOT         ;go check slot and display icons
1A00|
1A00| 3018                  CHKS3   MOVE    (A0)+,D0        ;read slot 3 id
1A02| 6A10                          BPL.S   WT4BOOT         ;skip if not bootable or not there
1A04| 247C 00FC 8001                MOVE.L  #SLOT3L,A2      ;else set slot address
1A0A| 7203                          MOVEQ   #3,D1           ;set slot # for generic display
1A0C| 343C 0009                     MOVE    #IO3PORT1,D2    ;set base boot id for slot
1A10| 6100 0132                     BSR     CHKSLOT         ;go check slot 3 and display icons
1A14|
1A14|                       ;---------------------------------------------------------------------------
1A14|                       ;  Menu displayed - now wait for operator selection
1A14|                       ;---------------------------------------------------------------------------
1A14|                       WT4BOOT
1A14| 6100 15F8                     BSR     CursorDisplay    ;display cursor on screen
1A18| 08F8 0005 02A2                BSET    #CHKCMD,STATFLGS ;set flag for CMD key check
1A1E| 6100 1226                     BSR     GETINPUT        ;go wait for user input
1A22| 6500 0CC2                     BCS     GETERR          ;skip if error
1A26| 6100 F836                     BSR     XLATE           ;translate and save boot id
1A2A| 6100 15BE                     BSR     CursorHide      ;remove cursor from screen
1A2E| 6100 16AA                     BSR     CLRDESK         ;clear desktop
1A32| 6000 FCB2                     BRA     BOOTCHK         ;and go start boot
1A36|
1A36|                               .PAGE
1A36|                       ;---------------------------------------------------------------------------
1A36|                       ;  Routine to check for Profile attached to built-in parallel port.
1A36|                       ;  Checks for Profile connected (OCD) and tries an initial handshake to
1A36|                       ;  ensure the device is a Profile.
1A36|                       ;
1A36|                       ;  Inputs: D2 = nonzero if full wait for Profile ready should be done
1A36|                       ;  Outputs: Zero condition code bit cleared if error
1A36|                       ;---------------------------------------------------------------------------
1A36|
1A36|                       CHKPROFILE
1A36| 48E7 AA80                     MOVEM.L A0/D0/D2/D4/D6,-(SP)    ;save regs                              RM011
1A3A| 6100 05B4                     BSR     PROINIT                 ;init for Profile access
1A3E| 664E                          BNE.S   @9                      ;skip if not attached
1A40|
1A40| 6100 06F0                     BSR     WFNBSY3                 ;wait for not busy                      RM000
1A44| 4A00                          TST.B   D0                      ;check return code
1A46| 671E                          BEQ.S   @0                      ;skip if OK
1A48| 4A02                          TST.B   D2                      ;do full wait?                          RM011
1A4A| 6740                          BEQ.S   @7                      ;skip if not                            RM011
1A4C|
1A4C| 4280                          CLR.L   D0                      ;else reset error code for retry
1A4E| 6100 0456                     BSR     WAITALRT                ;output wait alert
1A52| 6100 06D6                     BSR     WFNBSY2                 ;try wait for normal profile boot time  CHG019
1A56| 48E7 8080                     MOVEM.L A0/D0,-(SP)             ;save regs
1A5A| 6100 167E                     BSR     CLRDESK                 ;clear desktop
1A5E| 4CDF 0101                     MOVEM.L (SP)+,A0/D0             ;restore regs
1A62| 4A00                          TST.B   D0
1A64| 661E                          BNE.S   @8                      ;exit if still not ready
1A66|
1A66| 0210 00EF             @0      ANDI.B  #$EF,ORB2(A0)           ;set command = true
1A6A| 6100 0690                     BSR     WFBSY                   ;then get initial Profile response      RM016
1A6E| 660A                          BNE.S   @1                      ;skip if error
1A70|
1A70| 0C28 0001 0078                CMPI.B  #1,PORTA2(A0)           ;check for expected '01' response
1A76| 6702                          BEQ.S   @1                      ;skip if OK
1A78| 7052                          MOVEQ   #BADRSP,D0              ;else set error code
1A7A|
1A7A| 7600                  @1      MOVEQ   #0,D3                   ;send '0' response to reset Profile
1A7C| 6100 0690                     BSR     SENDRSP
1A80| 6100 06A0                     BSR     WFNBSY                  ;wait until command taken
1A84|
1A84| 4228 0018             @8      CLR.B   DDRA2(A0)               ;set port A bits to input
1A88| 0010 0018                     ORI.B   #$18,ORB2(A0)           ;and set dir=in, cmd=false
1A8C|
1A8C| 4A40                  @7      TST     D0                      ;set return code
1A8E|
1A8E| 4CDF 0155             @9      MOVEM.L (SP)+,A0/D0/D2/D4/D6    ;restore                                RM011
1A92| 4E75                          RTS                             ; and exit
1A94|
1A94|                       ;---------------------------------------------------------------------------
1A94|                       ;  Subroutine to invoke display of boot menu entry
1A94|                       ;  Inputs:
1A94|                       ;       D2 = boot id
1A94|                       ;       A2 = ptr to icon
1A94|                       ;  Outputs:
1A94|                       ;       Location MenuBase updated with address for next menu "box"
1A94|                       ;  Side Effects:
1A94|                       ;       None
1A94|                       ;---------------------------------------------------------------------------
1A94|
1A94|                       DSPMNTRY
1A94| 48E7 8040                     MOVEM.L D0/A1,-(SP)     ;save boot id and addr ptr
1A98| 3002                          MOVE    D2,D0           ;get boot id
1A9A| 6100 FE14                     BSR     EXPAND          ;go convert boot id to keycode
1A9E| 3278 0530                     MOVE    MenuBase,A1     ;get address for display of entry
1AA2| 6106                          BSR.S   ICONMENU        ;go display in menu
1AA4| 4CDF 0201                     MOVEM.L (SP)+,D0/A1     ;restore boot id and addr ptr
1AA8| 4E75                          RTS                     ;and exit
1AAA|
1AAA|                       ;----------------------------------------------------------------------------
1AAA|                       ;  Subroutine to display icon menu on screen.  Creates "active rectangle
1AAA|                       ;  table" as entries are made.
1AAA|                       ;  Inputs:
1AAA|                       ;       D0 = alternate keycode
1AAA|                       ;       D3 = compressed icon indicator
1AAA|                       ;       A1 = address for start of next menu "box"
1AAA|                       ;       A2 = ptr to icon
1AAA|                       ;  Outputs:
1AAA|                       ;       A1 = ptr for display of next menu entry
1AAA|                       ;  Side Effects:
1AAA|                       ;       None
1AAA|                       ;----------------------------------------------------------------------------
1AAA|
1AAA|                       ICONMENU
1AAA| 48E7 F8A4                     MOVEM.L D0-D4/A0/A2/A5,-(SP)
1AAE|
1AAE|                       ;  first save icon coordinates in active rectangle table
1AAE|
1AAE| 41F8 053A                     LEA     RectTable,A0    ;get ptr to active rect table
1AB2| 3410                          MOVE    (A0),D2         ;get current count of rect's
1AB4| C4FC 0005                     MULU    #5,D2           ;five entries per rect
1AB8| D442                          ADD     D2,D2           ;double for word index
1ABA| 5258                          ADDQ    #1,(A0)+        ;incr for new rect
1ABC| 3180 2000                     MOVE    D0,0(A0,D2.W)   ;save keycode id for new rect
1AC0| 6100 0C58                     BSR     KeyToAscii      ;convert keycode to Ascii
1AC4| 3800                          MOVE    D0,D4           ;save for later display
1AC6|
1AC6|                       ;  compute X,Y pixel coordinates from starting address
1AC6|
1AC6| 6100 193E                     BSR     GETROWCOL       ;get pixel row, byte col
1ACA| CCFC 0008                     MULU    #8,D6           ;convert to pixel col
1ACE| 3186 2002                     MOVE    D6,2(A0,D2.W)   ;save upper left X
1AD2| 3185 2004                     MOVE    D5,4(A0,D2.W)   ; and Y coordinates
1AD6|
1AD6| 303C 0090                     MOVE    #,D0 ;width in pixels of menu entry
1ADA| DC40                          ADD     D0,D6             ;compute and save
1ADC| 3186 2006                     MOVE    D6,6(A0,D2.W)     ; lower Y coordinate
1AE0| 0645 0022                     ADD     #,D5  ;compute and save
1AE4| 3185 2008                     MOVE    D5,8(A0,D2.W)     ; lower X coordinate
1AE8|
1AE8|                       ;  now do icon display
1AE8|
1AE8| 9DCE                          SUBA.L  A6,A6           ;clear for use
1AEA| 3C78 0532                     MOVE    IconAddr,A6     ;get address for icon display
1AEE| 224E                          MOVE.L  A6,A1           ;save for later use
1AF0| DDF8 0110                     ADD.L   SCRNBASE,A6     ;convert to screen address
1AF4| 4A03                          TST.B   D3              ;check for compressed icon
1AF6| 6A14                          BPL.S   @1              ;skip if not
1AF8| 6100 1AE8                     BSR     DSPICON         ;go do display
1AFC|
1AFC| 41FA 2020                     LEA     DRIVEN,A0       ;displaying drive?                      CHG009
1B00| B5C8                          CMPA.L  A0,A2           ;                                       CHG009
1B02| 660C                          BNE.S   @2              ;skip if not                            CHG009
1B04| 2A49                          MOVE.L  A1,A5           ;else set icon display address          CHG009
1B06| 6100 195C                     BSR     DSPNUM          ; and display with id #                 CHG009
1B0A| 6004                          BRA.S   @2              ;skip to continue                       CHG009
1B0C|
1B0C| 6100 1916             @1      BSR     DSPRGICON       ;display an uncompressed icon           CHG008
1B10|
1B10|                       ;  now display the alternate keycode
1B10|
1B10| D2FC 0445             @2      ADD     #ALTKYADDR,A1   ;set starting display pt
1B14| 6100 18F0                     BSR     GETROWCOL       ;convert to row, col
1B18| 4240                          CLR     D0              ;first display the apple
1B1A| 6100 1C1E                     BSR     DSPVAL
1B1E| 3004                          MOVE    D4,D0           ;get Ascii char
1B20| 6100 1C18                     BSR     DSPVAL          ;and display it
1B24|
1B24|                       ;  finally compute the next menu entry and icon display address
1B24|
1B24| 3278 0530             @3      MOVE    MenuBase,A1     ;get base address for the entry
1B28| D2FC 0BF4                     ADD     #BMenuSpc,A1    ;space to next col
1B2C| 31C9 0530                     MOVE    A1,MenuBase     ;and save for next entry
1B30|
1B30| 3278 0532                     MOVE    IconAddr,A1     ;else get this icon's address
1B34| D2FC 0BF4                     ADD     #BMenuspc,A1    ;and bump to next spot in column
1B38| 31C9 0532                     MOVE    A1,IconAddr     ;and do update
1B3C| 6000                          BRA.S   @4
1B3E|
1B3E| 4CDF 251F             @4      MOVEM.L (SP)+,D0-D4/A0/A2/A5
1B42| 4E75                          RTS
1B44|                       ;---------------------------------------------------------------------------
1B44|                       ;  Routine to check slots for icons and do display or do generic display.
1B44|                       ;  Inputs:
1B44|                       ;       D0 = card id
1B44|                       ;       D1 = slot #
1B44|                       ;       D2 = first boot id for slot
1B44|                       ;       A1 = address for icon display
1B44|                       ;       A2 = slot address
1B44|                       ;  Outputs:
1B44|                       ;       Returns with carry bit set if error.
1B44|                       ;  Side Effects:
1B44|                       ;       None
1B44|                       ;---------------------------------------------------------------------------
1B44|
1B44| 48E7 F8E0             CHKSLOT MOVEM.L D0-D4/A0-A2,-(SP) ;save regs
1B48| 0800 000D                     BTST    #ICBIT,D0       ;icon available?
1B4C| 661A                          BNE.S   CHKICONS        ;skip if yes
1B4E|
1B4E|                       ;  no icons available - display slot # and display generic slot card icon
1B4E| 45FA 1EC4                     LEA     XCARD,A2        ;point to generic icon
1B52| 76FF                          MOVEQ   #-1,D3          ;set compressed flag
1B54| 3278 0532                     MOVE    IconAddr,A1     ;get display address for later use
1B58| 6100 FF3A                     BSR     DSPMNTRY        ;go display entry
1B5C| 45FA 1EB6                     LEA     XCARD,A2        ;set icon ptr
1B60| 2A49                          MOVE.L  A1,A5           ;get icon address
1B62| 6100 1900                     BSR     DSPNUM          ;display slot #
1B66| 602C                          BRA.S   CHKSXIT         ;and exit
1B68|
1B68|                       ;  Slot has icon - read ROM and get ptr to desired icon
1B68|
1B68|                       CHKICONS
1B68| 6130                          BSR.S   RDSLT           ;go read slot
1B6A| 6528                          BCS.S   CHKSXIT         ;exit if error
1B6C| 227C 0001 FFFC                MOVE.L  #ADR128K-4,A1   ;set base address of I/O slot ROM code
1B72| 2803                          MOVE.L  D3,D4           ;save icon count
1B74| 0244 0003                     ANDI    #$03,D4         ;isolate count (max = 2)
1B78| 204A                          MOVE.L  A2,A0           ;get code ptr
1B7A| 3218                          MOVE    (A0)+,D1        ;get icon offset
1B7C| 2449                          MOVE.L  A1,A2           ;get base address
1B7E| D4C1                          ADD     D1,A2           ;add offset to set up icon ptr
1B80| 6100 FF12                     BSR     DSPMNTRY        ;display as menu entry
1B84|
1B84| 5344                          SUBQ    #1,D4           ;more than one icon?
1B86| 670C                          BEQ.S   CHKSXIT         ;skip if not
1B88| 3218                          MOVE    (A0)+,D1        ;else get ptr to second icon
1B8A| 5242                          ADDQ    #1,D2           ;bump boot id ptr for slot
1B8C| 2449                          MOVE.L  A1,A2           ;restore base address
1B8E| D4C1                          ADD     D1,A2           ;set up icon address
1B90| 6100 FF02                     BSR     DSPMNTRY        ;display as menu entry
1B94|
1B94| 4CDF 071F             CHKSXIT MOVEM.L (SP)+,D0-D4/A0-A2 ;restore regs and exit
1B98| 4E75                          RTS
1B9A|
1B9A|                       ;---------------------------------------------------------------------
1B9A|                       ;  Routine to read I/O slot ROM's and get icon count if any.
1B9A|                       ;
1B9A|                       ;  Expects D0 = boot id
1B9A|                       ;          A2 = slot address
1B9A|                       ;
1B9A|                       ;  Returns D3 = icon count
1B9A|                       ;          A2 = address of ptr to first icon if more than one
1B9A|                       ;---------------------------------------------------------------------
1B9A|
1B9A| 48E7 A000             RDSLT   MOVEM.L D0/D2,-(SP)     ;save boot id's
1B9E| 0800 000D                     BTST    #ICBIT,D0       ;any icons stored in ROM?
1BA2| 6720                          BEQ.S   @2              ;skip if none
1BA4| 4284                          CLR.L   D4              ;set flag for no status check
1BA6| 6100 0624                     BSR     RDIOSLT         ;and go read ROM on slot
1BAA| 651A                          BCS.S   @1              ;skip if error
1BAC|
1BAC| 4283                          CLR.L   D3              ;clear for use
1BAE| 3639 0002 0004                MOVE    ICONPTR,D3      ;get icon ptr
1BB4| 08C3 0000                     BSET    #0,D3           ;must be odd address
1BB8| 247C 0001 FFFC                MOVE.L  #ADR128K-4,A2   ;set base address
1BBE| D5C3                          ADD.L   D3,A2           ;set actual address
1BC0| 161A                          MOVE.B  (A2)+,D3        ;read icon count
1BC2| 6002                          BRA.S   @1
1BC4|
1BC4| 7601                  @2      MOVEQ   #1,D3           ;set default icon count
1BC6|
1BC6| 4CDF 0005             @1      MOVEM.L (SP)+,D0/D2     ;restore boot id's
1BCA| 4E75                          RTS
1BCC|                               .ENDC                   ;{USERINT}
1BCC|                               .PAGE
1BCC|                       ;-------------------------------------------------------------------------
1BCC|                       ;  Do default boot from Twiggy specified drive.
1BCC|                       ;  Assumes regs:
1BCC|                       ;       D0 = drive #
1BCC|                       ;  Following assumptions are made for power-up status:
1BCC|                       ;    1) No interrupt from disk unless diskette inserted or button pushed
1BCC|                       ;-------------------------------------------------------------------------
1BCC|
1BCC| 47FA F5B8             TWGBOOT LEA     DSKVCT,A3       ; first set up bus error vector
1BD0| 21CB 0008                     MOVE.L  A3,BUSVCTR
1BD4|
1BD4|                               .IF  USERINT = 0
1BD4|                               .ELSE
1BD4| 11C0 0535                     MOVE.B  D0,DRIVE        ;save drive id
1BD8| 6100 02CC                     BSR     WAITALRT        ;display wait icon
1BDC|                               .ENDC
1BDC|
1BDC| 207C 00FC C001                MOVE.L  #DISKMEM,A0     ; set ptr to controller memory
1BE2| 227C 0001 FFF4                MOVE.L  #TWGHDR,A1      ; set ptr to load header
1BE8| 247C 0002 0000                MOVE.L  #TWGHDR+12,A2   ; and ptr to load data
1BEE| 4281                          CLR.L   D1              ; set drive/side/sector/track ptr
1BF0| 0280 0000 00FF                ANDI.L  #$00FF,D0       ; mask off junk
1BF6|
1BF6| 4A40                          TST     D0              ;enable only drive selected
1BF8| 6608                          BNE.S   @1
1BFA| 117C 0008 0002                MOVE.B  #$08,CMD(A0)    ;enable drive #1
1C00| 6006                          BRA.S   @2
1C02| 117C 0080 0002        @1      MOVE.B  #$80,CMD(A0)    ;enable drive #2
1C08|
1C08| E098                  @2      ROR.L   #8,D0           ; get actual drive desired
1C0A| 8280                          OR.L    D0,D1           ; and save for shared mem format
1C0C|
1C0C| 10BC 0086                     MOVE.B  #ENBLINT,(A0)   ;go do enable
1C10| 6100 01F2                     BSR     CMDCHK          ;wait until cmd taken
1C14| 6500 0082                     BCS     DSKTIMERR       ;skip if timeout error
1C18| 267C 00FC DD81                MOVE.L  #VIA1BASE,A3    ;else enable
1C1E| 08AB 0004 0004                BCLR    #FDIR,DDRB1(A3) ; FDIR
1C24|
1C24|                       ;        BTST    #FDIR,(A3)      ;FDIR present?
1C24|                       ;        BEQ.S   DOREAD          ;skip if no to do read
1C24|
1C24| 6100 024C             CLRINT  BSR     CLRFDIR         ;clear interrupts
1C28| 6500 006E                     BCS     DSKTIMERR       ;exit if timeout error
1C2C|
1C2C|                               .PAGE
1C2C|                       ;-----------------------------------------------------------------------------
1C2C|                       ;  Read boot data - retry on sector 0 if needed.
1C2C|                       ;-----------------------------------------------------------------------------
1C2C|
1C2C|                       DOREAD
1C2C| 4240                          CLR     D0              ; set speed value
1C2E| 6100 0140                     BSR     TWGRD           ; go read sector 0                      RM000
1C32| 640A                          BCC.S   @1              ; skip if OK
1C34| 0C00 0027                     CMP.B   #TIMOUT,D0      ; timeout error?
1C38| 6700 0060                     BEQ     DSKCHK          ; exit if yes
1C3C| 600A                          BRA.S   RDRETRY         ; else go do retry
1C3E|
1C3E| 3029 0004             @1      MOVE    FILEID(A1),D0   ; else get file ID
1C42| 0C40 AAAA                     CMP     #BOOTPAT,D0     ; is it a boot file?
1C46| 6724                          BEQ.S   RDSCTR1         ; skip if yes
1C48|
1C48|                       ;  Do retry by reading track 1 to try to get head properly aligned, then
1C48|                       ;  retry reading track 0
1C48| 123C 0001             RDRETRY MOVE.B  #1,D1           ; set for track 1
1C4C| 4240                          CLR     D0              ; set speed value
1C4E| 6100 0120                     BSR     TWGRD           ; go do read                            RM000
1C52| 6546                          BCS.S   DSKCHK          ; exit if second error
1C54| 4201                          CLR.B   D1              ; else retry track 0
1C56| 4240                          CLR     D0              ; set speed value
1C58| 6100 0116                     BSR     TWGRD           ; go do read                            RM000
1C5C| 653C                          BCS.S   DSKCHK          ; exit if error
1C5E|
1C5E|                       ;  Now check again for a valid boot track
1C5E| 3029 0004                     MOVE    FILEID(A1),D0   ; get file ID
1C62| 0C40 AAAA                     CMP     #BOOTPAT,D0     ; is it a boot file?
1C66| 6704                          BEQ.S   RDSCTR1         ; skip if yes
1C68| 7026                          MOVEQ   #BADTHDR,D0     ; set error code
1C6A| 602E                          BRA.S   DSKCHK          ; and exit
1C6C|
1C6C|                       RDSCTR1
1C6C|                               .IF  NEWTWIG = 0
1C6C|                               .ENDC
1C6C|
1C6C| 42B8 01B4                     CLR.L   BOOTDATA        ;set for no error
1C70| 47FA 009C                     LEA     DSKERR2,A3      ;set up vectors in case of bad diskette
1C74| 49FA 009E                     LEA     DSKERR3,A4
1C78| 6100 0236                     BSR     VCTRINIT
1C7C| 247C 0002 0000                MOVE.L  #TWGDATA,A2     ;set data ptr (software view)
1C82|
1C82|                       ;  Do keyboard/mouse reset before continuing boot process
1C82|
1C82|                       STRTBOOT
1C82| 48E7 8080                     MOVEM.L A0/D0,-(SP)     ;save regs
1C86| 6100 EE22                     BSR     RSTKBD          ;send reset signal
1C8A| 6100 EE38                     BSR     CLRRST          ;then clear it
1C8E| 4238 02B0                     CLR.B   KBDQ            ;clear first byte of keyboard queue
1C92| 4CDF 0101                     MOVEM.L (SP)+,A0/D0     ;restore regs
1C96| 4ED2                          JMP     (A2)            ;and away we go ...
1C98|
1C98|                               .PAGE
1C98|                       ;-------------------------------------------------------------------------
1C98|                       ;  Error occurred - output error message and go to monitor
1C98|                       ;-------------------------------------------------------------------------
1C98|
1C98|                       DSKTIMERR
1C98| 7027                          MOVEQ   #TIMOUT,D0      ;set timeout error code
1C9A| 11C0 01B4             DSKCHK  MOVE.B  D0,BOOTDATA     ;save the error status
1C9E| 0C00 0027                     CMPI.B  #TIMOUT,D0      ;timeout?
1CA2| 6720                          BEQ.S   DSKERR          ;skip if yes
1CA4| 6100 01CC                     BSR     CLRFDIR         ;ensure intrpt cleared
1CA8| 6512                          BCS.S   DSKOUT          ;exit if error
1CAA|
1CAA|                               .IF  USERINT = 0
1CAA|                               .ENDC
1CAA|
1CAA| 11E8 00BA 01B6        DSKBAD  MOVE.B  CHKCNT(A0),BOOTDATA+2  ; and data checksum count
1CB0|
1CB0|                               .IF  NEWTWIG = 1
1CB0| 11E8 00C4 01B5                MOVE.B  CHKCNT2(A0),BOOTDATA+1 ; and address checksum count
1CB6| 11E8 0058 01B7                MOVE.B  RTRYCNT(A0),BOOTDATA+3 ; and retry count
1CBC|                               .ENDC
1CBC|
1CBC| 6100 0198             DSKOUT  BSR     EJCTDSK         ;then eject the disk
1CC0|
1CC0| 6100 0084             DSKDIS  BSR     DSABLDSK        ;disable both drives
1CC4|
1CC4| 6100 EA1C             DSKERR  BSR     SETBUSVCT       ; restore default bus error vector      RM000
1CC8|
1CC8|                               .IF  USERINT = 0
1CC8|                               .ELSE
1CC8| 6100 0092                     BSR     CHKDRIVE        ;go determine drive
1CCC| 1038 01B4                     MOVE.B  BOOTDATA,D0     ;get error code
1CD0| 0C00 0007                     CMP.B   #NODISK,D0      ;no disk error?
1CD4| 6614                          BNE.S   @1              ;skip if not
1CD6|
1CD6|                                                       ;2 statements deleted                   CHG009
1CD6|
1CD6| 45FA 1E7E                     LEA     INSERTD,A2      ;set icon for insert rqst               CHG009
1CDA| 6100 1850                     BSR     DSPALRTICON     ;display basic icon                     CHG009
1CDE| 3A7C 287E                     MOVE    #ERRSTRT,A5     ;set display pt for id #                CHG009
1CE2| 6100 1780                     BSR     DSPNUM          ; and display it                        CHG009
1CE6| 6000 0256                     BRA     BFAIL2          ;then go signal user
1CEA|
1CEA| 0C00 0017             @1      CMP.B   #RDWRERR,D0     ;read error?
1CEE| 670C                          BEQ.S   @2              ;skip if yes
1CF0| 0C00 0026                     CMP.B   #BADTHDR,D0     ;bad file id?
1CF4| 6706                          BEQ.S   @2
1CF6| 0C00 004B                     CMP.B   #EBOOT,D0       ;boot error?
1CFA| 6606                          BNE.S   @3              ;skip if not
1CFC|
1CFC| 6100 1752             @2      BSR     DSPNUMICON      ;display diskette icon with id #
1D00| 6008                          BRA.S   TBOOTERR        ;and exit
1D02|
1D02| 45FA 1C47             @3      LEA     IOBRD,A2        ;error must be on I/O board
1D06| 6100 17D2                     BSR     DSPERRICON      ;display icon
1D0A|                               .ENDC
1D0A|
1D0A|                       TBOOTERR
1D0A|                               .IF  USERINT = 0
1D0A|                               .ELSE
1D0A| 6000 022E                     BRA     BOOTFAIL        ;and go signal boot failure
1D0E|                               .ENDC
1D0E|
1D0E|                       ;--------------------------------------------------------------------------
1D0E|                       ;  Handler for Twiggy boot errors
1D0E|                       ;--------------------------------------------------------------------------
1D0E|                       DSKERR2 BSRS4   SAVEXCP         ;go save exception info
1D0E| 49FA 0004            #          LEA      @1,A4
1D12| 6008                 #          BRA.S    SAVEXCP
1D14|                      #@1
1D14|
1D14|                       DSKERR3 BSRS4   BTERR           ;regroup
1D14| 49FA 0004            #          LEA      @1,A4
1D18| 6010                 #          BRA.S    BTERR
1D1A|                      #@1
1D1A| 60A0                          BRA.S   DSKOUT          ;and display error
1D1C|
1D1C|                       SAVEXCP
1D1C| 31DF 0280                     MOVE    (SP)+,EXCFC     ;save function code
1D20| 21DF 0282                     MOVE.L  (SP)+,EXCADR    ;and address
1D24| 31DF 0286                     MOVE    (SP)+,EXCIR     ;and instruction reg
1D28|                               RTS4
1D28| 4ED4                 #          JMP      (A4)
1D2A|
1D2A| 31DF 0288             BTERR   MOVE    (SP)+,EXCSR     ;save status reg
1D2E| 21DF 028A                     MOVE.L  (SP)+,EXCPC     ;and pc
1D32| 6100 E306                     BSR     SAVEREGS        ;save regs
1D36| 3E7C 0480                     MOVEA   #STKBASE,SP     ;reset stack pointer
1D3A| 6100 E970                     BSR     SETVCTRS        ;reinit vectors
1D3E| 704B                          MOVEQ   #EBOOT,D0       ;set boot error
1D40| 11C0 01B4                     MOVE.B  D0,BOOTDATA     ;and save
1D44|                               RTS4
1D44| 4ED4                 #          JMP      (A4)
1D46|
1D46|                       ;---------------------------------------------------------------------------
1D46|                       ;  Subroutine to disable interrupts from both Twiggy drives
1D46|                       ;  Inputs:
1D46|                       ;       None
1D46|                       ;  Outputs:
1D46|                       ;       Carry bit set if timeout error (in CMDCHK).
1D46|                       ;  Side Effects:
1D46|                       ;       A0 trashed (other regs trashed in CMDCHK)
1D46|                       ;---------------------------------------------------------------------------
1D46|
1D46|                       DSABLDSK
1D46| 207C 00FC C001                MOVE.L  #DISKMEM,A0     ;set ptr to shared memory
1D4C| 117C 0088 0002                MOVE.B  #$88,CMD(A0)    ;disable ints from both drives
1D52| 10BC 0087                     MOVE.B  #DSABLINT,(A0)
1D56| 6100 00AC                     BSR     CMDCHK          ;wait for command to be taken
1D5A| 4E75                          RTS                     ;then return
1D5C|
1D5C|                       ;--------------------------------------------------------------------------
1D5C|                       ;  Subroutine to determine drive # in error and get icon ptr
1D5C|                       ;  Inputs:
1D5C|                       ;       Location DRIVE = drive id # (0 or $80)
1D5C|                       ;  Outputs:
1D5C|                       ;       A2 = ptr to diskette icon
1D5C|                       ;       D1 = id #
1D5C|                       ;  Side Effects:
1D5C|                       ;       None
1D5C|                       ;--------------------------------------------------------------------------
1D5C|
1D5C|                       CHKDRIVE
1D5C| 45FA 1FC0                     LEA     DISKETTE,A2     ;set ptr for diskette icon
1D60| 1238 0535                     MOVE.B  DRIVE,D1        ;get drive id
1D64| 4A01                          TST.B   D1              ; drive #1?
1D66| 6604                          BNE.S   @1              ; skip if no
1D68|
1D68|                               .IF  USERINT = 0
1D68|                               .ELSE
1D68| 7201                          MOVEQ   #1,D1           ; else set up id code
1D6A|                               .ENDC
1D6A|
1D6A| 6002                          BRA.S   @2
1D6C|                       @1
1D6C|                               .IF  USERINT = 0
1D6C|                               .ELSE
1D6C| 7202                          MOVEQ   #2,D1           ; else set up id code
1D6E|                               .ENDC
1D6E|                       @2
1D6E| 4E75                          RTS                     ;exit
1D70|
1D70|
1D70|                               .IF     EXTERNAL = 1
1D70|                               .ENDC
1D70|                               .PAGE
1D70|                       ;-----------------------------------------------------------------------------
1D70|                       ;  Read a Twiggy sector routine.  Uses hardware view of the world, with
1D70|                       ;  12 bytes for header and 256 bytes (512 for new format) of data per sector.
1D70|                       ;  Also assumes registers:
1D70|                       ;    D0 = speed (for new Twiggy code)   A0 = disk shared memory address
1D70|                       ;    D1 = drive/side/sector/track       A1 = address to load header(12 bytes)
1D70|                       ;    D2 = timeout for read              A2 = address to load data(256 or 512 bytes)
1D70|                       ;    D3 = scratch                       A3 = VIA address for FDIR
1D70|                       ;  If error, returns with carry bit set and error code in D0.
1D70|                       ;------------------------------------------------------------------------------
1D70|
1D70|                       TWGRD
1D70| 243C 00C0 0000                MOVE.L  #FDIRTIME,D2    ; set default timeout value             RM000
1D76|
1D76|                       TWGREAD
1D76|                               .IF TWIGGY = 1
1D76| 48E7 1078                     MOVEM.L D3/A1-A4,-(SP)  ; save regs
1D7A|                               DISABLE                 ; disable interrupts
1D7A| 40E7                 #          MOVE     SR,-(SP)
1D7C| 007C 0700            #          ORI      #$0700,SR
1D80| 6100 0114                     BSR     CHKFDIR         ;ensure no ints pending
1D84| 03C8 0004                     MOVEP.L D1,DRV(A0)      ; set disk ptrs
1D88|                               .IF     NEWTWIG = 1
1D88| 1140 000C                     MOVE.B  D0,SPEED(A0)    ;set speed value
1D8C|                               .ENDC
1D8C| 4228 0002                     MOVE.B  #READS,CMD(A0)  ; set for read operation
1D90| 10BC 0081                     MOVE.B  #EXRW,(A0)      ; and go do it
1D94| 6100 00A8                     BSR     CHKFIN          ; wait
1D98| 6556                          BCS.S   TWGOUT          ; exit if timeout
1D9A| 1028 0010                     MOVE.B  STAT(A0),D0     ; get disk return code
1D9E| 117C 00CC 0002                MOVE.B  #$CC,CMD(A0)    ;clear RWTS interrupt bits
1DA4| 10BC 0085                     MOVE.B  #CLRSTAT,(A0)
1DA8| 615A                          BSR.S   CMDCHK          ;wait until cmd taken
1DAA| 6544                          BCS.S   TWGOUT          ;exit if error
1DAC| 4A00                          TST.B   D0              ;check status code
1DAE| 6642                          BNE.S   TWGERR          ; and exit if error
1DB0|
1DB0|                       ;  Read successful - transfer header and then data to main memory
1DB0|
1DB0|                               .IF  NEWTWIG = 0
1DB0|                               .ELSE
1DB0| 49E8 03E8                     LEA     DSKBUFF(A0),A4  ;set address for Twiggy buffer
1DB4| 074C 0000             XFRHDR  MOVEP.L (A4),D3         ;load header bytes
1DB8| 22C3                          MOVE.L  D3,(A1)+
1DBA| 074C 0008                     MOVEP.L 8(A4),D3
1DBE| 22C3                          MOVE.L  D3,(A1)+
1DC0| 074C 0010                     MOVEP.L 16(A4),D3
1DC4| 22C3                          MOVE.L  D3,(A1)+
1DC6|
1DC6| 49E8 0400                     LEA     DSKDATA(A0),A4  ;set address for data
1DCA| 303C 001F                     MOVE.W  #31,D0          ;need to load 512 bytes
1DCE| 074C 0000             XFRDATA MOVEP.L (A4),D3         ;load data bytes
1DD2| 24C3                          MOVE.L  D3,(A2)+
1DD4| 074C 0008                     MOVEP.L 8(A4),D3
1DD8| 24C3                          MOVE.L  D3,(A2)+
1DDA| 074C 0010                     MOVEP.L 16(A4),D3
1DDE| 24C3                          MOVE.L  D3,(A2)+
1DE0| 074C 0018                     MOVEP.L 24(A4),D3
1DE4| 24C3                          MOVE.L  D3,(A2)+
1DE6| D8FC 0020                     ADD.W   #32,A4
1DEA| 51C8 FFE2                     DBF     D0,XFRDATA      ;loop until done
1DEE| 600A                          BRA.S   TWGOK           ;and go to exit
1DF0|
1DF0|                               .ENDC
1DF0|
1DF0|                       ;  Error exit - set carry bit as error indicator
1DF0|
1DF0| 7027                  TWGOUT  MOVEQ   #TIMOUT,D0      ; set timeout error
1DF2|                       TWGERR  ENABLE                  ; restore interrupt mask
1DF2| 46DF                 #          MOVE     (SP)+,SR
1DF4| 003C 0001                     ORI.B   #$01,CCR
1DF8| 6004                          BRA.S   TWGRXIT         ; and exit
1DFA|
1DFA|                       TWGOK   ENABLE                  ; restore interrupt mask
1DFA| 46DF                 #          MOVE     (SP)+,SR
1DFC| 4280                          CLR.L   D0              ; set OK return code            CHG025
1DFE|
1DFE| 4CDF 1E08             TWGRXIT MOVEM.L (SP)+,D3/A1-A4  ; restore regs
1E02| 4E75                          RTS                     ; and return to caller
1E04|
1E04|                       ;-------------------------------------------------------------------------
1E04|                       ;  Subroutine to check for disk command taken. Also does check for DSKDIAG
1E04|                       ;  in case Twiggy controller becomes busy servicing second disk drive before
1E04|                       ;  command is seen.  Loop takes about 12.4 us if DSKDIAG OK, else DSKDIAG
1E04|                       ;  loop takes about 9.6 us.
1E04|                       ;
1E04|                       ;  Destroys register A0
1E04|                       ;-------------------------------------------------------------------------
1E04|
1E04| 48E7 1010             CMDCHK  MOVEM.L D3/A3,-(SP)     ;save regs
1E08| 263C 0012 0000                MOVE.L  #CMDTIME,D3     ;set timeout for about 15 secs
1E0E| 207C 00FC C001                MOVE.L  #DISKMEM,A0     ;set ptr to shared memory
1E14| 267C 00FC D901                MOVE.L  #VIA2BASE,A3    ;also set up to monitor DSKDIAG
1E1A| 022B 00BF 0010                ANDI.B  #$BF,DDRB2(A3)
1E20| 4A10                  @1      TST.B   (A0)            ;cmd taken when byte 0'ed
1E22| 6714                          BEQ.S   @2
1E24| 0813 0006             @3      BTST    #DSKDIAG,IRB2(A3) ;check if controller not ready
1E28| 6606                          BNE.S   @4              ;skip if OK
1E2A| 5383                          SUBQ.L  #1,D3           ;else loop until timeout or ready
1E2C| 66F6                          BNE.S   @3
1E2E| 6004                          BRA.S   @5              ;take error exit
1E30| 5383                  @4      SUBQ.L  #1,D3
1E32| 66EC                          BNE.S   @1              ;loop until yes or timeout
1E34| 003C 0001             @5      ORI.B   #$01,CCR        ;set error
1E38| 4CDF 0808             @2      MOVEM.L (SP)+,D3/A3     ;restore regs
1E3C| 4E75                          RTS
1E3E|
1E3E|                       ;----------------------------------------------------------------------------
1E3E|                       ;  Subroutine to check for disk interrupt (FDIR asserted) - loop takes 8.8us
1E3E|                       ;  Destroys register D3 and A3
1E3E|                       ;----------------------------------------------------------------------------
1E3E|
1E3E|                       CHKFIN
1E3E|                               .IF  NEWTWIG = 0
1E3E|                               .ENDC
1E3E|                               .IF  NEWTWIG = 1
1E3E| 2602                          MOVE.L  D2,D3           ;set user-supplied timeout
1E40|                               .ENDC
1E40| 267C 00FC DD81                MOVE.L  #VIA1BASE,A3    ;set ptr for interface
1E46| 0813 0004             @1      BTST    #4,(A3)         ;FDIR?
1E4A| 6608                          BNE.S   @2              ;exit if yes
1E4C| 5383                          SUBQ.L  #1,D3
1E4E| 66F6                          BNE.S   @1              ;else loop
1E50| 003C 0001                     ORI.B   #$01,CCR        ;set error
1E54| 4E75                  @2      RTS
1E56|
1E56|                               .PAGE
1E56|                       ;-------------------------------------------------------------------------
1E56|                       ;  Subroutine to eject disk
1E56|                       ;  Assumes A0 = ptr to disk shared memory
1E56|                       ;-------------------------------------------------------------------------
1E56|
1E56|                       EJCTDSK
1E56|                               .IF     NEWTWIG = 1
1E56| 611A                          BSR.S   CLRFDIR          ;ensure interrupts cleared
1E58| 6516                          BCS.S   @1               ;exit if error
1E5A| 243C 0018 0000                MOVE.L  #EJCTTIME,D2     ;set eject timeout
1E60|                               .ENDC
1E60| 117C 0002 0002                MOVE.B  #UNCLAMP,CMD(A0) ;set up cmd
1E66| 10BC 0081                     MOVE.B  #EXRW,(A0)       ;go do it
1E6A| 61D2                          BSR.S   CHKFIN           ;wait for FDIR
1E6C| 6502                          BCS.S   @1               ;skip if error
1E6E| 6102                          BSR.S   CLRFDIR          ;clear intrpt and return
1E70| 4E75                  @1      RTS
1E72|
1E72|                       ;-------------------------------------------------------------------------
1E72|                       ;  Subroutine to clear interrupt.  Waits for FDIR to go low before return.
1E72|                       ;  Assumes A0 = ptr to disk shared memory.
1E72|                       ;-------------------------------------------------------------------------
1E72|
1E72| 117C 00FF 0002        CLRFDIR MOVE.B  #$FF,CMD(A0)    ;clear FDIR
1E78| 10BC 0085                     MOVE.B  #CLRSTAT,(A0)
1E7C| 6186                          BSR.S   CMDCHK          ;wait until cmd taken
1E7E| 267C 00FC DD81                MOVE.L  #VIA1BASE,A3    ;then wait for FDIR to go low
1E84| 7619                          MOVEQ   #25,D3          ;set timeout for about 200 us
1E86| 0813 0004             @1      BTST    #FDIR,(A3)      ;FDIR?
1E8A| 6708                          BEQ.S   @2              ;skip if none
1E8C| 5343                          SUBQ    #1,D3           ;else loop until gone or timeout
1E8E| 66F6                          BNE.S   @1
1E90| 003C 0001                     ORI.B   #01,CCR         ;set error indicator
1E94| 4E75                  @2      RTS
1E96|
1E96|                       ;-------------------------------------------------------------------------
1E96|                       ;  Subroutine to ensure FDIR gone after clear status cmd
1E96|                       ;-------------------------------------------------------------------------
1E96|
1E96| 267C 00FC DD81        CHKFDIR MOVE.L  #VIA1BASE,A3    ;set ptr for FDIR status
1E9C| 0813 0004                     BTST    #FDIR,(A3)      ;FDIR present?
1EA0| 6702                          BEQ.S   @1              ;skip if not
1EA2| 61CE                          BSR.S   CLRFDIR         ;else do clear
1EA4| 4E75                  @1      RTS                     ;and exit
1EA6|
1EA6|                               .IF  USERINT = 0
1EA6|                               .ENDC                   ;{USERINT}
1EA6|
1EA6|                               .IF  USERINT = 1
1EA6|                       ;-------------------------------------------------------------------------
1EA6|                       ;  Subroutine to enable display of wait icon.  Main entry point creates
1EA6|                       ;  alert box also, secondary enrty point (DSPWTICON) invokes icon display
1EA6|                       ;  only.
1EA6|                       ;  Inputs:
1EA6|                       ;       None
1EA6|                       ;  Outputs:
1EA6|                       ;       None
1EA6|                       ;  Side Effects:
1EA6|                       ;       A2,A3 trashed
1EA6|                       ;-------------------------------------------------------------------------
1EA6|
1EA6|                       WAITALRT
1EA6|                       DSPWTICON
1EA6| 45FA 1B95                     LEA     WAITICON,A2     ;and display wait icon
1EAA| 6100 1680                     BSR     DSPALRTICON
1EAE| 4E75                          RTS
1EB0|                               .ENDC                   ;{USERINT}
1EB0|
1EB0|                               .ENDC                   ;{TWIGGY}
1EB0|
1EB0|                       ;-----------------------------------------------------------------------------
1EB0|                       ;  Routine to reinit vectors before release of control to boot loader.
1EB0|                       ;  Sets all vectors other than reset and interrupts to jump to the
1EB0|                       ;  failing boot device handler.
1EB0|                       ;
1EB0|                       ;  Inputs:
1EB0|                       ;       A3 = address of boot error handler for bus/address errors
1EB0|                       ;       A4 = address of boot error handler for other exceptions
1EB0|                       ;  Outputs:
1EB0|                       ;       None
1EB0|                       ;  Side Effects:
1EB0|                       ;       A0/D1 trashed
1EB0|                       ;-----------------------------------------------------------------------------
1EB0|
1EB0|                       VCTRINIT
1EB0| 307C 0008                     MOVEA   #BUSVCTR,A0     ;get ptr to vector locations            RM000
1EB4| 20CB                          MOVE.L  A3,(A0)+        ;set up for bus error
1EB6| 20CB                          MOVE.L  A3,(A0)+        ;and address error
1EB8| 7214                          MOVEQ   #20,D1          ;# of remaining low vectors to init
1EBA| 20CC                  @1      MOVE.L  A4,(A0)+        ;setup handler for errors up
1EBC| 5341                          SUBQ    #1,D1           ; to spurious intrpt vector
1EBE| 66FA                          BNE.S   @1
1EC0| 307C 0080                     MOVEA   #TRPVCT0,A0     ;next do all trap vectors               RM000
1EC4| 7220                          MOVEQ   #32,D1          ;set count
1EC6| 20CC                  @2      MOVE.L  A4,(A0)+        ;and do init
1EC8| 5341                          SUBQ    #1,D1
1ECA| 66FA                          BNE.S   @2
1ECC| 4E75                          RTS
1ECE|
1ECE|                               .IF     EXTERNAL = 1
1ECE|                               .ENDC
1ECE|                               .PAGE
1ECE|                               .IF PROFLE = 1          ;ASSEMBLE ONLY IF PROFILE CODE NEEDED
1ECE|                       ;-----------------------------------------------------------------------------
1ECE|                       ;  Routine to boot from Profile hard disk attached to parallel port
1ECE|                       ;  Sets up input parameters and then calls READ routine.  If no error
1ECE|                       ;  on return (carry not set), a jump to the loaded boot code is done.
1ECE|                       ;-----------------------------------------------------------------------------
1ECE|
1ECE|                       PROBOOT
1ECE|                               .IF  USERINT = 0
1ECE|                               .ELSE
1ECE| 61D6                          BSR     WAITALRT                ; display wait icon
1ED0|                               .ENDC
1ED0|
1ED0| 227C 0001 FFEC                MOVE.L  #HDRBUFR,A1             ; set up ptr to save header
1ED6| 247C 0002 0000                MOVE.L  #HDRBUFR+20,A2          ; ptr for data
1EDC| 4281                          CLR.L   D1                      ; set sector #
1EDE| 243C 0120 0000                MOVE.L  #STRTIME,D2             ; set timeout count (3 mins)
1EE4| 760A                          MOVEQ   #RCNT,D3                ; set retry count
1EE6| 7803                          MOVEQ   #TCNT,D4                ; set threshold count
1EE8| 6100 0086                     BSR     PROREAD                 ; go get data
1EEC| 6522                          BCS.S   HDSKERR                 ; exit if error
1EEE|
1EEE|                       ;  Now verify header and if OK, jump to startup program
1EEE|
1EEE| 3029 0004                     MOVE    FILEID(A1),D0           ; get file id
1EF2| 0C40 AAAA                     CMP     #BOOTPAT,D0             ; is it a boot block?
1EF6| 6704                          BEQ.S   PBOOT                   ; continue if OK
1EF8| 7054                          MOVEQ   #BADHDR,D0              ; else set error code
1EFA| 6014                          BRA.S   HDSKERR                 ; and exit
1EFC|
1EFC| 47FA 0060             PBOOT   LEA     HDERR2,A3               ;set up vectors in case of errors
1F04| 61AA                          BSR     VCTRINIT4
1F06|
1F06| 247C 0002 0000                MOVE.L  #HDRBUFR+20,A2          ; set ptr for data
1F0C| 6000 FD74                     BRA     STRTBOOT                ; and go start execution
1F10|
1F10|                       ;  Error detected - output message and abort boot
1F10|
1F10|                       HDSKERR
1F10|                               .IF  USERINT = 0
1F10|                               .ELSE
1F10|
1F10| 0C38 0003 02AF                CMP.B   #3,SYSTYPE              ;check system type              CHG009/CHG029
1F16| 6706                          BEQ.S   @2                      ;skip if internal disk          CHG009/CHG029
1F18| 45FA 1B85                     LEA     PROICON,A2              ;else setup Profile icon
1F1C| 6004                          BRA.S   @3                      ;skip to do display             CHG009
1F1E| 45FA 1BBA             @2      LEA     UPPER,A2                ;set for integral hard disk     CHG009
1F22|
1F22| 0C00 0050             @3      CMP.B   #NODSK,D0               ;Profile not attached error?
1F26| 660E                          BNE.S   @1                      ;skip if not
1F28|
1F28|                       ;  If default boot and no Profile attached, go to boot menu
1F28|
1F28| 0807 001C                     BTST    #ALTBOOT,D7             ;is this a default boot?
1F2C| 6608                          BNE.S   @1                      ;skip if not
1F2E| 6100 11AA                     BSR     CLRDESK                 ;clear desktop
1F32| 6000 F8FA                     BRA     LSTCHK                  ;and do beep and display the boot menu
1F36|
1F36| 6100 15A2             @1      BSR     DSPERRICON              ;display with bad mark
1F3A|
1F3A|                               .ENDC                           ;{PROFILE}
1F3A|
1F3A|                       ;  Sound error tones and display error code
1F3A|
1F3A|                       BOOTFAIL
1F3A| 6100 F6E6                     BSR     DSPCODE                 ;display error code
1F3E|
1F3E|                       BFAIL2
1F3E| 6100 F788                     BSR     HIPTCH                  ;startup failure causes hi,hi,hi tones
1F42| 6100 F784                     BSR     HIPTCH
1F46| 6100 F780                     BSR     HIPTCH
1F4A| 6100 11C8                     BSR     CLRMENU                 ;clear menu bar
1F4E| 0238 00FC 02A2                ANDI.B  #$FC,STATFLGS           ;allow CONTINUE option from boot error
1F54| 08F8 0000 02A2                BSET    #NORSTRT,STATFLGS       ; but not restart option
1F5A| 6000 0640                     BRA     MONITOR                 ;and go to monitor
1F5E|
1F5E|                       HDERR2  BSR4    SAVEXCP                 ;save exception info
1F5E| 49FA 0006            #          LEA      @1,A4
1F62| 6000 FDB8            #          BRA      SAVEXCP
1F66|                      #@1
1F66|                       HDERR3  BSR4    BTERR                   ;regroup from error
1F66| 49FA 0006            #          LEA      @1,A4
1F6A| 6000 FDBE            #          BRA      BTERR
1F6E|                      #@1
1F6E| 60A0                          BRA.S   HDSKERR                 ;and go display it
1F70|
1F70|                               .IF     EXTERNAL = 1
1F70|                               .ENDC
1F70|
1F70|                               .PAGE
1F70|                       ;-----------------------------------------------------------------------------
1F70|                       ;  First initialize and then ensure disk is attached by checking OCD line.
1F70|                       ;  Assumes ACR and IER registers of VIA set up by caller.  For boot, these
1F70|                       ;  are cleared by power-up reset.
1F70|                       ;  Register usage:
1F70|                       ;    D0 = scratch use           A0 = VIA address for parallel port interface
1F70|                       ;    D1 = block to read         A1 = address to save header
1F70|                       ;    D2 = timeout count         A2 = address to save data
1F70|                       ;    D3 = retry count           A3 = scratch
1F70|                       ;    D4 = threshold count       A4 = unused
1F70|                       ;  Returns:
1F70|                       ;    D0 = error code (0 = OK)
1F70|                       ;    D1 = error bytes (4)
1F70|                       ;    D2 - D7 and A1 - A6 are preserved
1F70|                       ;-----------------------------------------------------------------------------
1F70|
1F70| 48E7 3F7E             PROREAD MOVEM.L D2-D7/A1-A6,-(SP)       ; save regs
1F74|                               DISABLE                         ; ensure interrupts off
1F74| 40E7                 #          MOVE     SR,-(SP)
1F76| 007C 0700            #          ORI      #$0700,SR
1F7A| 6174                          BSR.S   PROINIT                 ; init for Profile access and check
1F7C|                                                               ;  if attached
1F7C| 6704                          BEQ.S   CHKBSY                  ; go on if OK
1F7E| 7050                          MOVEQ   #NODSK,D0               ; else set error code and
1F80| 605C                          BRA.S   PROERR                  ; skip if error - no disk attached
1F82|
1F82|                       ;  Now check if Profile ready - wait time presently set for about 100 seconds
1F82|                       ;  to allow enough time for normal Profile startup time of about 80 seconds
1F82|
1F82| 0810 0001             CHKBSY  BTST    #BSY,IRB2(A0)           ; check if Profile ready (not busy)
1F86| 6608                          BNE.S   TRYRD                   ; skip if yes
1F88| 5382                          SUBQ.L  #1,D2                   ; else loop until timeout
1F8A| 66F6                          BNE.S   CHKBSY
1F8C|
1F8C| 7051                          MOVEQ   #DSKBSY,D0              ; set disk busy error code
1F8E| 604E                          BRA.S   PROERR                  ; and go to error exit
1F90|
1F90|                       ;  Now start read and check status to see if OK
1F90|
1F90| 6100 00B6             TRYRD   BSR     STRTRD                  ; go begin read process
1F94| 6418                          BCC.S   @1                      ; skip if OK                    CHG016
1F96| 6100 018A                     BSR     WFNBSY                  ; else check for ready          CHG016
1F9A| 6100 00AC                     BSR     STRTRD                  ; and do retry                  CHG016
1F9E| 640E                          BCC.S   @1                      ; continue if OK                CHG016
1FA0| 6100 01A4                     BSR     DOCRES                  ; else issue reset signal       CHG016
1FA4| 6100 017C                     BSR     WFNBSY                  ; wait until ready              CHG016
1FA8| 6100 009E                     BSR     STRTRD                  ; and try one more time         CHG016
1FAC| 6530                          BCS.S   PROERR                  ; finally exit if error
1FAE|
1FAE| 4A78 01B6             @1      TST.W   STAT3                   ; check if reset error          CHG016
1FB2| 6A06                          BPL.S   @2                      ; skip if not
1FB4| 6100 0092                     BSR     STRTRD                  ; else go try read again
1FB8| 6524                          BCS.S   PROERR                  ; and abort if error
1FBA|
1FBA| 4AB8 01B4             @2      TST.L   STATBFR                 ; check complete status
1FBE| 6712                          BEQ.S   RDDATA                  ; skip if OK
1FC0| 2238 01B4                     MOVE.L  STATBFR,D1              ; else get status
1FC4| 2001                          MOVE.L  D1,D0                   ; save for use
1FC6| 0280 C140 C000                ANDI.L  #STATMSK,D0             ; mask don't care bits
1FCC| 6704                          BEQ.S   RDDATA                  ; and continue if OK
1FCE| 7053                          MOVEQ   #STATNZ,D0              ; else set error code
1FD0| 600C                          BRA.S   PROERR                  ; and go to error exit
1FD2|
1FD2|                       ;  All OK - go read block and transfer to memory; do as multiple moves for
1FD2|                       ;  max transfer rate.
1FD2|
1FD2| 7004                  RDDATA  MOVEQ   #-1,D0       ; set count for header read
1FD4| 615C                          BSR.S   READIT                  ; go do it
1FD6|
1FD6| 707F                          MOVEQ   #-1,D0       ; set count for data read
1FD8| 224A                          MOVEA.L A2,A1                   ; set new read location
1FDA| 6156                          BSR.S   READIT
1FDC|
1FDC| 6008                          BRA.S   PROXIT                  ; and go to exit
1FDE|
1FDE|                       ;  Error exit - set carry bit as indicator flag
1FDE|
1FDE| 46DF                 #          MOVE     (SP)+,SR             ;restore interrupt mask
1FE0| 003C 0001                     ORI.B   #$01,CCR
1FE4| 6004                          BRA.S   PROXIT2
1FE6|
1FE6|                       ;  Normal exit - restore regs and exit
1FE6|                       PROXIT  ENABLE                          ;restore interrupt mask
1FE6| 46DF                 #          MOVE     (SP)+,SR
1FE8| 4280                          CLR.L   D0                      ;set OK return code             CHG025
1FEA|
1FEA| 4CDF 7EFC             PROXIT2 MOVEM.L (SP)+,D2-D7/A1-A6
1FEE| 4E75                          RTS
1FF0|
1FF0|                       ;----------------------------------------------------------------------------
1FF0|                       ;  Subroutine to init parallel port for Profile access.
1FF0|                       ;  Inputs:
1FF0|                       ;       None
1FF0|                       ;  Outputs:
1FF0|                       ;       D0 cleared for error use
1FF0|                       ;       A0 = VIA base address for parallel port
1FF0|                       ;       CCR zero bit set if cable connected
1FF0|                       ;  Side Effects:
1FF0|                       ;       None
1FF0|                       ;----------------------------------------------------------------------------
1FF0|
1FF0|                       PROINIT
1FF0| 4280                          CLR.L   D0                      ; clear for result use
1FF2| 267C 00FC DD81                MOVE.L  #VIA1BASE,A3            ; get kybd VIA base address                     CHG036
1FF8| 0013 00A0                     ORI.B   #$A0,ORB1(A3)           ; initialize profile-reset and parity-reset     CHG036
1FFC| 002B 00A0 0004                ORI.B   #$A0,DDRB1(A3)          ;  and set lines as outputs                     CHG036
2002| 207C 00FC D901                MOVE.L  #VIA2BASE,A0            ; get paraport VIA base address
2008| 0228 007B 0060                ANDI.B  #$7B,PCR2(A0)           ; set ctrl CA2 pulse mode/positive edge
200E| 0028 006B 0060                ORI.B   #$6B,PCR2(A0)
2014| 4228 0018                     MOVE.B  #$00,DDRA2(A0)          ; set port A bits to input
2018| 0010 0018                     ORI.B   #$18,ORB2(A0)           ; then set direction=in, cmd=false,             CHG036
201C| 0210 00FB                     ANDI.B  #$FB,ORB2(A0)           ;  enable=true                                  CHG036
2020| 0228 00FC 0010                ANDI.B  #$FC,DDRB2(A0)          ; set port B bits 0,1=in,
2026| 0028 001C 0010                ORI.B   #$1C,DDRB2(A0)          ;  2,3,4=out
202C| 0810 0000                     BTST    #OCD,IRB2(A0)           ; check OCD line
2030| 4E75                          RTS                             ; and exit
2032|
2032|                       ;----------------------------------------------------------------------------
2032|                       ;  Subroutine to read bytes from Profile.  Assumes:
2032|                       ;    D0 = byte count - 1
2032|                       ;    A0 = VIA address for parallel interface
2032|                       ;    A1 = memory load address
2032|                       ;----------------------------------------------------------------------------
2032|
2032| 12E8 0008             READIT  MOVE.B  IRA2(A0),(A1)+          ; read the bytes
2036| 12E8 0008                     MOVE.B  IRA2(A0),(A1)+
203A| 12E8 0008                     MOVE.B  IRA2(A0),(A1)+
203E| 12E8 0008                     MOVE.B  IRA2(A0),(A1)+
2042| 51C8 FFEE                     DBF     D0,READIT
2046| 4E75                          RTS
2048|
2048|                               .PAGE
2048|                       ;---------------------------------------------------------------------------
2048|                       ;  Subroutine to begin the read process.  First calls a routine that
2048|                       ;  an appropriate response from Profile is executed.  Then a wait for
2048|                       ;  Assumes regs:
2048|                       ;    D0 = scratch use           A0 = VIA address
2048|                       ;    D1 = block to read         A1 = unused
2048|                       ;    D2 = used for Profile cmd  A2 = unused
2048|                       ;    D3 = retry count           A3 = scratch use
2048|                       ;    D4 = threshold count       A4 = unused
2048|                       ;  If error, carry bit set and error code in D0.
2048|                       ;---------------------------------------------------------------------------
2048|
2048| 367C 0304             STRTRD  MOVEA   #CMDBUFR,A3             ; first set up command                  RM000
204C| 2681                          MOVE.L  D1,(A3)                 ; set read command (0) and block #
204E| 1743 0004                     MOVE.B  D3,RETRY(A3)            ; set retry count
2052| 1744 0005                     MOVE.B  D4,THRESH(A3)           ; set threshhold for sparing
2056| 611E                          BSR.S   STAT01                  ; get 01 byte and send read command
2058| 651A                          BCS.S   STRTXIT                 ; exit if error
205A|
205A|                       ;  OK so far - go check if Profile ready to send data
205A|
205A| 7402                          MOVEQ   #2,D2                   ; get 02 byte                           RM000
205C| 615E                          BSR.S   FINDD2
205E| 6514                          BCS.S   STRTXIT                 ; exit if timeout error
2060|
2060|                       ;  Get status bytes
2060| 367C 01B4             GETSTAT MOVEA   #STATBFR,A3             ; set buffer ptr                        RM000
2064| 16E8 0008                     MOVE.B  IRA2(A0),(A3)+          ; read and save the status
2068| 16E8 0008                     MOVE.B  IRA2(A0),(A3)+
206C| 16E8 0008                     MOVE.B  IRA2(A0),(A3)+
2070| 16E8 0008                     MOVE.B  IRA2(A0),(A3)+
2074|
2074| 4E75                  STRTXIT RTS                             ; return to caller
2076|
2076|                               .PAGE
2076|                       ;--------------------------------------------------------------------------
2076|                       ;  Subroutine to get in sync with Profile.
2076|                       ;  Input regs:
2076|                       ;    A0 = VIA address
2076|                       ;    A3 = ptr to command buffer
2076|                       ;  If error, returns with carry bit set and error code in D0
2076|                       ;--------------------------------------------------------------------------
2076|
2076| 48E7 2800             STAT01  MOVEM.L D2/D4,-(SP)             ; save regs
207A| 7401                          MOVE.L  #1,D2                   ; try to find state 01
207C| 613E                          BSR.S   FINDD2
207E| 6412                          BCC.S   COPY6                   ; skip if OK
2080| 0C00 0055                     CMP.B   #TMOUT,D0               ; else check if timeout error
2084| 672C                          BEQ.S   STATERR                 ; and exit if yes
2086|
2086| 6100 00AA                     BSR     WFNBSY3                 ; ensure Profile ready                  RM000
208A| 4A00                          TST.B   D0                      ; check for timeout error
208C| 6624                          BNE.S   STATERR                 ; and exit if yes
208E|
208E| 612C                  @2      BSR.S   FINDD2                  ; try to find state 01 again
2090| 6524                          BCS.S   STATXIT                 ; exit if error again
2092|
2092| 0210 00F7             COPY6   ANDI.B  #$F7,ORB2(A0)           ; set dir=out
2096| 117C 00FF 0018                MOVE.B  #$FF,DDRA2(A0)          ; set port A bits to output
209C| 303C 0005                     MOVE.W  #PCMDSZ,D0              ; set command size
20A0| 115B 0008             COPY6LP MOVE.B  (A3)+,ORA2(A0)          ; send the command bytes
20A4| 51C8 FFFA                     DBF     D0,COPY6LP
20A8| 0010 0008                     ORI.B   #$08,ORB2(A0)           ; reset dir=in
20AC| 4228 0018                     MOVE.B  #$00,DDRA2(A0)          ;  and set port A bits to input
20B0| 6004                          BRA.S   STATXIT                 ; then exit
20B2|
20B2| 003C 0001             STATERR ORI.B   #$01,CCR                ; set error indicator
20B6|
20B6| 4CDF 0014             STATXIT MOVEM.L (SP)+,D2/D4             ; restore regs
20BA| 4E75                          RTS
20BC|
20BC|                               .PAGE
20BC|                       ;------------------------------------------------------------------------------
20BC|                       ;  Subroutine to handshake with Profile and wait for command completion.
20BC|                       ;  Polls busy bit until it goes low (not busy).
20BC|                       ;  Assumes regs:
20BC|                       ;    A0 = VIA address
20BC|                       ;    D2 = Expected response to previously issued command
20BC|                       ;  If error, carry bit set and error code in D0.
20BC|                       ;------------------------------------------------------------------------------
20BC|
20BC| 48E7 7800             FINDD2  MOVEM.L D1-D4,-(SP)             ; save regs
20C0| 0210 00EF                     ANDI.B  #$EF,ORB2(A0)           ; set cmd=true
20C4| 4228 0018                     MOVE.B  #$00,DDRA2(A0)          ; set port A bits to input
20C8| 4280                          CLR.L   D0                      ; used for return code
20CA| 6130                          BSR.S   WFBSY                   ; wait for busy
20CC| 6618                          BNE.S   FINDERR                 ; exit if error
20CE|
20CE| 1228 0078             GETRSP  MOVE.B  PORTA2(A0),D1           ; get response in D1 w/o handshake
20D2| 4203                          CLR.B   D3                      ; used for reply to Profile
20D4| B202                          CMP.B   D2,D1                   ; did pippin return state requested ?
20D6| 6704                          BEQ.S   RSPOK                   ; skip if yes
20D8| 7052                          MOVEQ   #BADRSP,D0              ; else set error code
20DA| 6002                          BRA.S   SNDR1                   ; and go send reply
20DC|
20DC| 7655                  RSPOK   MOVEQ   #$55,D3                 ; set up OK reply                       RM000
20DE|
20DE| 612E                  SNDR1   BSR.S   SENDRSP                 ; send response
20E0|
20E0| 4A00                          TST.B   D0                      ; check return code
20E2| 6602                          BNE.S   FINDERR                 ; skip if error
20E4|
20E4| 613C                          BSR.S   WFNBSY                  ; now go wait for not busy
20E6|
20E6| 4228 0018             FINDERR MOVE.B  #$00,DDRA2(A0)          ; reset port A bits to input
20EA| 0010 0018                     ORI.B   #$18,ORB2(A0)           ; and dir = in, cmd=false
20EE|
20EE| 4A00                          TST.B   D0                      ; check return code
20F0| 6704                          BEQ.S   FNDXIT                  ; skip if OK
20F2| 003C 0001                     ORI.B   #$01,CCR                ; else set error indicator
20F6|
20F6| 4CDF 001E             FNDXIT  MOVEM.L (SP)+,D1-D4             ; restore regs(but don't affect CCR bits)
20FA| 4E75                          RTS
20FC|
20FC|
20FC|                       ;------------------------------------------------------------------------------
20FC|                       ;  Subroutine to wait for Profile busy signal.  Polls busy bit until it
20FC|                       ;  goes high (busy).
20FC|                       ;  Assumes regs:
20FC|                       ;    A0 = VIA address
20FC|                       ;    D4 = timeout value if WFBSY1 entry point used
20FC|                       ;  If error, error code in D0.
20FC|                       ;------------------------------------------------------------------------------
20FC|
20FC| 383C FFFF             WFBSY   MOVE    #RSPTIME,D4             ; set response timeout = 100 msec
2100|
2100| 0810 0001             WFBSY1  BTST    #BSY,IRB2(A0)           ; wait for busy
2104| 6706                          BEQ.S   @9                      ; skip if OK
2106| 5344                          SUBQ    #1,D4                   ; else loop until timeout
2108| 66F6                          BNE.S   WFBSY1
210A| 7055                          MOVEQ   #TMOUT,D0               ; set timeout error
210C| 4E75                  @9      RTS
210E|
210E|                       ;------------------------------------------------------------------------------
210E|                       ;  Subroutine to send response command to Profile.
210E|                       ;  Assumes regs:
210E|                       ;    A0 = VIA address
210E|                       ;------------------------------------------------------------------------------
210E|
210E| 0210 00E7             SENDRSP ANDI.B  #$E7,ORB2(A0)           ; set dir=out, cmd=true
2112| 117C 00FF 0018                MOVE.B  #$FF,DDRA2(A0)          ; set port A bits to output
2118| 1143 0078                     MOVE.B  D3,PORTA2(A0)           ; send reply(00 or 55) w/o handshake
211C| 0010 0010                     ORI.B   #$10,ORB2(A0)           ; set cmd=false
2120| 4E75                          RTS
2122|
2122|                       ;------------------------------------------------------------------------------
2122|                       ;  Subroutine to wait for Profile not busy signal.  Polls busy bit until it
2122|                       ;  goes low (not busy).
2122|                       ;  Assumes regs:
2122|                       ;    A0 = VIA address
2122|                       ;    D4 = timeout value if WFNBSY1 entry point used
2122|                       ;  If error, D0 has error code.
2122|                       ;------------------------------------------------------------------------------
2122|
2122| 283C 0018 0000        WFNBSY  MOVE.L  #RDTIME,D4              ; set timeout for about 16 secs         CHG037
2128| 600E                          BRA.S   WFNBSY1                 ;                                       CHG019
212A|
212A| 283C 0120 0000        WFNBSY2 MOVE.L  #STRTIME,D4             ; set initial Profile self-test time    CHG019
2130| 6006                          BRA.S   WFNBSY1                 ;                                       CHG019
2132|
2132| 283C 0000 0500        WFNBSY3 MOVE.L  #BSYTIME,D4             ; set timeout for about 10 ms           RM000
2138|
2138| 0810 0001             WFNBSY1 BTST    #BSY,IRB2(A0)           ; wait for not busy
213C| 6606                          BNE.S   @9                      ; exit if OK
213E| 5384                          SUBQ.L  #1,D4                   ; else loop until timeout
2140| 66F6                          BNE.S   WFNBSY1
2142| 7055                          MOVEQ   #TMOUT,D0               ; set timeout error
2144| 4E75                  @9      RTS
2146|
2146|                       ;-----------------------------------------------------------------------------
2146|                       ;  Subroutine to send reset to Profile controller to enable handshake retry     CHG016
2146|                       ;-----------------------------------------------------------------------------
2146|
2146| 267C 00FC DD81        DOCRES  MOVE.L  #VIA1BASE,A3            ;use keyboard 6522                      CHG026
214C| 0213 007F                     ANDI.B  #$7F,ORB1(A3)           ;set reset signal                       CHG016/CHG026/CHG036
2150| 6100 E97A                     BSR     DELAY_1                 ;delay for controller to get signal     CHG016
2154| 0013 0080                     ORI.B   #$80,ORB1(A3)           ;remove reset signal                    CHG016/CHG026/CHG036
2158| 6100 E972                     BSR     DELAY_1                 ;delay for controller to respond        CHG038
215C| 4E75                          RTS                             ;and exit
215E|
215E|                               .ENDC                           ;{PROFLE}
215E|                               .IF     EXTERNAL = 1
215E|                               .ENDC
215E|                               .PAGE
215E|                       ;-------------------------------------------------------------------------
215E|                       ;  Routine to boot from I/O slot.
215E|                       ;  Verifies that slot has bootable card installed and then reads in ROM
215E|                       ;  data.  If status routine exists it is executed, else jump to boot
215E|                       ;  routine done if checksum OK.
215E|                       ;
215E|                       ;  Inputs:
215E|                       ;       D0 = boot device id ($4-$C)
215E|                       ;       A0 = scratch use
215E|                       ;       A1 = slot address
215E|                       ;  Outputs: (relayed to loaded boot program)
215E|                       ;       D0 = boot device id
215E|                       ;       A1 = slot address
215E|                       ;-------------------------------------------------------------------------
215E|
215E| 1800                  IOSBOOT MOVE.B  D0,D4           ;save boot device id
2160|                                                       ; also acts as flag for status check
2160| 2A78 0008                     MOVE.L  BUSVCTR,A5      ;save bus error vector
2164| 2C4F                          MOVE.L  SP,A6           ;save current stack pointer
2166|
2166| 47FA 002C                     LEA     NOCRD,A3        ;setup new bus error vector
216A| 21CB 0008                     MOVE.L  A3,BUSVCTR
216E| 0309 0000                     MOVEP   (A1),D1         ;read card id
2172|
2172|                               .IF  USERINT = 0
2172|                               .ENDC
2172|
2172| 4A41                          TST     D1              ;check if card installed
2174| 6A28                          BPL.S   INVID           ;exit if not bootable
2176| 0C41 FFFF                     CMP     #$FFFF,D1       ;check if special case
217A| 6722                          BEQ.S   INVID
217C|
217C|                               .IF  USERINT = 1
217C| 6100 FD28                     BSR     WAITALRT        ;display wait icon
2180|                               .ENDC
2180|
2180| 2449                          MOVE.L  A1,A2           ;get slot address
2182| 6148                          BSR.S   RDIOSLT         ;go check the board
2184| 651C                          BCS.S   BADBRD          ;exit if error
2186|
2186|                       STATOK
2186| 1038 01B3                     MOVE.B  BOOTDVCE,D0     ;setup boot device id
218A| 247C 0002 0002                MOVE.L  #BTENTRY,A2     ;and starting program address
2190| 6000 FAF0                     BRA     STRTBOOT        ;and go do boot ...
2194|
2194|                       ;  Error routines for I/O slot booting. Error code saved and error message output.
2194| 705A                  NOCRD   MOVEQ   #NOC,D0         ;set error code
2196| 21CD 0008                     MOVE.L  A5,BUSVCTR      ;restore bus error vector
219A| 2E4E                          MOVE.L  A6,SP           ;and stack ptr
219C| 6008                          BRA.S   SENDMSG         ;then go display msg
219E|
219E| 705B                  INVID   MOVEQ   #INV,D0         ;set error code
21A0| 6004                          BRA.S   SENDMSG         ;go do display
21A2|
21A2| 1838 01B3             BADBRD  MOVE.B  BOOTDVCE,D4     ;restore boot device id for checking
21A6|
21A6|                       SENDMSG
21A6| 11C0 01B4                     MOVE.B  D0,BOOTDATA     ;save error code
21AA|
21AA|                               .IF  USERINT = 0
21AA|                               .ELSE
21AA|                       ;  determine which slot # being used
21AA|
21AA| 45FA 1868                     LEA     XCARD,A2        ;set general I/O slot card ptr
21AE| 0C04 0004                     CMP.B   #IO1PORT2,D4    ;in slot 1 range?
21B2| 6E04                          BGT.S   @1
21B4| 7201                          MOVEQ   #1,D1           ;yes - set slot #1
21B6| 600C                          BRA.S   @3
21B8|
21B8| 0C04 0007             @1      CMP.B   #IO2PORT2,D4    ;slot 2 range?
21BC| 6E04                          BGT.S   @2
21BE| 7202                          MOVEQ   #2,D1           ;set slot 2 id
21C0| 6002                          BRA.S   @3
21C2|
21C2| 7203                  @2      MOVEQ   #3,D1           ;else must be slot 3
21C4|
21C4| 6100 128A             @3      BSR     DSPNUMICON      ;display error icon and slot #
21C8| 6000 FD70                     BRA     BOOTFAIL        ;and signal boot failure
21CC|                               .ENDC
21CC|
21CC|                               .PAGE
21CC|                               .IF  NEWTWIG = 1
21CC|                       ;----------------------------------------------------------------------------
21CC|                       ;  Routine to read ROM on an I/O slot.
21CC|                       ;  Inputs:
21CC|                       ;       A2 = I/O slot base address
21CC|                       ;       D4 = nonzero if status check also to be done, else 0 for no check
21CC|                       ;       D1 = card id if status check needed
21CC|                       ;  Outputs:
21CC|                       ;       Carry bit set if error, error code saved in D0, error code from
21CC|                       ;       status check saved in BOOTDATA+1
21CC|                       ;  Side Effects:
21CC|                       ;       D0, A2 trashed
21CC|                       ;----------------------------------------------------------------------------
21CC| 48E7 70C0             RDIOSLT MOVEM.L D1-D3/A0-A1,-(SP) ;save regs
21D0| 207C 0001 FFFC                MOVE.L  #ADR128K-4,A0   ;set load pt (also load id/word count)
21D6| 224A                          MOVE.L  A2,A1           ;save slot address for later use
21D8| 4280                          CLR.L   D0              ;clear for use
21DA| 010A 0004                     MOVEP   4(A2),D0        ;read word count
21DE| 5440                          ADDQ    #2,D0           ;incr for id/count fields
21E0| 0C40 0FFF                     CMPI    #$0FFF,D0       ;check for max count
21E4| 6244                          BHI.S   INVSUM          ;exit if error
21E6| 4282                          CLR.L   D2              ;clear for use
21E8| 4283                          CLR.L   D3
21EA|
21EA| 050A 0000             LOADPGM MOVEP   (A2),D2         ;read word
21EE| 3082                          MOVE    D2,(A0)         ;save in memory
21F0| 3418                          MOVE    (A0)+,D2        ;reread it from memory
21F2| D642                          ADD     D2,D3           ;add to checksum
21F4| E35B                          ROL     #1,D3           ;rotate for better effectiveness
21F6| 588A                          ADDQ.L  #4,A2           ;bump address ptr
21F8| 5340                          SUBQ    #1,D0
21FA| 66EE                          BNE.S   LOADPGM         ;loop until done
21FC|
21FC| 050A 0000                     MOVEP   (A2),D2         ;read expected checksum (2 bytes)
2200| D642                          ADD     D2,D3           ;add to calculated checksum
2202| 4A43                          TST     D3              ;check for 0 result (also clears carry bit)
2204| 6624                          BNE.S   INVSUM          ;skip if error
s2206|
2206|                       ;  Do status check if desired and available
2206|
2206| 4A44                          TST     D4              ;do status check?
2208| 672A                          BEQ.S   RDIOXIT         ;skip if not
220A| 0801 000E                     BTST    #STBIT,D1       ;status routine available?
220E| 6724                          BEQ.S   RDIOXIT         ;skip if not
2210|
2210| 48E7 0F3E                     MOVEM.L D4-D7/A2-A6,-(SP) ;save regs not already saved
2214| 4EB9 0002 0000                JSR     STENTRY           ;go execute status routine
221A| 4CDF 7CF0                     MOVEM.L (SP)+,D4-D7/A2-A6 ;restore regs
221E|
221E| 4A40                          TST     D0              ;check status
2220| 6712                          BEQ.S   RDIOXIT         ;skip if no error
2222| 11C0 01B5                     MOVE.B  D0,BOOTDATA+1   ;save card error code
2226| 705D                          MOVEQ   #BADST,D0       ;set general error code
2228| 6002                          BRA.S   SAVERR
222A|
222A| 705C                  INVSUM  MOVEQ   #BADSM,D0       ;set invalid checksum
222C|
222C| 11C0 01B4             SAVERR  MOVE.B  D0,BOOTDATA     ;save error code
2230| 003C 0001                     ORI.B   #$01,CCR        ;set error indicator
2234|
2234| 4CDF 030E             RDIOXIT MOVEM.L (SP)+,D1-D3/A0-A1 ;restore regs
2238| 4E75                          RTS
223A|
223A|                               .ENDC
223A|
223A|                               .IF     BURNIN = 1
223A|                               .PAGE
223A|                       ;-------------------------------------------------------------------------
223A|                       ;  Special code to enable burnin cycling by the ROM.  Does initialization
223A|                       ;  on first pass, and then causes cycling for the specified cycle count,
223A|                       ;  which defaults to approximately 60 minutes.  At
223A|                       ;  that point a branch to a system shutdown routine is performed.
223A|                       ;-------------------------------------------------------------------------
223A|
223A|                       ;  Do first pass initialization
223A|
223A| 0C39 0001 00FC C191   CHKPASS CMP.B   #$01,INITFLG    ;first pass done?
2242| 6756                          BEQ.S   CHKTIM          ;skip if yes
2244| 207C 00FC C191        CHKPAS2 MOVEA.L #INITFLG,A0     ;set ptr for other data areas
224A| 227C 00FC C1FF                MOVEA.L #ENDPM,A1       ;and ending ptr
2250|
2250| 4210                  CLRPM   CLR.B   (A0)            ;do clear
2252| 5488                          ADDQ.L  #2,A0           ;bump ptr
2254| B3C8                          CMPA.L  A0,A1           ;loop until done
2256| 66F8                          BNE.S   CLRPM
2258|
2258| 7001                          MOVEQ   #1,D0
225A| 13C0 00FC C191                MOVE.B  D0,INITFLG      ;set init flag
2260| 13FC 003C 00FC C1C3           MOVE.B  #60,CYCLVAL     ;set cycling for 60 minutes
2268| 42B8 01BA                     CLR.L   CLKDATA         ;and init clock data area
226C| 4278 01BE                     CLR     CLKDATA+4
2270|
2270|                       ;  Set clock to initial value so run can be ended at cycle count.  Sends
2270|                       ;  value of day=01, all other values=0 (e.g., time = 00:00:00).
2270|
2270| 702C                          MOVEQ   #$2C,D0         ;set up clock set cmd
2272| 6100 E6E2                     BSR     COPSCMD         ;and send to COPS
2276| 651E                          BCS.S   @9              ;exit if error                          RM000
2278| 4281                          MOVE.L  #SET1,D1        ;set up value for clock
227A| 7408                          MOVEQ   #8,D2           ;set "char" count
227C| 6100 01E8                     BSR     TODSET          ;and go do it
2280| 6514                          BCS.S   @9              ;                                       RM000
2282| 223C 1000 0000                MOVE.L  #SET2,D1        ;set up next value for clock
2288| 7408                          MOVEQ   #8,D2           ;set "char" count
228A| 6100 01DA                     BSR     TODSET          ;and go do it
228E| 6506                          BCS.S   @9              ;                                       RM000
2290| 7025                          MOVEQ   #$25,D0         ;finally set up clock enable cmd
2292| 6100 E6C2                     BSR     COPSCMD         ;and send it
2296| 6500 01B0             @9      BCS     SETERR1         ;exit if error
229A|
229A|                       ;  Check to see if cycle count to be changed and if time data needs to be saved
229A|
229A|                       CHKTIM
229A|                               .IF  USERINT = 1
229A| 6100 0EC8                     BSR     MAKEPCALRT      ;setup powercycle alert box
229E|                               .ENDC
229E|
229E| 0838 0002 02A2                BTST    #MSBUTN,STATFLGS ;mouse button detected?
22A4| 6718                          BEQ.S   @3              ;skip if no                             RM000
22A6| 1039 00FC C1C3                MOVE.B  CYCLVAL,D0      ;read current setting                   RM000
22AC| 0C00 003C                     CMP.B   #60,D0          ;long cycle set?                        RM000
22B0| 6604                          BNE.S   @1
22B2| 7003                          MOVEQ   #3,D0           ;set for 3 minute cycle                 RM000
22B4| 6002                          BRA.S   @2
22B6| 703C                  @1      MOVEQ   #60,D0          ;set for 60 minute cycle                RM000
22B8| 13C0 00FC C1C3        @2      MOVE.B  D0,CYCLVAL      ;save in PM                             RM000
22BE|
22BE| 0C39 0001 00FC C199   @3      CMP.B   #$01,TIMFLG     ;time data saved?                       RM000
22C6| 6722                          BEQ.S   TWGCHK          ;skip if yes
22C8|
22C8| 2038 01BC                     MOVE.L  HOUR,D0         ;get minutes
22CC| E998                          ROL.L   #4,D0
22CE| 4840                          SWAP    D0
22D0| 13C0 00FC C19B                MOVE.B  D0,MINSAV       ;save minutes
22D6| 4239 00FC C1C5                CLR.B   MINCNT          ;and clear minute count
22DC| 4239 00FC C1C1                CLR.B   CYCLCNT         ; and cycle count
22E2| 13FC 0001 00FC C199           MOVE.B  #$01,TIMFLG     ;and set flag
22EA|
22EA|                       ;  Check if time for Twiggy test (do every two minutes)
22EA|
22EA| 0C39 0002 00FC C1C5   TWGCHK  CMP.B   #2,MINCNT       ;check minute counter
22F2| 6600 0082                     BNE     WRTMSG
22F6|
22F6| 4239 00FC C1C5                CLR.B   MINCNT          ;clear counter
22FC| 47FA 1AEB                     LEA     TWGMSG,A3       ;get msg ptr
2300| 6100 13F4                     BSR     DSPMSGR         ;and display it
2304| 7C0C                          MOVEQ   #PCCOL,D6       ;reset left margin
2306|
2306| 47FA EE7E                     LEA     DSKVCT,A3       ;set up bus error vector
230A| 21CB 0008                     MOVE.L  A3,BUSVCTR
230E| 207C 00FC C001                MOVE.L  #DISKMEM,A0     ;set ptr to shared memory
2314| 267C 00FC DD81                MOVE.L  #VIA1BASE,A3
231A| 4A38 02AF                     TST.B   SYSTYPE         ;check system type                      CHG009
231E| 6704                          BEQ.S   @1              ;skip if Lisa 1.0                       CHG009
2320| 7850                          MOVEQ   #80,D4          ;else set track count for SONY drive    CHG009
2322| 6012                          BRA.S   @2              ;and go test single drive               CHG009
2324|
2324| 4281                  @1      CLR.L   D1              ;else set for drive 1, track 0 to start
2326| 782D                          MOVEQ   #45,D4          ;set count (# of tracks)
2328|
2328|                       ;  Now do the drive test, one drive at a time
2328|
2328| 6100 FB48                     BSR     CLRFDIR         ;first clear interrupts
232C| 6516                          BCS.S   TSTERR          ;exit if error
232E| 6100 014E                     BSR     TWGTST          ;go do test
2332| 6510                          BCS.S   TSTERR
2334| 782D                          MOVEQ   #45,D4          ;reset track count                      CHG009
2336|
2336| 4281                  @2      CLR.L   D1              ;set for drive 2                        CHG009
2338| 123C 0008                     MOVE.B  #$08,D1
233C| E899                          ROR.L   #4,D1
233E| 6100 013E                     BSR     TWGTST          ;and do test again
2342| 6420                          BCC.S   DISINT          ;and continue if OK
2344|
2344| 47FA 1ACA             TSTERR  LEA     TWGFAIL,A3      ;display error msg
2348| 6100 13AC                     BSR     DSPMSGR
234C| 7C0C                          MOVEQ   #PCCOL,D6       ;reset left margin
234E| 0C00 0027                     CMP.B   #TIMOUT,D0      ;timeout error?
2352| 6700 010A                     BEQ     CMDERR          ;exit testing if yes
2356| 5239 00FC C19F                ADDQ.B  #1,DSKCNTL      ;else bump low error count
235C| 6406                          BCC.S   DISINT          ;skip if no overflow
235E| 5239 00FC C19D                ADDQ.B  #1,DSKCNTH      ;else bump high counter also
2364|
2364|                       ;  Disable interrupt so disks can be ejected
2364|
2364| 6100 01AA             DISINT  BSR     TWGDSP          ;display Twiggy error count
2368| 117C 0088 0002                MOVE.B  #$88,CMD(A0)    ;set ptr for both drives
236E| 10BC 0087                     MOVE.B  #DSABLINT,(A0)  ;send disable cmd
2372| 6100 FA90                     BSR     CMDCHK          ;wait until done
2376|
2376|                       ;  Output initial message
2376|
2376| 47FA 1A56             WRTMSG  LEA     BRNMSG,A3       ;get msg ptr
237A| 6100 1384                     BSR     DSPMSG          ;and display it
237E| 1039 00FC C1C3                MOVE.B  CYCLVAL,D0      ;get cycling value
2384| 6100 F2AA                     BSR     DSPDEC          ;display as decimal
2388| 7C0C                          MOVEQ   #PCCOL,D6       ;set col for window limits
238A|                       ;  Increment loop count and display it on screen
238A| 5239 00FC C197        CNTINC  ADDQ.B  #1,LCNTLO       ;inc low byte
2390| 6406                          BCC.S   DSPTIM          ;skip if no carry
2392| 5239 00FC C195                ADDQ.B  #1,LCNTHI       ;else inc high byte also
2398|
2398| 6100 0130             DSPTIM  BSR     DSPCLK          ;go display time
239C|
239C|                       ;  Now check time to see if update needed
239C|
239C| 2038 01BC                     MOVE.L  HOUR,D0         ;get minute value
23A0| E998                          ROL.L   #4,D0
23A2| 4840                          SWAP    D0
23A4| B039 00FC C19B                CMP.B   MINSAV,D0       ;has value changed?
23AA| 6712                          BEQ.S   NOCHG           ;skip if not
23AC| 5239 00FC C1C5                ADDQ.B  #1,MINCNT       ;else bump minute count
23B2| 5239 00FC C1C1                ADDQ.B  #1,CYCLCNT      ;and cycle count
23B8| 13C0 00FC C19B                MOVE.B  D0,MINSAV       ;save new minute value
23BE|
23BE|                       ;  Delay so screen can be read
23BE|
23BE| 6100 E714             NOCHG   BSR     DELAY5          ;delay for 5 secs
23C2|                       ;  Check to see if run should be ended
23C2|
23C2| 1039 00FC C1C1                MOVE.B  CYCLCNT,D0      ;get cycle count
23C8| 1239 00FC C1C3                MOVE.B  CYCLVAL,D1      ;get desired cycle value
23CE| B001                          CMP.B   D1,D0           ;cycle if same or greater
23D0| 6C16                          BGE.S   SHUTDOWN
23D2|
23D2|                       ;  If not, cause double bus fault to restart diagnostics
23D2|                       ;  First make parameter memory valid
23D2|
23D2| 103C 000F                     MOVE.B  #PC,D0          ;set power-cycle boot code
23D6| 6100 F476                     BSR     SAV2PM          ;and go set param mem
23DA| 6100 FC14                     BSR     PROINIT         ;check for attached hard disk   CHG019
23DE| 6604                          BNE.S   @1              ;skip if none                   CHG019
23E0| 6100 FD48                     BSR     WFNBSY2         ;else wait until disk ready     CHG019
23E4| 6000 026C             @1      BRA     DORESET         ;then go cause a system reset
23E8|
23E8|                       ;  Do soft power-off for specified cycle period
23E8|                       SHUTDOWN
23E8| 4239 00FC C199                CLR.B   TIMFLG          ;reset time save indicator
23EE| 2038 01BC                     MOVE.L  CLKDATA+2,D0    ;and save clock data
23F2| 227C 00FC C1A1                MOVE.L  #CLKSAVE,A1
23F8| 01C9 0000                     MOVEP.L D0,(A1)
23FC|
23FC|                       ;  Disable Twiggy controller to avoid any RAM problems
23FC|
23FC|                       DSCONT
23FC| 207C 00FC C001                MOVE.L  #DISKMEM,A0     ;set ptr to shared memory
2402| 10BC 0089                     MOVE.B  #DIE,(A0)       ;and send "die" cmd
2406| 6100 F9FC                     BSR     CMDCHK          ;wait until done
240A| 6552                          BCS.S   CMDERR          ;exit if error
240C|
240C| 702D                          MOVEQ   #$2D,D0         ;enable alarm setting
240E| 6100 E546                     BSR     COPSCMD
2412| 6538                          BCS.S   SETERR2
2414|
2414| 4281                          CLR.L   D1
2416| 1239 00FC C1C3                MOVE.B  CYCLVAL,D1      ;get desired shutdown time
241C| 703C                          MOVEQ   #60,D0          ;multiply by 60 for seconds
241E| C2C0                          MULU    D0,D1
2420| 700C                          MOVEQ   #12,D0          ;rotate to send as alarm value
2422| E1B9                          ROL.L   D0,D1
2424|
2424| 227C 00FC C1B1                MOVE.L  #ALRMSAV,A1
242A| 03C9 0000                     MOVEP.L D1,(A1)         ;save alarm value
242E| 7405                          MOVEQ   #5,D2           ;5 digits for alarm value
2430| 6134                          BSR.S   TODSET
2432| 6518                          BCS.S   SETERR2
2434|
2434|                       ;  Make parameter memory valid
2434| 103C 000F                     MOVE.B  #PC,D0          ;set power-cycle boot code
2438| 6100 F414                     BSR     SAV2PM          ;and go set param mem
243C|                       ;  And finally send power-off cmd
243C| 7023                          MOVEQ   #$23,D0         ;set up enable/power off cmd
243E| 6100 E516                     BSR     COPSCMD         ;send it
2442| 6508                          BCS.S   SETERR2
2444| 4E71                  SELF    NOP
2446| 60FC                          BRA.S   SELF            ;goodbye ...
2448|
2448| 703D                  SETERR1 MOVEQ   #SERR1,D0       ;set error code
244A| 6002                          BRA.S   DSPERR          ;and go display
244C|
244C| 703E                  SETERR2 MOVEQ   #SERR2,D0       ;set error code
244E|
244E|                       DSPERR
244E|                               .IF  USERINT = 0
244E|                               .ELSE
244E| 45FA 14FB                     LEA     IOBRD,A2        ;set icon ptr
2452| 6100 1086                     BSR     DSPERRICON      ;display it
2456|                               .ENDC
2456|
2456| 6100 F1CA                     BSR     DSPCODE
245A| 6000 0140                     BRA     MONITOR         ;and exit to monitor
245E|
245E|                       ;  Error routine if disk cmd not taken
245E|
245E| 08C7 0011             CMDERR  BSET    #DISK,D7        ;set error bit
2462| 6000 EF36                     BRA     TSTCHK          ;and exit
2466|
2466|                               .PAGE
2466|                       ;-------------------------------------------------------------------------
2466|                       ;  Subroutine to send clock data.  Assumes registers:
2466|                       ;       D0 = scratch use
2466|                       ;       D1 = clock data
2466|                       ;       D2 = digit count
2466|                       ;-------------------------------------------------------------------------
2466|
2466| E999                  TODSET  ROL.L   #4,D1           ;get digit
2468| 1001                          MOVE.B  D1,D0           ;set up for COPS as 1X
246A| 0200 000F                     ANDI.B  #$0F,D0         ; where X = digit for clock
246E| 0000 0010                     ORI.B   #$10,D0
2472| 6100 E4E2                     BSR     COPSCMD         ;and send it
2476| 6504                          BCS.S   SETXIT          ;exit if error
2478| 5342                          SUBQ    #1,D2           ;decr count
247A| 66EA                          BNE.S   TODSET          ;and loop until done
247C| 4E75                  SETXIT  RTS
247E|
247E|                               .PAGE
247E|                       ;--------------------------------------------------------------------------
247E|                       ;  Subroutine to do Twiggy testing
247E|                       ;  Expects
247E|                       ;       D0 = scratch use                A0 = shared memory address
247E|                       ;       D1 = drive parameters           A1 = unused
247E|                       ;       D2 = FDIR timeout value         A2 = unused
247E|                       ;       D3 = unused                     A3 = VIA address for FDIR access
247E|                       ;       D4 = loop count for reads
247E|                       ;--------------------------------------------------------------------------
247E|
247E| 117C 0088 0002        TWGTST  MOVE.B  #$88,CMD(A0)    ;enable interrupts from both drives
2484| 10BC 0086                     MOVE.B  #ENBLINT,(A0)   ;do it
2488| 6100 F97A                     BSR     CMDCHK          ;wait until done
248C| 6536                          BCS.S   TERR            ;exit if error
248E| 08AB 0004 0004                BCLR    #FDIR,DDRB1(A3) ;enable FDIR bit
2494| 243C 00C0 0000                MOVE.L  #FDIRTIME,D2    ;set timeout value for FDIR
249A|
249A| 03C8 0004             TWGLOOP MOVEP.L D1,DRV(A0)      ; set disk ptrs
249E| 4228 0002                     MOVE.B  #READS,CMD(A0)  ; set for read operation
24A2| 10BC 0081                     MOVE.B  #EXRW,(A0)      ; and go do it
24A6| 6100 F996                     BSR     CHKFIN          ; wait
24AA| 6516                          BCS.S   TOOLONG         ; exit if timeout
24AC| 1028 0010                     MOVE.B  STAT(A0),D0     ; get disk return code
24B0| 6100 F9C0                     BSR     CLRFDIR         ; clear interrupt indicator
24B4| 650C                          BCS.S   TOOLONG
24B6| 4A00                          TST.B   D0              ;any error?
24B8| 660A                          BNE.S   TERR            ; and exit if error
24BA| 5241                          ADDQ    #1,D1           ;incr track ptr
24BC| 5344                          SUBQ    #1,D4           ;decrement count
24BE| 66DA                          BNE.S   TWGLOOP         ;loop until done
24C0| 4E75                          RTS
24C2|
24C2| 7027                  TOOLONG MOVEQ   #TIMOUT,D0      ;set error code
24C4| 003C 0001             TERR    ORI.B   #$01,CCR        ;set indicator
24C8|
24C8| 4E75                          RTS                     ;and exit
24CA|
24CA|                       ;------------------------------------------------------------------------
24CA|                       ;  Subroutine to display clock reading as D HH MM SS
24CA|                       ;------------------------------------------------------------------------
24CA|
24CA| 47FA 1914             DSPCLK  LEA     TIMMSG,A3       ;get msg ptr
24CE| 6100 1230                     BSR     DSPMSG          ;and display it
24D2| 5246                          ADDQ    #1,D6           ;add extra space
24D4| 6100 EDCA                     BSR     READCLK         ;go read clock
24D8| 2038 01BC                     MOVE.L  CLKDATA+2,D0    ;get time (minus Ey/dd digits)
24DC| 227C 00FC C1A1                MOVE.L  #CLKSAVE,A1     ;and save it
24E2| 01C9 0000                     MOVEP.L D0,(A1)
24E6|
24E6| E998                          ROL.L   #4,D0           ;get day value
24E8| 7201                          MOVEQ   #1,D1           ;set # of digits to display
24EA| 6100 F18C                     BSR     OUTCH           ;and display it
24EE| 5246                          ADDQ    #1,D6           ;bump col ptr
24F0|
24F0| E198                          ROL.L   #8,D0           ;get hour
24F2| 7202                          MOVEQ   #2,D1           ;and display
24F4| 6100 F182                     BSR     OUTCH
24F8| 5246                          ADDQ    #1,D6
24FA|
24FA| E198                          ROL.L   #8,D0           ;display minute
24FC| 7202                          MOVEQ   #2,D1
24FE| 6100 F178                     BSR     OUTCH
2502| 5246                          ADDQ    #1,D6
2504|
2504| E198                          ROL.L   #8,D0           ;display seconds
2506| 7202                          MOVEQ   #2,D1
2508| 6100 F164                     BSR     OUTCHR
250C|
250C|                               .IF  USERINT = 1
250C| 7C0C                          MOVEQ   #PCCOL,D6       ;set col for window
250E|                               .ENDC
250E|
250E| 4E75                          RTS
2510|
2510|
2510|                               .PAGE
2510|                       ;-------------------------------------------------------------------------
2510|                       ;  Subroutine to display Twiggy error count
2510|                       ;-------------------------------------------------------------------------
2510|
2510| 48E7 C010             TWGDSP  MOVEM.L D0-D1/A3,-(SP)  ;save regs
2514| 47FA 190D                     LEA     TWGRSLT,A3      ;output msg
2518| 6100 11E6                     BSR     DSPMSG
251C| 267C 00FC C19D                MOVE.L  #DSKCNTH,A3     ;set ptr to error count
2522| 010B 0000                     MOVEP   (A3),D0         ;get count
2526| 7204                          MOVEQ   #4,D1           ;# of digits to display
2528| 6100 F144                     BSR     OUTCHR
252C|
252C|                               .IF  USERINT = 1
252C| 7C0C                          MOVEQ   #PCCOL,D6       ;set col for window
252E|                               .ENDC
252E|
252E| 4CDF 0803                     MOVEM.L (SP)+,D0-D1/A3  ;restore and exit
2532| 4E75                          RTS
2534|
2534|                               .ENDC
2534|
2534|                               .PAGE
2534|                               .IF  USERINT = 0
2534|                               .ENDC
2534|
2534|
2534|                               .INCLUDE RM248.M.TEXT
2534|
2534|                               .PAGE
2534|                       ;--------------------------------------------------------------------------
2534|                       ;  Monitor code - first displays requested icons, error codes or messages,
2534|                       ;  and then outputs menu of options to user and awaits input
2534|                       ;--------------------------------------------------------------------------
2534|
2534|                       INITMON                           ;entry point for displays
2534|                               .IF  ROM4K = 0
2534| 6100 DB04                     BSR     SAVEREGS          ;save registers
2538| 4287                          CLR.L   D7                ;reset reg for error indicators
253A| 4238 02A2                     CLR.B   STATFLGS          ; and status flags
253E| 08F8 0001 02A2                BSET    #NOCONT,STATFLGS  ;set external entry indicator
2544|
2544|                       INIT1
2544| 48E7 8030                     MOVEM.L D0/A2-A3,-(SP)    ;save incoming arguments
2548| 6100 F7FC                     BSR     DSABLDSK          ;disable ints from both drives
254C| 6100 E55C                     BSR     RSTKBD            ;reset keyboard
2550| 6100 E572                     BSR     CLRRST            ;and clear reset
2554| 6100 0A76                     BSR     CursorInit        ;init cursor and mouse
2558| 4CDF 0C01                     MOVEM.L (SP)+,D0/A2-A3    ;restore arguments
255C|
255C|                       INIT2                           ;internal entry point
255C|                               .IF  DEBUG = 0
255C| 3E7C 0480                     MOVEA   #STKBASE,SP     ;reset stack pointer                    RM000
2560|                               .ENDC
2560|
2560|                               .IF  USERINT = 1
2560| 48E7 8030                     MOVEM.L D0/A2-A3,-(SP)  ;save incoming arguments
2564|                               .ENDC
2564|                               .ENDC                   ;{ROM4K}
2564|
2564| 6100 E320                     BSR     SETVLTCH        ;set video latch
2568|
2568|                               .IF  USERINT = 0
2568|                               .ELSE
2568| 6100 0B6C                     BSR     DRAWDESK        ;display the desktop
256C| 6100 0BFA                     BSR     MAKEALERT       ;draw alert box (in case no icon display)
2570|
2570| 4CDF 0401             INIT3   MOVEM.L (SP)+,D0/A2     ;restore arguments
2574|
2574| 220A                          MOVE.L  A2,D1           ;icon display?
2576| 6704                          BEQ.S   @0              ;skip if no
2578| 6100 0FB2                     BSR     DSPALRTICON     ;go do icon display
257C|
257C| 4A40                  @0      TST     D0              ;error code display?
257E| 6712                          BEQ.S   @2              ;skip if no
2580| 220A                          MOVE.L  A2,D1           ;icon displayed?
2582| 660A                          BNE.S   @1              ;skip if yes
2584| 7A7E                          MOVEQ   #MSGROW,D5      ;else display error code on same line
2586| 7C12                          MOVEQ   #CODECOL,D6     ; as error msg
2588| 6100 F0A6                     BSR     DSPDEC          ;display as decimal #
258C| 6004                          BRA.S   @2
258E|
258E| 6100 F092             @1      BSR     DSPCODE         ;output error code under icon
2592|
2592| 265F                  @2      MOVE.L  (SP)+,A3        ;restore msg ptr
2594|                               .ENDC
2594|
2594| 200B                          MOVE.L  A3,D0           ;message display?
2596| 6704                          BEQ.S   MONITOR
2598|
2598|                               .IF  USERINT = 0
2598|                               .ELSE
2598| 6100 1140                     BSR     DSPALRTMSG      ;go display message in alert box
259C|                               .ENDC
259C|
259C|                       MONITOR                         ;entry point for no screen setup
259C|                               .IF  ROM4K = 0
259C| 007C 0700                     ORI     #$0700,SR       ;disable all interrupts
25A0| 6100 E10A                     BSR     SETVCTRS        ;set vectors for ROM space              CHG028
25A4|                               .ELSE
25A4|                               .ENDC
25A4|
25A4|                               .IF  ROM4K = 0
25A4|                       ;---------------------------------------------------------------------------
25A4|                       ;  Now output first level menu, prompt line and cursor.  Do preliminary
25A4|                       ;  check to see if CONTINUE option can be displayed.  This is the Customer
25A4|                       ;  mode level of the monitor code.
25A4|                       ;---------------------------------------------------------------------------
25A4|
25A4|                       LEVEL1
25A4|                               .IF  USERINT = 1
25A4| 4278 053A                     CLR     RECTCNT         ;clear active rectangle count
25A8| 0238 000F 02A2                ANDI.B  #$0F,STATFLGS   ;init flags
25AE| 08F8 0006 02A2                BSET    #BTN,STATFLGS   ;set operating with buttons flag
25B4|
25B4| 0838 0001 02A2                BTST    #NOCONT,STATFLGS ;display continue?
25BA| 6630                          BNE.S   OTHRBTNS        ;skip if no
25BC| 2038 0180                     MOVE.L  STATUS,D0       ;get test status
25C0| 0280 001E 3FFA                ANDI.L  #CONTMSK,D0     ;mask don't cares
25C6| 661E                          BNE.S   @1              ;skip if error that disallows continuing
25C8| 4A78 0188                     TST     BOOTMEM         ;check boot memory area for R/W errors
25CC| 6618                          BNE.S   @1              ;skip if any errors
25CE|
25CE| 327C 2956                     MOVE    #BTN2STRT,A1    ;display CONTINUE button
25D2| 103C 00F1                     MOVE.B  #KEY2,D0        ;with alternate keycode
25D6| 47FA 18A0                     LEA     CONTMSG,A3      ;and description
25DA| 347C 2CE8                     MOVEA   #BTN2MSG,A2     ;and location                           RM000
25DE| 4281                          CLR.L   D1              ;don't append '...' string
25E0| 6100 0C98                     BSR     MAKEBUTN
25E4| 6006                          BRA.S   OTHRBTNS        ;and go make other buttons
25E6| 08F8 0001 02A2        @1      BSET    #NOCONT,STATFLGS ;set indicator for no CONTINUE option
25EC|
25EC|                       OTHRBTNS
25EC|                               .ENDC
25EC|
25EC|                       DOMENU
25EC|                               .IF  USERINT = 0
25EC|                               .ELSE
25EC| 0838 0000 02A2                BTST    #NORSTRT,STATFLGS ;display RESTART button?
25F2| 6616                          BNE.S   @1                ;skip if not
25F4| 327C 1876                     MOVE    #BTN1STRT,A1      ;else do display
25F8| 103C 00F4                     MOVE.B  #KEY1,D0
25FC| 47FA 185A                     LEA     RTRYMSG,A3
2600| 347C 1C08                     MOVEA   #BTN1MSG,A2     ;                                       RM000
2604| 4281                          CLR.L   D1              ;don't append '...' string
2606| 6100 0C72                     BSR     MAKEBUTN
260A|
260A| 327C 3A36             @1      MOVE    #BTN3STRT,A1    ;display STARTUP button
260E| 303C 00F2                     MOVE    #KEY3,D0
2612| 47FA 1884                     LEA     STRTMSG,A3
2616| 347C 3DC8                     MOVEA   #BTN3MSG,A2     ;                                       RM000
261A| 72FF                          MOVEQ   #-1,D1          ;append '...' string
261C| 6100 0C5C                     BSR     MAKEBUTN
2620|
2620|                       ;        MOVE.L  #KBDBFR,KBDQPTR ;init queue ptr
2620|
2620| 6100 09EC                     BSR     CursorDisplay   ;display mouse cursor
2624| 08F8 0005 02A2                BSET    #CHKCMD,STATFLGS ;require user keyboard input to be prefaced
262A|                                                        ; by the CMD key
262A| 6100 061A             GETL1   BSR     GETINPUT        ;and go wait for input
262E| 6500 00B6                     BCS     GETERR          ;exit if error
2632| 6100 09B6                     BSR     CursorHide      ;remove cursor from screen
2636|
2636|                               .ENDC
2636|
2636|
2636|                       ;  Check if input valid.  If invalid, beep speaker.
2636|
2636| 0C00 00F2                     CMP.B   #KEY3,D0        ;alternate boot?
263A| 6608                          BNE.S   @2
263C|
263C|                               .IF  USERINT = 0
263C|                               .ELSE
263C| 6100 0A9C                     BSR     CLRDESK         ;close the alert box
2640| 6000 F2B6                     BRA     BOOTMENU        ;and go display boot menu
2644|                               .ENDC
2644|
2644| 0838 0000 02A2        @2      BTST    #NORSTRT,STATFLGS ;RESTART button displayed?
264A| 6612                          BNE.S   CONTCHK           ;skip if not
264C| 0C00 00F4                     CMP.B   #KEY1,D0        ;retry?
2650| 660C                          BNE.S   CONTCHK         ;skip if not
2652|
2652|                       DORESET
2652| 4287                          CLR.L   D7              ;clear error reg                        RM000
2654| 4A39 00FC E010                TST.B   SETUPON         ;turn on setup bit                      RM000
265A| 6000 DB2E                     BRA     BEGIN3          ;and restart diags                      RM000
265E|
265E|                       CONTCHK
265E|                               .IF  USERINT = 1
265E| 0838 0001 02A2                BTST    #NOCONT,STATFLGS ;continue option displayed?
2664| 666C                          BNE.S   @4              ;skip if not
2666| 0C00 00F1                     CMP.B   #KEY2,D0        ;continue option selected?
266A| 6666                          BNE.S   @4
266C|
266C|                       ;  continue from point of failure
266C|
266C| 6100 0A6C                     BSR     CLRDESK         ;clear desktop                          CHG008
2670| 0287 7000 0000                ANDI.L  #ALTBMSK,D7     ;erase error indicators
2676| 2038 0180                     MOVE.L  STATUS,D0       ;get power-up status
267A| 0800 0000                     BTST    #MMU,D0         ;MMU error?
267E| 6600 E100                     BNE     VIA2TST         ;yes - continue from VIA tests
2682|
2682| 0280 008F FFFF                ANDI.L  #BOOTMSK,D0     ;check if error that continues to boot attempt
2688| 6700 F05C                     BEQ     BOOTCHK         ;skip if yes
268C| 2F00                          MOVE.L  D0,-(SP)        ;else save status
268E| 6100 0AF0                     BSR     MAKETEST        ;make test window
2692|
2692|                       ;  do init for continue to other tests
2692| 103C 0070                     MOVE.B  #$70,D0         ;turn off mouse
2696| 6100 E2BE                     BSR     COPSCMD
269A| 201F                          MOVE.L  (SP)+,D0        ;restore status
269C|
269C| 0800 0002                     BTST    #VID,D0         ;serial # error?
26A0| 670C                          BEQ.S   @1              ;skip if not
26A2| 327C 1DF6                     MOVEA   #CPUSTRT,A1     ;display CPU icon
26A6| 6100 0ECC                     BSR     INVICON
26AA| 6000 E6B0                     BRA     PARTST          ;continue with parity test
26AE|
26AE| EE88                  @1      LSR.L   #7,D0           ;skip other CPU errors
26B0| 4A00                          TST.B   D0              ;clock error?
26B2| 6600 EC3A                     BNE     CONFIG          ;yes - continue with config check
26B6|
26B6| E488                          LSR.L   #2,D0
26B8| 4A00                          TST.B   D0              ;RS232 error?
26BA| 670C                          BEQ.S   @2              ;skip if not
26BC| 327C 1E12                     MOVEA   #IOSTRT,A1      ;else display I/O board icon
26C0| 6100 0EB2                     BSR     INVICON
26C4| 6000 EA46                     BRA     DSKTST          ;cont with disk test
26C8|
26C8| 4A39 00FC E01E        @2      TST.B   PARON           ;must be memory error - reenable parity
26CE| 6000 E930                     BRA     IOTST           ; and continue with I/O board testing
26D2|
26D2|                               .ENDC
26D2|                       @4
26D2|                               .IF  USERINT = 0
26D2|                               .ENDC
26D2|
26D2| 0C00 00F6                     CMP.B   #SKEY,D0        ; service mode desired?
26D6| 6700 0064                     BEQ     LEVEL2          ; skip if yes
26DA|
26DA|                       ;  Indicate invalid by beeping speaker
26DA|
26DA|                       GETL1XIT
26DA| 6100 0030                     BSR     SQUAWK          ; sorry charlie
26DE|                               .IF  USERINT = 0
26DE|                               .ELSE
26DE|                       LEV1LOOP
26DE| 6100 092E                     BSR     CursorDisplay   ;redisplay cursor
26E2| 6000 FF46                     BRA.S   GETL1           ;go get more input
26E6|
26E6|                       ;  Error exit - go output error and return to level 1
26E6|
26E6|                       GETERR
26E6| 45FA 1263                     LEA     IOBRD,A2        ;get I/O board icon
26EA| 97CB                          SUBA.L  A3,A3           ;no error message
26EC| 6000 FE6E                     BRA     INIT2
26F0|                               .ENDC
26F0|
26F0|                               .ENDC                   ;{ROM4K}
26F0|                               .PAGE
26F0|                       ;-------------------------------------------------------------------------
26F0|                       ;  Subroutine to clear video page of memory or write arbitrary long word
26F0|                       ;  pattern to entire screen (WRTSCRN entry point).
26F0|                       ;-------------------------------------------------------------------------
26F0|
26F0| 4280                  CLRSCRN CLR.L   D0              ; write 0's for white screen
26F2|                       WRTSCRN                         ; entry pt for write to screen (assumes D0 set)
26F2| 2078 0110                     MOVE.L  SCRNBASE,A0     ; get screen base address
26F6| 323C 1FFD                     MOVE    #HEX8K-3,D1     ; set longs count
26FA| 20C0                  @1      MOVE.L  D0,(A0)+           ; clear for video page
26FC| 51C9 FFFC                     DBF     D1,@1
2700| 4E75                          RTS
2702|
2702|                               .IF  ROM4K = 0
2702|                               .IF  USERINT = 0
2702|                               .ENDC
2702|                               .PAGE
2702|                               .IF  USERINT = 0
2702|                               .ELSE
2702|                       ;-------------------------------------------------------------------------
2702|                       ;  Subroutine to read keycode from COPS - returns down transitions in D0
2702|                       ;-------------------------------------------------------------------------
2702|
2702|                       ReadKey
2702| 6100 0634                     BSR     WT4INPUT
2706| 4A00                          TST.B   D0              ;ignore "up" transitions and mouse data
2708| 6AF8                          BPL.S   ReadKey
270A| 4E75                          RTS                     ;exit with data
270C|
270C|                               .ENDC
270C|
270C|                       ;-------------------------------------------------------------------------
270C|                       ;  Subroutine to beep speaker for invalid input
270C|                       ;-------------------------------------------------------------------------
270C|
270C| 7020                  SQUAWK  MOVEQ   #$20,D0         ; set frequency
270E| 323C 00FA                     MOVE    #250,D1         ; 1/8 sec duration
2712| 7404                          MOVEQ   #4,D2           ; low volume
2714| 6100 E3E0                     BSR     TONE            ; and go do it
2718| 4E75                          RTS
271A|
271A|                       ;-------------------------------------------------------------------------
271A|                       ;  Subroutine to convert keycodes to Ascii
271A|                       ;  Inputs:  D0 = keycode (word)
271A|                       ;  Outputs: D0 = Ascii (byte) or =2 if input invalid
271A|                       ;-------------------------------------------------------------------------
271A|
271A|                       KeyToAscii
271A| 48E7 4080                     MOVEM.L D1/A0,-(SP)     ;save regs
271E| 41FA 119C                     LEA     AsciiTable,A0   ;keycode to ascii table
2722| 3200                          MOVE    D0,D1           ;keycode to convert
2724| 0241 007F                     ANDI    #$007F,D1       ;ensure valid
2728| 0441 0020                     SUBI    #32,D1          ;decrement for table                    RM000
272C| 6A04                          BPL.S   @1              ;skip if valid                          RM000
272E| 7002                          MOVEQ   #2,D0           ;else set for invalid char              RM000
2730| 6004                          BRA.S   @2              ;                                       RM000
2732| 1030 1000             @1      MOVE.B  0(A0,D1.W),D0   ;get ascii
2736| 4CDF 0102             @2      MOVEM.L (SP)+,D1/A0     ;restore
273A| 4E75                          RTS                     ;exit
273C|
273C|
273C|                               .PAGE
273C|                       ;-------------------------------------------------------------------------
273C|                       ;  Monitor level 2 (Service mode) - enables access to memory and disk
273C|                       ;-------------------------------------------------------------------------
273C|
273C|                       LEVEL2
273C|                               .IF  USERINT = 0
273C|                               .ELSE
273C| 6100 099C                     BSR     CLRDESK         ;display the desktop
2740|
2740|                               .IF  BMENU = 0
2740|                               .ENDC
2740|
2740|                       ;  make window for output, and display menu line and pull down menu
2740|
2740| 6100 00D2                     BSR     MAKESVCW        ;output service window
2744| 6100 005A             DSPMENU BSR     WRTMENU
2748|
2748|                       ;  do final initialization and await input
2748|
2748| 6100 08C4                     BSR     CursorDisplay   ;display cursor
274C|                       ;----------------------------------------------------------------------
274C|                       ;  Program NMI key
274C|                       ;
274C|                       ;        MOVEQ   #$5A,D0         ;set / key for NMI
274C|                       ;        BSR     COPSCMD
274C|                       ;        MOVEQ   #$61,D0
274C|                       ;        BSR     COPSCMD
274C|                       ;----------------------------------------------------------------------
274C|
274C|                       GETLEV2
274C| 6100 04F8                     BSR     GETINPUT        ;and go await input
2750| 6594                          BCS     GETERR          ;exit if error
2752| 6100 0896                     BSR     CursorHide      ;else remove cursor from screen and go
2756|                                                       ; analyze input
2756|
2756|                               .ENDC
2756|
2756|                               .IF  USERINT = 0
2756|                               .ENDC
2756|
2756|                       ;  Check for valid input
2756|
2756| 0C00 00F4                     CMP.B   #KEY1,D0        ; display memory?
275A| 6700 00DA                     BEQ     DSPMEM
275E| 0C00 00F1                     CMP.B   #KEY2,D0        ; set memory?
2762| 6700 013E                     BEQ     SETMEM
2766|
2766| 0C00 00F2                     CMP.B   #KEY3,D0        ; call routine
276A| 6700 019C                     BEQ     CALLRTN
276E|
276E|                               .IF  ROM16K = 1
276E| 0C00 00F3                     CMP.B   #KEY4,D0        ; loop?
2772| 6700 01C0                     BEQ     LOOPTST
2776|                               .ENDC
2776|
2776| 0C00 00E4                     CMP.B   #KEY5,D0        ; video adjust?
277A| 6700 0278                     BEQ     VIDAJST
277E|
277E|                               .IF  BURNIN = 1
277E| 0C00 00E1                     CMP.B   #KEY6,D0        ; power cycle?
2782| 6700 02E8                     BEQ     PowerCycle
2786|                               .ENDC
2786|
2786| 0C00 00E2                     CMP.B   #KEY7,D0        ; quit?
278A| 6610                          BNE.S   @1
278C| 08B8 0000 02A2                BCLR    #NORSTRT,STATFLGS ;clear no reset status flag
2792| 4280                          CLR.L   D0                ;set parms for level1 - no error code
2794| 95CA                          SUBA.L  A2,A2             ;no icon display
2796| 97CB                          SUBA.L  A3,A3             ;no message display
2798| 6000 FDC2                     BRA     INIT2             ;and go back to level1
279C|
279C| 6000 02D6             @1      BRA     INVALID         ; else invalid input
27A0|
27A0|                               .PAGE
27A0|                               .IF  USERINT = 1
27A0|                       ;---------------------------------------------------------------------------
27A0|                       ;  Routine to display the preliminary pull-down menu
27A0|                       ;---------------------------------------------------------------------------
27A0|
27A0|                       WRTMENU
27A0|                               .IF  BMENU = 0
27A0|                               .ELSE
27A0| 4278 053A                     CLR     RectCnt         ;clear active rectangle count
27A4| 0238 000F 02A2                ANDI.B  #$0F,STATFLGS   ;init flags
27AA| 7012                          MOVEQ   #MENUWIDTH,D0   ;set menu parms
27AC| 7207                          MOVEQ   #MITEMS,D1      ;set # of items in menu
27AE| C2FC 000B                     MULU    #MENULEN,D1     ;length depends on # of items
27B2| 47FA 170D                     LEA     MENUHDG,A3      ;set ptr for menu heading
27B6| 6118                          BSR.S   DSPMENUBOX      ;go display blank menu box w/ heading
27B8|
27B8| 7807                          MOVEQ   #MITEMS,D4      ;set # of items in menu
27BA| 327C 05A2                     MOVE    #MENUSTRT,A1    ;set menu starting point
27BE| 347C 0658                     MOVE    #MENU1MSG,A2    ;menu items display address
27C2| 47FA 1705                     LEA     DISPMSG,A3      ;set ptr to menu entries
27C6| 49FA 1771                     LEA     MENUID,A4       ;ptr to id's for menu entries
27CA| 6100 0B9E                     BSR     MAKEMENU        ;go fill in the menu
27CE|
27CE|                               .ENDC                   ;{MENU}
27CE|
27CE| 4E75                          RTS
27D0|
27D0|                               .IF  BMENU = 1
27D0|                       ;---------------------------------------------------------------------------
27D0|                       ;  Subroutine to display blank menu box with heading
27D0|                       ;  Inputs:
27D0|                       ;       D0 = menu width
27D0|                       ;       D1 = menu length
27D0|                       ;       A3 = menu heading
27D0|                       ;  Outputs:
27D0|                       ;       None
27D0|                       ;  Side Effects:
27D0|                       ;       D2/A1,A3 trashed
27D0|                       ;---------------------------------------------------------------------------
27D0|
27D0|                       DSPMENUBOX
27D0| 48E7 C000                     MOVEM.L D0-D1,-(SP)     ;save regs
27D4| 08F8 0007 02A2                BSET    #MENU,STATFLGS  ;set working with menu flag
27DA| 6100 0938                     BSR     CLRMENU         ;first clear the menu bar
27DE| 5441                          ADDQ    #2,D1           ;bump length for bottom border
27E0| 327C 05A2                     MOVE    #MENUSTRT,A1    ;set menu starting point
27E4| 6100 0A00                     BSR     MAKEBOX         ;display the box
27E8| 327C 0111                     MOVEA   #MENULOC,A1     ;set up menu heading display point
27EC| 6100 0C18                     BSR     GETROWCOL       ;convert to screen ptrs
27F0|
27F0| 4281                          CLR.L   D1              ;don't display '...' string
27F2| 6100 0E40                     BSR     DSPSTRING       ;display the title
27F6| 97CA                          SUBA.L  A2,A3           ;get length of menu title
27F8| 240B                          MOVE.L  A3,D2           ;move to working reg
27FA| 5442                          ADDQ    #2,D2           ;add extra bytes to cover entire title
27FC| 0202 00FE                     ANDI.B  #$FE,D2         ;ensure it's even
2800| 3002                          MOVE    D2,D0           ;save as width of menu heading "box"
2802| 720E                          MOVEQ   #14,D1          ;set height for "box"
2804| 74FF                          MOVEQ   #-1,D2          ;set fill pattern
2806| 92FC 005B                     SUB.W   #91,A1          ;decrement start pt by 1 row + 1 byte
280A| 6100 0922                     BSR     INVERSE         ;go hilite it
280E| 4CDF 0003                     MOVEM.L (SP)+,D0-D1     ;restore regs
2812| 4E75                          RTS
2814|
2814|                               .ENDC                   ;{MENU}
2814|
2814|                       ;---------------------------------------------------------------------------
2814|                       ;  Subroutine to create Service mode window
2814|                       ;---------------------------------------------------------------------------
2814|
2814|                       MAKESVCW
2814| 327C 0EDA                     MOVEA   #SVCSTRT,A1     ;left corner point                      RM000
2818| 7042                          MOVEQ   #SVCWIDTH,D0    ;width of window
281A| 223C 0000 0140                MOVE.L  #SVCHIGH,D1     ;height
2820| 47FA D830                     LEA     SVCMSG,A3       ;title
2824| 6100 09A0                     BSR     MAKEWINDOW      ;go do it
2828| 31FC 003E 0300                MOVE    #FIRSTROW,CRTROW ;init screen ptrs
282E| 31FC 0018 0302                MOVE    #FIRSTCOL,CRTCOL
2834| 4E75                          RTS
2836|
2836|                               .ENDC                   ;{USERINT}
2836|
2836|                       ;---------------------------------------------------------------------------
2836|                       ;  Do display memory operation
2836|                       ;---------------------------------------------------------------------------
2836|
2836| 6100 036C             DSPMEM  BSR     GETA            ;go get address
283A| 6500 0238                     BCS     INVALID
283E| 4A43                          TST     D3              ;if no input go back to menu line
2840|
2840|                               .IF  USERINT = 0
2840|                               .ELSE
2840| 6700 0240                     BEQ     LEV2LOOP
2844|                               .ENDC
2844|
2844| 0882 0000                     BCLR    #0,D2           ;ensure even address
2848| 2442                          MOVE.L  D2,A2           ;and save
284A|
284A|                       ;  Check for all input on one line
284A| 6100 034A                     BSR     GETCH           ;read queue to see if more input
284E| 6506                          BCS.S   @1              ;skip if not
2850| 0C00 0020                     CMPI.B  #' ',D0         ;must be a space separator
2854| 6708                          BEQ.S   RDCNT           ;skip if yes
2856|
2856| 47FA 1774             @1      LEA     CNTMSG,A3       ;display count prompt
285A| 6100 0236                     BSR     PROMPT
285E|
285E|                       ;  Decode count input and do display
285E|
285E| 7204                  RDCNT   MOVEQ   #4,D1           ;go get count (max of $FFFF)
2860| 6100 0350                     BSR     GETPARM
2864| 6500 020E                     BCS     INVALID
2868| 6100 02E6                     BSR     PUTLF           ;set display ptrs and space 1 line
286C| 4A43                          TST     D3              ;set default count if no input
286E| 6702                          BEQ.S   @4
2870| 6002                          BRA.S   @5
2872|
2872| 7410                  @4      MOVEQ   #16,D2          ;set default count
2874|
2874|                       ;  Do display of memory
2874|
2874| 200A                  @5      MOVE.L  A2,D0           ;get display address
2876| 7208                          MOVEQ   #8,D1           ;and display it
2878| 6100 EDFE                     BSR     OUTCH
287C|
287C|                               .IF  USERINT = 0
287C|                               .ELSE
287C| 5846                          ADDQ    #4,D6           ;bump col for data display
287E|                               .ENDC
287E| 7808                          MOVEQ   #8,D4           ;set loop count
2880| 301A                  @6      MOVE    (A2)+,D0        ;read data word
2882| 7204                          MOVEQ   #4,D1           ;display it
2884| 6100 EDF2                     BSR     OUTCH
2888| 5246                          ADDQ    #1,D6           ;add space
288A| 5344                          SUBQ    #1,D4           ;loop for one line
288C| 66F2                          BNE.S   @6
288E|
288E| 5182                          SUBQ.L  #8,D2           ;decr data count                        RM000
2890| 5182                          SUBQ.L  #8,D2           ;                                       RM000
2892| 6F06                          BLE.S   @7              ;exit if done
2894| 6100 02BA                     BSR     PUTLF           ;go to next line
2898| 60DA                          BRA.S   @5              ;and continue until done
289A|
289A| 6100 02B4             @7      BSR     PUTLF           ;add blank line
289E|
289E|                               .IF  USERINT = 0
289E|                               .ELSE
289E| 6000 01E2                     BRA     LEV2LOOP        ;continue level2 loop
28A2|                               .ENDC
28A2|
28A2|                               .PAGE
28A2|                       ;---------------------------------------------------------------------------
28A2|                       ;  Do set memory operation - enables setting of bytes, words or longs
28A2|                       ;  up to 24 bytes max.  Decodes data length to determine type of operation.
28A2|                       ;---------------------------------------------------------------------------
28A2|
28A2| 6100 0300             SETMEM  BSR     GETA            ;go get address
28A6| 6500 01CC                     BCS     INVALID         ;abort if invalid
28AA| 4A43                          TST     D3              ;any input?
28AC|
28AC|                               .IF  USERINT = 0
28AC|                               .ELSE
28AC| 6700 01D4                     BEQ     LEV2LOOP        ;abort if none
28B0|                               .ENDC
28B0|
28B0| 2442                          MOVE.L  D2,A2           ;save target address
28B2|                       ;  Check for all input on one line
28B2|
28B2| 6100 02E2                     BSR     GETCH           ;read queue to see if more input
28B6| 6506                          BCS.S   @1              ;skip if not
28B8| 0C00 0020                     CMPI.B  #' ',D0         ;must be a space separator
28BC| 6708                          BEQ.S   RDDTA           ;skip if yes
28BE|
28BE| 47FA 1705             @1      LEA     DATAMSG,A3      ;else output data prompt
28C2| 6100 01CE                     BSR     PROMPT
28C6|
28C6|                       ;  Decode parameter input and do operation
28C6| 7208                  RDDTA   MOVEQ   #8,D1           ;get max of 8 chars
28C8| 6100 02E8                     BSR     GETPARM
28CC| 6500 01A6                     BCS     INVALID
28D0| 4A43                          TST     D3              ;any input?
28D2|
28D2|                               .IF  USERINT = 0
28D2|                               .ELSE
28D2| 6700 01AE                     BEQ     LEV2LOOP
28D6|                               .ENDC
28D6|
28D6|                       ;  write data to memory
28D6|
28D6| 0C03 0002                     CMP.B   #2,D3           ;first test for byte operation
28DA| 6E04                          BGT.S   @1
28DC| 14C2                          MOVE.B  D2,(A2)+        ;write byte
28DE| 6014                          BRA.S   @3
28E0| 200A                  @1      MOVE.L  A2,D0           ;ensure even address for word or long op
28E2| 0880 0000                     BCLR    #0,D0
28E6| 2440                          MOVE.L  D0,A2
28E8| 0C03 0004                     CMP.B   #4,D3           ;test for word op
28EC| 6E04                          BGT.S   @2
28EE| 34C2                          MOVE    D2,(A2)+        ;write word
28F0| 6002                          BRA.S   @3
28F2|
28F2| 24C2                  @2      MOVE.L  D2,(A2)+        ;write long
28F4|
28F4| 6100 02A0             @3      BSR     GETCH           ;read input queue
28F8| 650A                          BCS.S   @4              ;skip if none
28FA| 0C00 0020                     CMPI.B  #' ',D0         ;must be a space separator
28FE| 6600 0174                     BNE     INVALID         ;exit if error
2902| 60C2                          BRA.S   RDDTA           ;else continue operation
2904|
2904|                       @4
2904|                               .IF  USERINT = 0
2904|                               .ELSE
2904| 6000 017C                     BRA     LEV2LOOP        ;continue level2 loop
2908|                               .ENDC
2908|
2908|                               .PAGE
2908|                       ;---------------------------------------------------------------------------
2908|                       ;  Do 'call' function - ensures address is on word boundary.
2908|                       ;---------------------------------------------------------------------------
2908|
2908| 6100 029A             CALLRTN BSR     GETA            ;go get address
290C| 6500 0166                     BCS     INVALID
2910| 4A43                          TST     D3              ;abort if no input
2912|
2912|                               .IF  USERINT = 0
2912|                               .ELSE
2912| 6700 016E                     BEQ     LEV2LOOP        ;continue level2 loop
2916|                               .ENDC
2916|
2916| 0882 0000                     BCLR    #0,D2           ;else ensure on word boundary
291A| 21C2 01F8                     MOVE.L  D2,A6SAV        ;save for jump
291E|
291E|                       ;  load registers from save area before jumping
291E|
291E| 4DF8 01C0                     LEA     DATARGS,A6      ;get ptr
2922| 4CDE 3FFF                     MOVEM.L (A6)+,D0-D7/A0-A5  ;load regs
2926| 2C78 01F8                     MOVE.L  A6SAV,A6        ;restore address
292A| 4E96                          JSR     (A6)            ;and do call
292C| 6100 D70C                     BSR     SAVEREGS        ;save registers on exit
2930|
2930|                               .IF  USERINT = 0
2930|                               .ELSE
2930| 6000 0150                     BRA     LEV2LOOP        ;continue level2 loop
2934|                               .ENDC
2934|
2934|                               .IF     ROM16K = 1
2934|                               .PAGE
2934|                       ;---------------------------------------------------------------------------
2934|                       ;  Do loop on diagnostic
2934|                       ;---------------------------------------------------------------------------
2934|
2934|                       LOOPTST
2934|                               .IF USERINT = 1
2934| 6100 FEDE                     BSR     MAKESVCW        ;redraw service window
2938| 6100 0216                     BSR     PUTLF           ;add blank line and setup ptrs
293C| 47FA 1602                     LEA     TSTMENU,A3      ;set ptr to test choices
2940| 7818                          MOVEQ   #FIRSTCOL,D4    ;set left margin
2942| 6100 0DBC                     BSR     DSPMSG          ;and go do display choices
2946|                               .ENDC
2946|
2946| 47FA 168C                     LEA     TSTMSG,A3       ;display test routine prompt
294A| 6100 0146                     BSR     PROMPT
294E| 6500 0124                     BCS     INVALID         ;skip if bad input
2952| 4A43                          TST     D3              ;any input?
2954|
2954|                               .IF  USERINT = 0
2954|                               .ELSE
2954| 6608                          BNE.S   @0              ;skip if yes
2956| 6100 FEBC                     BSR     MAKESVCW        ;else redraw service window
295A| 6000 0126                     BRA     LEV2LOOP        ;and return to level 2
295E|                               .ENDC
295E|
295E| 5343                  @0      SUBQ    #1,D3           ;ensure only one char input
2960| 6600 0112                     BNE     INVALID         ;skip if more than one
2964|
2964| 7201                          MOVEQ   #1,D1           ;go get one character of input
2966| 6100 024A                     BSR     GETPARM
296A| 0C02 000C                     CMP.B   #MAXTEST,D2     ;check if within max range
296E| 6200 0104                     BHI     INVALID         ;exit if not
2972| 5342                          SUBQ    #1,D2           ;decr for index
2974| 6B00 00FE                     BMI     INVALID         ;skip if negative (i.e., 0 was input)
2978|
2978|                       ;----------------------------------------------------------------------------
2978|                       ;  Program NMI key to exit loop
2978|                       ;
2978|                       ;        LEA     LOOPEND,A3      ;set NMI vector
2978|                       ;        MOVE.L  A3,NMIVCT
2978|                       ;        MOVEQ   #$5A,D0         ;set / key for NMI
2978|                       ;        BSR     COPSCMD
2978|                       ;        MOVEQ   #$61,D0
2978|                       ;        BSR     COPSCMD
2978|                       ;----------------------------------------------------------------------------
2978|
2978|                               .IF  USERINT = 1
2978|
2978|                               .IF  FULLSCC = 0
2978|                               .ENDC
2978|
2978| 2F02                          MOVE.L  D2,-(SP)        ;save test #
297A| 6100 075E                     BSR     CLRDESK         ;clear desktop except for menu bar
297E| 6100 0800                     BSR     MAKETEST        ;draw test window
2982| 241F                          MOVE.L  (SP)+,D2        ;restore test #
2984| 0C02 0004                     CMP.B   #4,D2           ;CPU test?
2988| 6C06                          BGE.S   @1              ;skip if not
298A| 327C 1DF6                     MOVEA   #CPUSTRT,A1     ;else set ptr for CPU board icon                RM000
298E| 601C                          BRA.S   @4              ;and go hilite it
2990|
2990| 0C02 000A             @1      CMP.B   #10,D2          ;I/O board test?
2994| 6C06                          BGE.S   @2
2996| 327C 1E12                     MOVEA   #IOSTRT,A1      ;set ptr for I/O board icon                     RM000
299A| 6010                          BRA.S   @4
299C|
29A0| 6C06                          BGE.S   @31,D2          ;memory test?
29A2| 327C 1E04                     MOVEA   #MEMSTRT,A1     ;set ptr for memory board icon                  RM000
29A6| 6004                          BRA.S   @4
29A8| 327C 1E20             @3      MOVEA   #XCRDSTRT,A1    ;else must be I/O slot card                     RM000
29AC|
29AC| 6100 0BC6             @4      BSR     INVICON         ;display in test window
29B0|                               .ENDC
29B0|
29B0| D442                          ADD     D2,D2           ;double test # for table index
29B2| 08C7 001F                     BSET    #LOOP,D7        ;set loop flag
29B6| 41FA 0024                     LEA     LOOPTBL,A0      ;and jump to requested routine
29BA| D0F0 2000                     ADD     0(A0,D2.W),A0
29BE| 4ED0                          JMP     (A0)
29C0|
29C0|                       ;---------------------------------------------------------------------------
29C0|                       ;  Loop exit via NMI routine
29C0|                       ;
29C0|                       ;LOOPEND BTST    #1,STATREG      ;parity error?
29C0|                       ;        BEQ     NMI             ;skip if yes to report error
29C0|                       ;        MOVE.L  #STKBASE,SP     ;else restore stack
29C0|                       ;        BRA     LEVEL2          ;and redisplay service mode
29C0|                       ;---------------------------------------------------------------------------
29C0|
29C0|                       ;  special entry points for routines that require initial setup
29C0|
29C0|                       MMUTSTE1
29C0| 4A39 00FC E010                TST.B   SETUPON         ;turn on SETUP bit for MMU tests
29C6| 6000 D7E8                     BRA     MMUTST          ;go do main test
29CA|
29CA|                               .IF  FULLSCC = 0
29CA|                               .ENDC
29CA|
29CA| 08F9 0006 00FC C18D   MEMTST3 BSET    #6,MEMCODE      ;set for extended memory test
29D2| 7002                          MOVEQ   #PROFILE,D0     ;and for normal boot default (Profile)
29D4| 6100 EE78                     BSR     SAV2PM          ;save in parameter memory
29D8| 6000 E434                     BRA     MEMLOOP         ;and go do memory testing
29DC|
29DC|                       ;  jump table for looping on start-up diagnostics
29DC|
29DC| D7B8                  LOOPTBL .WORD   ROMTST-LOOPTBL          ;1 = ROM checksum test
29DE| FFE4                          .WORD   MMUTSTE1-LOOPTBL        ;2 = MMU test
29E0| E1C6                          .WORD   VIDCHK-LOOPTBL          ;3 = Video test
29E2| E380                          .WORD   PARTST-LOOPTBL          ;4 = Parity logic test
29E4| DDA4                          .WORD   VIA2TST-LOOPTBL         ;5 = Parallel port VIA test
29E6| DED4                          .WORD   VIA1CHK-LOOPTBL         ;6 = Keyboard port VIA test
29E8| DF0E                          .WORD   COPSENBL-LOOPTBL        ;7 = I/O board COPS test
29EA|
29EA|                               .IF  FULLSCC = 1
29EA| E62C                          .WORD   SCCTEST-LOOPTBL         ;8 = SCC test
29EC|                               .ELSE
29EC|                               .ENDC
29EC|
29EC| E730                          .WORD   DSKTST-LOOPTBL          ;9 = disk controller test
29EE| E8B0                          .WORD   CLKTST-LOOPTBL          ;A = clock test
29F0| FFEE                          .WORD   MEMTST3-LOOPTBL         ;B = memory test
29F2| E91A                          .WORD   CONFIG2-LOOPTBL         ;C = configuration check
29F4|
29F4|                               .ENDC
29F4|                               .PAGE
29F4|                       ;---------------------------------------------------------------------------
29F4|                       ;  Display video adjust pattern
29F4|                       ;---------------------------------------------------------------------------
29F4|
29F4| 70FF                  VIDAJST MOVEQ   #-1,D0          ;first erase the screen
29F6| 6100 FCFA                     BSR     WRTSCRN
29FA|
29FA|                       ;  Next draw the horizontal lines
29FA|
29FA| 4280                          CLR.L   D0              ;set scan line
29FC| 6128                          BSR.S   DRWHORZ         ;go draw white line
29FE| 701B                          MOVEQ   #27,D0          ;set next scan line
2A00| 721C                          MOVEQ   #28,D1          ;set increment value also
2A02| 740C                          MOVEQ   #12,D2          ;set line count
2A04| 6120                  @1      BSR.S   DRWHORZ         ;draw some more
2A06| D041                          ADD     D1,D0           ;incr to next line position
2A08| 51CA FFFA                     DBF     D2,@1           ;loop until done
2A0C|
2A0C|                       ;  Now draw the vertical lines
2A0C|
2A0C| 4280                          CLR.L   D0              ;set pixel #
2A0E| 6130                          BSR.S   DRWVERT         ;draw a vertical line
2A10| 702C                          MOVEQ   #44,D0          ;set next pixel position
2A12| 722D                          MOVEQ   #45,D1          ;set incr value also
2A14| 740F                          MOVEQ   #15,D2          ;set line count
2A16| 6128                  @2      BSR.S   DRWVERT         ;draw some more
2A18| D041                          ADD     D1,D0           ;incr to next pixel position
2A1A| 51CA FFFA                     DBF     D2,@2           ;loop until done
2A1E|
2A1E|                       ;  Wait for any keystroke to terminate display
2A1E|
2A1E| 6100 FCE2                     BSR     READKEY
2A22| 6000 FD18                     BRA     LEVEL2          ;return to menu display
2A26|
2A26|                               .PAGE
2A26|                       ;----------------------------------------------------------------------------
2A26|                       ;  Subroutine to draw horizontal lines.  Requires inputs:
2A26|                       ;    D0 = scan line (0 to 363 decimal)
2A26|                       ;    $110 = base address of screen
2A26|                       ;----------------------------------------------------------------------------
2A26|
2A26| 48E7 C080             DRWHORZ MOVEM.L D0/D1/A0,-(SP)  ;save regs
2A2A| 725A                          MOVEQ   #90,D1          ;line length in bytes
2A2C| C0C1                          MULU    D1,D0           ;compute address offset
2A2E| 2078 0110                     MOVE.L  SCRNBASE,A0     ;get base screen address
2A32| D1C0                          ADDA.L  D0,A0           ;add offset
2A34| 4218                  @1      CLR.B   (A0)+           ;draw the line
2A36| 5341                          SUBQ    #1,D1
2A38| 66FA                          BNE.S   @1
2A3A| 4CDF 0103                     MOVEM.L (SP)+,D0/D1/A0  ;restore
2A3E| 4E75                          RTS
2A40|
2A40|                       ;----------------------------------------------------------------------------
2A40|                       ;  Subroutine to draw vertical lines.  Requires inputs:
2A40|                       ;    D0 = pixel position (0 to 719 decimal)
2A40|                       ;    $110 = base address of screen
2A40|                       ;----------------------------------------------------------------------------
2A40|
2A40| 48E7 F080             DRWVERT MOVEM.L D0-D3/A0,-(SP)  ;save regs
2A44| 7208                          MOVEQ   #8,D1           ;pixels per byte
2A46| 80C1                          DIVU    D1,D0           ;compute address offset
2A48| 4282                          CLR.L   D2
2A4A| 3400                          MOVE    D0,D2           ;save offset
2A4C| 2078 0110                     MOVE.L  SCRNBASE,A0     ;get base screen address
2A50| D1C2                          ADDA.L  D2,A0           ;add offset
2A52|
2A52| 4840                          SWAP    D0              ;get remainder
2A54| 9240                          SUB     D0,D1           ;compute bit position to set
2A56| 5341                          SUBQ    #1,D1
2A58|
2A58| 745A                          MOVEQ   #90,D2          ;distance to next pixel
2A5A| 363C 016C                     MOVE    #364,D3         ;line length
2A5E| 0390                  @1      BCLR    D1,(A0)         ;draw the line
2A60| D1C2                          ADDA.L  D2,A0           ;compute next pixel to set
2A62| 5343                          SUBQ    #1,D3
2A64| 66F8                          BNE.S   @1              ;loop until done
2A66| 4CDF 010F                     MOVEM.L (SP)+,D0-D3/A0  ;restore
2A6A| 4E75                          RTS
2A6C|
2A6C|                               .IF  BURNIN = 1
2A6C|                       ;-----------------------------------------------------------------------------
2A6C|                       ;  Power cycle entry point - branches to cycling routine
2A6C|                       ;-----------------------------------------------------------------------------
2A6C|
2A6C|                       PowerCycle
2A6C| 6100 066C                     BSR     CLRDESK         ;clear desktop
2A70| 6000 F7D2                     BRA     CHKPAS2         ;go start power cycle
2A74|
2A74|                               .ENDC
2A74|
2A74|                               .PAGE
2A74|                       ;----------------------------------------------------------------------------
2A74|                       ;  Invalid input detected - beep speaker and notify user
2A74|                       ;----------------------------------------------------------------------------
2A74| 6100 FC96             INVALID BSR     SQUAWK          ;that's a no no
2A78|                               .IF  USERINT = 0
2A78|                               .ELSE
2A78| 47FA 1561                     LEA     WHATMSG,A3      ;output question mark
2A7C| 6100 018C                     BSR     DBOXDSPLY       ;display in dialog box
2A80| 6004                          BRA.S   INVXIT
2A82|
2A82|                       LEV2LOOP
2A82| 6100 01A4                     BSR     CLRDBOX         ;go remove dialog box
2A86|                       INVXIT
2A86| 6100 FD18                     BSR     WRTMENU         ;redisplay pull-down menu
2A8A| 6100 0582                     BSR     CursorDisplay   ;redisplay cursor
2A8E| 6000 FCBC                     BRA     GETLEV2         ;and go get more input
2A92|                               .ENDC
2A92|
2A92|                               .IF  ROM16K = 1
2A92|                               .IF  FULLSCC = 0
2A92|                               .ENDC                   ;{FULLSCC}
2A92|                               .ENDC                   ;{ROM16K}
2A92|
2A92|                               .PAGE
2A92|                               .IF  USERINT = 0
2A92|                               .ELSE
2A92|                       ;-----------------------------------------------------------------------------
2A92|                       ;  Subroutine to output prompt line and gather input
2A92|                       ;-----------------------------------------------------------------------------
2A92|
2A92| 48E7 0620             PROMPT  MOVEM.L D5-D6/A2,-(SP)  ;save screen ptrs and target address
2A96| 6100 071A                     BSR     MAKEDBOX        ;make dialog box
2A9A| 3A3C 0018                     MOVE    #DBOXROW,D5     ;set msg ptrs
2A9E| 3C3C 0018                     MOVE    #DBOXCOL,D6
2AA2| 6100 0974                     BSR     GETLENGTH       ;get message length
2AA6| 5442                          ADDQ    #2,D2           ;incr for spacing
2AA8| 31C2 052E                     MOVE    D2,MSGLEN       ;save as message length
2AAC| 6100 0C52                     BSR     DSPMSG          ;write msg
2AB0| 6100 0008                     BSR     RDINPUT         ;go handle input
2AB4| 4CDF 0460                     MOVEM.L (SP)+,D5-D6/A2  ;restore and exit
2AB8| 4E75                          RTS
2ABA|
2ABA|                       ;-----------------------------------------------------------------------------
2ABA|                       ;  Subroutine to read keyboard input and save in buffer.  Accepts max of
2ABA|                       ;  48 characters.
2ABA|                       ;-----------------------------------------------------------------------------
2ABA|
2ABA|                       RDINPUT
2ABA| 207C 0000 02C0                MOVE.L  #KBDBFR,A0      ;set buffer ptrs
2AC0| 2248                          MOVE.L  A0,A1           ;same for head and tail
2AC2| 4283                          CLR.L   D3              ;clear for result use
2AC4|
2AC4| 6100 FC3C             READIN  BSR     READKEY         ;get char
2AC8| 6100 FC50                     BSR     KeyToASCII      ;convert to ASCII
2ACC|
2ACC| 4A00                          TST.B   D0              ;ignore CMD, Option, Shift, Alpha lock
2ACE| 67F4                          BEQ.S   READIN
2AD0| 0C00 0008                     CMP.B   #BS,D0          ;backspace key?
2AD4| 6612                          BNE.S   @2
2AD6| 4A43                          TST     D3              ;any input
2AD8| 67EA                          BEQ.S   READIN          ;no - ignore
2ADA| 5343                          SUBQ    #1,D3           ;decrement count
2ADC| 4A21                          TST.B   -(A1)           ;delete char from queue
2ADE| 6100 008C                     BSR     PUTBS           ;do backspace on screen
2AE2| 6100 0096                     BSR     CLRIT           ;clear char on screen
2AE6| 60DC                          BRA.S   READIN          ;and continue
2AE8|
2AE8| 0C00 000D             @2      CMP.B   #RET,D0         ;return key?
2AEC| 6718                          BEQ.S   @3              ; yes - exit
2AEE|
2AEE| 0C03 0030                     CMP.B   #48,D3          ;at max?
2AF2| 6D06                          BLT.S   @4              ;skip if no
2AF4| 6100 FC16                     BSR     SQUAWK          ;else notify user
2AF8| 60CA                          BRA.S   READIN          ;and ignore input
2AFA|
2AFA| 5243                  @4      ADDQ    #1,D3           ;incr char count
2AFC| 6100 0088                     BSR     ENQKBD          ;queue it
2B00| 6100 0C38                     BSR     DSPVAL          ;and output it
2B04| 60BE                          BRA.S   READIN          ;and continue read
2B06|
2B06| 4E75                  @3      RTS
2B08|                       ;--------------------------------------------------------------------------
2B08|                       ;  SCROLL  - move contents of Service Window up one whole line.  Assumed
2B08|                       ;  that we are at bottom line when called. D6 (column) and D5 (row) are
2B08|                       ;  set to start of last line.
2B08|                       ;--------------------------------------------------------------------------
2B08|
2B08| 48E7 E080             SCROLL  MOVEM.L D0-D2/A0,-(SP)          ;save data regs and bfr ptr
2B0C| 7A48                          MOVEQ   #FIRSTROW+ROWLINES,D5   ;set beginning character row +1
2B0E| 7C18                          MOVEQ   #FIRSTCOL,D6            ; and beginning column
2B10| 6100 0C08                     BSR     SETCRSR                 ;get address of screen
2B14| 204E                          MOVE.L  A6,A0                   ;set as to ptr
2B16| D0FC 0384                     ADDA    #,A0         ;set from ptr down one character row            RM000
2B1A| 343C 001B                     MOVE    #NROWS,D2               ;number of rows to move
2B1E|
2B1E| 323C 000A             @1      MOVE    #ROWLINES,D1    ;number of pixel lines per character row
2B22| 303C 0042             @2      MOVE    #ROWLEN,D0      ;length of a pixel line in window
2B26| 3CD8                  @3      MOVE    (A0)+,(A6)+     ;scroll it
2B28| 5540                          SUBQ    #2,D0           ;do entire pixel line
2B2A| 6EFA                          BGT.S   @3
2B2C|
2B2C| 5245                          ADDQ    #1,D5           ;bump to next row
2B2E| 7C18                  @4      MOVEQ   #FIRSTCOL,D6    ;set first col
2B30| 6100 0BE8                     BSR     SETCRSR         ;compute address
2B34| 204E                          MOVE.L  A6,A0           ;set as to ptr
2B36| D0FC 0384                     ADDA    #,A0 ;set from ptr down one character row                    RM000
2B3A| 5341                          SUBQ    #1,D1           ;do all pixel lines
2B3C| 66E4                          BNE.S   @2
2B3E|
2B3E| 5342                          SUBQ    #1,D2           ;finished a character row
2B40| 66DC                          BNE.S   @1              ; loop until done
2B42|
2B42| 3A3C 014C                     MOVE    #LASTROW,D5     ;peg at bottom
2B46| 3C3C 0018                     MOVE    #FIRSTCOL,D6
2B4A| 4CDF 0107                     MOVEM.L (SP)+,D0-D2/A0  ;restore data regs and bfr ptr
2B4E| 4E75                          RTS
2B50|
2B50|                               .PAGE
2B50|
2B50|                       ;  PUTLF - advance to next row; this may cause a scroll if at bottom
2B50|
2B50| 3A38 0300             PUTLF   MOVE    CRTROW,D5       ;get last state
2B54| 7C18                          MOVEQ   #FIRSTCOL,D6    ;update column to left edge of window
2B56| 0645 000A                     ADD     #ROWLINES,D5    ;bump row by number of pixel lines per row
2B5A| 0C45 014C                     CMPI    #LASTROW,D5
2B5E| 6F02                          BLE.S   @9              ;skip if its ok
2B60| 61A6                          BSR.S   SCROLL          ; else, do a scroll operation
2B62| 31C5 0300             @9      MOVE    D5,CRTROW       ;save updates
2B66| 31C6 0302                     MOVE    D6,CRTCOL
2B6A| 4E75                          RTS
2B6C|
2B6C|                       ;  PUTBS - move cursor left one position.
2B6C|                       ;  Assumes location MSGLEN = left most column for window.
2B6C|
2B6C| 5346                  PUTBS   SUBQ    #1,D6
2B6E| BC78 052E                     CMP     MSGLEN,D6        ;stop at left edge
2B72| 6C04                          BGE.S   @9
2B74| 3C38 052E                     MOVE    MSGLEN,D6
2B78| 4E75                  @9      RTS
2B7A|
2B7A|                       ;  Routine to erase data on screen
2B7A| 303C 0020             CLRIT   MOVE    #' ',D0         ; output a space
2B7E| 6100 0BBA                     BSR     DSPVAL
2B82| 5346                          SUBQ    #1,D6           ; reposition col ptr
2B84| 4E75                          RTS                     ; and that's all there is...
2B86|
2B86|                               .ENDC
2B86|                               .PAGE
2B86|                       ;-----------------------------------------------------------------------------
2B86|                       ;  Subroutine to save keyboard input in buffer - ignores data if buffer full.
2B86|                       ;-----------------------------------------------------------------------------
2B86|
2B86| 2F0A                  ENQKBD  MOVE.L  A2,-(SP)        ;save working reg
2B88| 347C 0300                     MOVEA   #KBDEND,A2      ;get ptr to end of buffer               RM000
2B8C| B5C9                          CMPA.L  A1,A2           ; at end of buffer?
2B8E| 6702                          BEQ.S   @9              ; exit if yes
2B90| 12C0                          MOVE.B  D0,(A1)+        ; else do save
2B92| 245F                  @9      MOVE.L  (SP)+,A2        ;restore
2B94| 4E75                          RTS
2B96|
2B96|                       ;-----------------------------------------------------------------------------
2B96|                       ;  This code gets the next byte from the keyboard queue and delivers it to
2B96|                       ;  caller in D0.
2B96|                       ;-----------------------------------------------------------------------------
2B96|
2B96| B3C8                  GETCH   CMPA.L  A0,A1           ;check if any data
2B98| 6704                          BEQ.S   @1              ;exit if none
2B9A| 1018                          MOVE.B  (A0)+,D0        ;get data
2B9C| 6004                          BRA.S   @2
2B9E| 003C 0001             @1      ORI.B   #$01,CCR        ;set empty indicator
2BA2| 4E75                  @2      RTS
2BA4|
2BA4|                               .PAGE
2BA4|                       ;-------------------------------------------------------------------------
2BA4|                       ;  Subroutine to get address parameter
2BA4|                       ;-------------------------------------------------------------------------
2BA4|
2BA4| 47FA 1415             GETA    LEA     ADDRMSG,A3      ;output prompt and get input
2BA8| 6100 FEE8                     BSR     PROMPT
2BAC| 7208                          MOVEQ   #8,D1           ;decode address (max of 8 digits)
2BAE| 6102                          BSR.S   GETPARM
2BB0| 4E75                          RTS
2BB2|
2BB2|                               .PAGE
2BB2|                       ;-------------------------------------------------------------------------
2BB2|                       ;  Subroutine to get input parameters.  Reads Ascii values from keyboard
2BB2|                       ;  buffer and calls conversion routine to return hex values.  Stops after
2BB2|                       ;  reading requested input or 'space' separator encountered.
2BB2|                       ;  Inputs:  D1 = max chars to read
2BB2|                       ;  Outputs: D2 = value read
2BB2|                       ;           D3 = # of chars read
2BB2|                       ;  Carry bit set if invalid chars.
2BB2|                       ;-------------------------------------------------------------------------
2BB2|
2BB2| 4283                  GETPARM CLR.L   D3              ;use for counter
2BB4| 4282                          CLR.L   D2              ;use for result
2BB6|
2BB6| 61DE                  READQ   BSR     GETCH           ;check input queue
2BB8| 652E                          BCS.S   GETEXIT         ;exit if no chars
2BBA| 0C00 0020                     CMPI.B  #' ',D0         ;space separator?
2BBE| 6604                          BNE.S   @3              ;if not, go response
2BC0| 4A20                          TST.B   -(A0)           ;replace on queue
2BC2| 6024                          BRA.S   GETEXIT         ;and exit
2BC4|
2BC4| 0C00 0030             @3      CMPI.B  #'0',D0         ;check if valid hex char
2BC8| 6D24                          BLT.S   INVPARM
2BCA| 0C00 0039                     CMPI.B  #'9',D0
2BCE| 630C                          BLS.S   OKCH            ;OK if 0-9
2BD0| 0C00 0041                     CMPI.B  #'A',D0         ; or A-F
2BD4| 6D18                          BLT.S   INVPARM
2BD6| 0C00 0046                     CMPI.B  #'F',D0
2BDA| 6E12                          BGT.S   INVPARM
2BDC|
2BDC| 6116                  OKCH    BSR.S   CONVERT         ;convert to hex digit
2BDE| E98A                          LSL.L   #4,D2           ;save char
2BE0| 8400                          OR.B    D0,D2
2BE2| 5243                          ADDQ    #1,D3           ;bump counter
2BE4| B203                          CMP.B   D3,D1           ;at max?
2BE6| 66CE                          BNE.S   READQ           ;continue if no
2BE8|
2BE8| 023C 00FE             GETEXIT ANDI.B  #$FE,CCR        ;clear error indicator
2BEC| 6004                          BRA.S   GETXIT2         ;and exit
2BEE|
2BEE| 003C 0001             INVPARM ORI.B   #$01,CCR        ;set error indicator
2BF2|
2BF2| 4E75                  GETXIT2 RTS
2BF4|
2BF4|                       ;-------------------------------------------------------------------------
2BF4|                       ;  Subroutine to convert Ascii character to hex.  Expects input in D0
2BF4|                       ;  and returns converted value in D0.
2BF4|                       ;-------------------------------------------------------------------------
2BF4|
2BF4| 0C00 0040             CONVERT CMP.B   #$40,D0         ;check if number or letter
2BF8| 6E06                          BGT.S   @1              ;skip if letter
2BFA| 0400 0030                     SUBI.B  #$30,D0         ;simple operation for number
2BFE| 6008                          BRA.S   @9
2C00|
2C00| 0400 0041             @1      SUBI.B  #$41,D0         ;a little different for letters
2C04| 0600 000A                     ADDI.B  #$0A,D0
2C08|
2C08| 4E75                  @9      RTS
2C0A|
2C0A|                               .PAGE
2C0A|                               .IF  USERINT = 1
2C0A|                       ;-------------------------------------------------------------------------
2C0A|                       ;  Subroutine to write to dialog box
2C0A|                       ;-------------------------------------------------------------------------
2C0A|
2C0A|                       DBOXDSPLY
2C0A| 48E7 8600                     MOVEM.L D0/D5-D6,-(SP)  ;save D0 and current cursor ptrs
2C0E| 6100 05A2                     BSR     MAKEDBOX        ;clear dialog box and redraw
2C12| 3A3C 0018                     MOVE    #DBOXROW,D5     ;set box coordinates
2C16| 3C3C 0018                     MOVE    #DBOXCOL,D6
2C1A| 6100 0AFE                     BSR     SETCRSR         ;get address in A6
2C1E| 6100 0AE0                     BSR     DSPMSG          ;write msg
2C22| 4CDF 0061                     MOVEM.L (SP)+,D0/D5-D6  ;restore
2C26| 4E75                          RTS                     ;and exit
2C28|
2C28|                       ;-------------------------------------------------------------------------
2C28|                       ;  Subroutine to remove dialog box from screen
2C28|                       ;-------------------------------------------------------------------------
2C28|
2C28| 705A                  CLRDBOX MOVEQ   #ROWBYTES,D0            ;set pixel line length                          RM000
2C2A| 3C7C 05FA                     MOVEA   #DESKLINE,A6            ;set starting point as bottom of menu line      RM000
2C2E| 4281                          CLR.L   D1
2C30| 2A4E                          MOVE.L  A6,A5                   ;set limit as bottom of dialog box
2C32| 223C 0000 0708                MOVE.L  #,D1 ; by adding box heigth to start pt
2C38| 0681 0000 0168                ADD.L   #DBOXTOP,D1
2C3E| DBC1                          ADDA.L  D1,A5
2C40| 6100 04AC                     BSR     GRAY                    ;redraw gray pattern
2C44| 4E75                          RTS
2C46|                       ;-----------------------------------------------------------------------------
2C46|                       ;  GETINPUT routine - waits for inputs from mouse or keyboard and returns
2C46|                       ;  with keycode in D0 if keyboard input, or rectangle ID if active rect is
2C46|                       ;  selected with the mouse.  If CMD flag is set, keyboard input returned
2C46|                       ;  only when prefaced by the CMD key.
2C46|                       ;-----------------------------------------------------------------------------
2C46|
2C46|                       ;  State 1 - General wait
2C46|
2C46|                       GETINPUT
2C46| 0838 0003 02A2                BTST    #CMDFLG,STATFLGS ;command key still down?
2C4C| 666C                          BNE.S   GET2             ;skip if yes
2C4E| 6100 00E8             GET1    BSR     WT4INPUT        ;else go wait for COPS input
2C52|                       CHKIT
2C52| 0C00 0006                     CMP.B   #MOUSUP,D0      ;mouse button up?
2C56| 6608                          BNE.S   @1
2C58| 08B8 0004 02A2                BCLR    #MOUSE,STATFLGS ;clear mouse flag
2C5E| 60EE                          BRA.S   GET1            ;and go wait for more input
2C60|
2C60| 0C00 0086             @1      CMP.B   #MOUSDWN,D0     ;mouse button down?
2C64| 6608                          BNE.S   @2
2C66| 08F8 0004 02A2                BSET    #MOUSE,STATFLGS ;set reminder flag
2C6C| 6014                          BRA.S   @3
2C6E|
2C6E| 4A00                  @2      TST.B   D0              ;mouse data?
2C70| 661A                          BNE.S   @5              ;skip if not
2C72| 6100 0376                     BSR     CursorHide      ;else clear old cursor
2C76| 6100 0396                     BSR     CursorDisplay   ;and redisplay cursor in new position
2C7A|
2C7A| 0838 0004 02A2                BTST    #MOUSE,STATFLGS ;is mouse button down?
2C80| 67CC                          BEQ.S   GET1            ;skip if not
2C82|
2C82| 6100 01C2             @3      BSR     CHKPOSN         ;else go check mouse position
2C86| 67C6                          BEQ.S   GET1            ;continue if not over a rect
2C88| 6000 0082                     BRA     GET3            ;else go to state 3
2C8C|
2C8C| 0C00 00FF             @5      CMP.B   #CmdDwn,D0      ;command key down?
2C90| 6608                          BNE.S   @6
2C92| 08F8 0003 02A2                BSET    #CMDFLG,STATFLGS ;set flag if yes
2C98| 6020                          BRA.S   GET2             ;and go to state 2
2C9A|
2C9A| 0C00 007F             @6      CMP.B   #CmdUp,D0        ;command key up?
2C9E| 6608                          BNE.S   @4
2CA0| 08B8 0003 02A2                BCLR    #CMDFLG,STATFLGS ;clear flag if yes
2CA6| 60A6                          BRA.S   GET1             ;and continue in loop
2CA8| 0838 0005 02A2        @4      BTST    #CHKCMD,STATFLGS ;CMD key prefix required?
2CAE| 669E                          BNE.S   GET1             ;loop if yes
2CB0| 4A00                  @7      TST.B   D0              ;else check if downstroke
2CB2| 6A92                          BPL.S   GETINPUT        ;skip upstrokes
2CB4| 6100 01EC                     BSR     CHKINPUT        ;go check if rectangle selected
2CB8| 4E75                          RTS                     ;and return with keycode
2CBA|
2CBA|                       ;  State 2 - Command (apple) button down
2CBA|
2CBA|                       GET2
2CBA| 6100 007C             WAIT2   BSR     WT4INPUT        ;else go wait for COPS input
2CBE|
2CBE| 0C00 007F             CHKIT2  CMP.B   #CMDUP,D0       ;command key up?
2CC2| 6608                          BNE.S   @2              ;skip if not
2CC4| 08B8 0003 02A2                BCLR    #CMDFLG,STATFLGS ;else clear flag
2CCA| 6082                          BRA.S   GET1            ;and return to state 1
2CCC|
2CCC| 0C00 0006             @2      CMP.B   #MOUSUP,D0      ;mouse button up?
2CD0| 6608                          BNE.S   @3
2CD2| 08B8 0004 02A2                BCLR    #MOUSE,STATFLGS ;clear mouse flag
2CD8| 60E0                          BRA.S   GET2            ;and go wait for more input
2CDA|
2CDA| 0C00 0086             @3      CMP.B   #MOUSDWN,D0     ;mouse button down?
2CDE| 6608                          BNE.S   @4
2CE0| 08F8 0004 02A2                BSET    #MOUSE,STATFLGS ;set reminder flag
2CE6| 6014                          BRA.S   @5
2CE8|
2CE8| 4A00                  @4      TST.B   D0              ;mouse data?
2CEA| 6618                          BNE.S   @6
2CEC| 6100 02FC                     BSR     CursorHide      ;else clear old cursor
2CF0| 6100 031C                     BSR     CursorDisplay   ;and redisplay cursor in new position
2CF4|
2CF4| 0838 0004 02A2                BTST    #MOUSE,STATFLGS ;is mouse button down?
2CFA| 67BE                          BEQ.S   GET2            ;skip if not
2CFC|
2CFC| 6100 0148             @5      BSR     CHKPOSN         ;else go check mouse position
2D00| 67B8                          BEQ.S   GET2            ;continue if not over a rect
2D02| 6008                          BRA.S   GET3            ;else go to state 3
2D04|
2D04| 6AB4                  @6      BPL.S   WAIT2           ;ignore upstrokes
2D06| 6100 019A                     BSR     CHKINPUT        ;go check if rectangle selected
2D0A| 4E75                          RTS                     ;and return with keycode
2D0C|
2D0C|                       ;  State 3 - Mouse button down and over an active rectangle
2D0C|
2D0C| 3200                  GET3    MOVE    D0,D1           ;save rectangle ID
2D0E| 6100 0028             WAIT3   BSR     WT4INPUT        ;go wait for input
2D12|
2D12| 0C00 0006                     CMP.B   #MOUSUP,D0      ;mouse button up?
2D16| 660A                          BNE.S   @1              ;skip if not
2D18| 08B8 0004 02A2                BCLR    #MOUSE,STATFLGS ;clear indicator
2D1E| 3001                          MOVE    D1,D0           ;restore rectangle ID
2D20| 4E75                          RTS                     ;and go analyze input
2D22|
2D22| 4A00                  @1      TST.B   D0              ;mouse data?
2D24| 66E8                          BNE.S   WAIT3           ;continue wait if not - ignore keyboard input
2D26|
2D26| 6100 02C2             @2      BSR     CursorHide      ;move cursor to new position
2D2A| 6100 02E2                     BSR     CursorDisplay
2D2E| 6100 0116                     BSR     CHKPOSN         ;check if over a rect
2D32| 66D8                          BNE.S   GET3            ;stay in this state if yes
2D34| 6000 FF10                     BRA     GETINPUT        ;else return to state 1
2D38|
2D38|                       ;-------------------------------------------------------------------------
2D38|                       ;  WT4INPUT
2D38|                       ;
2D38|                       ;       Routine to wait for input from COPS.  Returns with keycode in D0
2D38|                       ;       or sets D0 = 0 if mouse data received.
2D38|                       ;
2D38|                       ;-------------------------------------------------------------------------
2D38|
2D38|                       WT4INPUT
2D38|
2D38|                       ;  State 0 - general wait
2D38|
2D38| 6100 0084             COPS0   BSR     ReadCOPS        ;get input from COPS
2D3C| 4A00                          TST.B   D0              ;mouse data?
2D3E| 6708                          BEQ.S   COPS1           ;go to state 1 if yes
2D40| 0C00 0080                     CMP.B   #RSTCODE,D0     ;reset code?
2D44| 6716                          BEQ.S   COPS2           ;skip to state 2 if yes
2D46| 4E75                          RTS                     ;else return with the keycode
2D48|
2D48|                       ;  State 1 - waiting for mouse data
2D48| 6174                  COPS1   BSR.S   ReadCOPS        ;get COPS input
2D4A| 11C0 048A                     MOVE.B  D0,MousDx       ;save mouse delta-x
2D4E| 616E                          BSR.S   ReadCOPS        ;read and
2D50| 11C0 048B                     MOVE.B  D0,MousDy       ;save mouse delta-y
2D54| 6100 01D4                     BSR     MouseMovement   ;record the mouse movement
2D58| 4240                          CLR     D0              ;set mouse flag
2D5A| 4E75                          RTS                     ;and exit
2D5C|
2D5C|                       ;  State 2 - waiting for reset code
2D5C|
2D5C| 6160                  COPS2   BSR.S   ReadCOPS        ;get COPS input
2D5E| 0C00 00DF                     CMP.B   #$DF,D0         ;reset code <= $DF?
2D62| 6318                          BLS.S   @1              ;branch if yes
2D64| 0C00 00EF                     CMP.B   #$EF,D0         ;reset code <= $EF?
2D68| 6318                          BLS.S   @2              ;skip if yes
2D6A| 0C00 00FB                     CMP.B   #$FB,D0         ;reset code <= $FB
2D6E| 6500 0018                     BLO.S   @3              ;branch if < $FB
2D72| 6716                          BEQ.S   @4              ;branch if = $FB
2D74| 0C00 00FD                     CMP.B   #$FD,D0         ;reset code <= $FD?
2D78| 630E                          BLS.S   @3              ;branch if <= $FD
2D7A| 6010                          BRA.S   @5              ;branch if > $FD
2D7C|
2D7C|                       ;  $00 - $DF    Keyboard ID number - save and return to state 0
2D7C| 11C0 01B2             @1      MOVE.B  D0,KeyID        ;save new ID
2D80| 60B6                          BRA.S   COPS0           ;return to general wait
2D82|
2D82|                       ;  $E0 - $EF    Clock data - save first nibble, and go to state 4
2D82|
2D82| 11C0 0480             @2      MOVE.B  D0,ClockBytes   ;save it
2D86| 6016                          BRA.S   COPS4           ;and go get rest of data
2D88|
2D88|                       ;  $F0 - $FA    Reserved --- ignored
2D88|                       ;  $FC - $FD    Clock timer interrupt, keyboard unplugged --- ignored
2D88|
2D88| 60AE                  @3      BRA.S   COPS0           ;go back to general wait
2D8A|
2D8A|                       ;  $FB          Soft on/off button - go to power-off routine
2D8A|
2D8A| 604C                  @4      BRA.S   PowerOff        ;go shutdown the system
2D8C|
2D8C|                       ;  $FE - $FF    COPS failure codes - go to error routine
2D8C| 0C00 00FE             @5      CMP.B   #$FE,D0         ;I/O board COPS?
2D90| 6604                          BNE.S   @6
2D92| 7034                          MOVEQ   #EIOCOP,D0      ;else set I/O COPS error code
2D94| 6002                          BRA.S   @7
2D96| 7035                  @6      MOVEQ   #EKBDCOP,D0     ;set keyboard COPS error code
2D98| 003C 0001             @7      ORI.B   #$01,CCR        ;set return error indicator
2D9C| 4E75                          RTS
2D9E|
2D9E|                       ;  State 4 - waiting for clock data; use timeout routine to guard against error
2D9E|
2D9E| 48E7 60E0             COPS4   MOVEM.L D1-D2/A0-A2,-(SP) ;save regs
2DA2| 43F8 0481                     LEA     ClockBytes+1,A1   ;set ptrs to save area
2DA6| 45F8 0486                     LEA     ClockBytes+6,A2
2DAA| 7205                          MOVEQ   #5,D1             ;5 more bytes expected
2DAC| 6100 DCD0             @1      BSR     GETDATA           ;get COPS data
2DB0| 6504                          BCS.S   @2                ;skip if any errors
2DB2| 5341                          SUBQ    #1,D1             ;loop until done
2DB4| 66F6                          BNE.S   @1
2DB6|
2DB6| 4CDF 0706             @2      MOVEM.L (SP)+,D1-D2/A0-A2 ;restore regs and
2DBA| 6000 FF7C                     BRA.S   COPS0             ;go back to general wait
2DBE|
2DBE|                               .ENDC           ;{USERINT}
2DBE|
2DBE|                       ;------------------------------------------------------------------------
2DBE|                       ;  ReadCOPS
2DBE|                       ;
2DBE|                       ;       Routine to get data from COPS. Returns with data in D0.
2DBE|                       ;
2DBE|                       ;------------------------------------------------------------------------
2DBE|
2DBE|                       ReadCOPS
2DBE| 2F08                          MOVE.L  A0,-(SP)
2DC0| 207C 00FC DD81                MOVE.L  #VIA1BASE,A0    ;get interface ptr
2DC6| 1028 001A             @1      MOVE.B  IFR1(A0),D0     ;poll for data
2DCA| 0800 0001                     BTST    #1,D0
2DCE| 67F6                          BEQ.S   @1              ;loop until data received
2DD0| 1028 0002                     MOVE.B  ORA1(A0),D0     ;read
2DD4| 205F                          MOVE.L  (SP)+,A0        ;and return
2DD6| 4E75                          RTS
2DD8|
2DD8|                               .IF  USERINT = 1
2DD8|                       ;-------------------------------------------------------------------------
2DD8|                       ;  PowerOff - routine to shutdown the system
2DD8|                       ;-------------------------------------------------------------------------
2DD8|
2DD8|                       PowerOff
2DD8| 0807 0011                     BTST    #DISK,D7        ;disk controller error?                 CHG023
2DDC| 6622                          BNE.S   @9              ;skip if yes                            CHG023
2DDE| 207C 00FC C001                MOVE.L  #DISKMEM,A0     ;set ptr for shared memory
2DE4| 6144                          BSR.S   ENBLDRVS        ;enable both drives
2DE6| 4228 0004                     MOVE.B  #DRV1,DRV(A0)   ;eject diskette in drive 1
2DEA| 6100 F06A                     BSR     EJCTDSK
2DEE| 117C 0080 0004                MOVE.B  #DRV2,DRV(A0)   ;and drive 2
2DF4| 6100 F060                     BSR     EJCTDSK
2DF8|
2DF8| 10BC 0089                     MOVE.B  #DIE,(A0)       ;get Twiggy controller out of memory
2DFC| 6100 F006                     BSR     CMDCHK          ;wait until command taken
2E00|                       @9      BSR4    CONOFF          ;turn off contrast                      CHG003
2E00| 49FA 0006            #          LEA      @1,A4
2E04| 6000 D9FA            #          BRA      CONOFF
2E08|                      #@1
2E08| 203C 0003 D090                MOVE.L  #ONESEC,D0      ;wait for it to happen                  CHG003
2E0E| 6100 DCD2                     BSR     DELAY           ;                                       CHG003
2E12| 7021                          MOVEQ   #$21,D0         ;power off, timer off, clock on         RM000
2E14| 6100 DB40                     BSR     COPSCMD         ;go do it
2E18| 6100 DCC2                     BSR     KBDDELAY        ;wait about 1.7 secs for power-off
2E1C|
2E1C| 6100 F8EE                     BSR     SQUAWK          ;error if still on
2E20| 45FA 0B29                     LEA     IOBRD,A2
2E24| 7034                          MOVEQ   #EIOCOP,D0      ;set error code
2E26| 6000 E798                     BRA     TSTXIT          ;display error and go back to level1 monitor
2E2A|
2E2A|                       ;------------------------------------------------------------------------
2E2A|                       ;  Subroutine to enable drives
2E2A|                       ;------------------------------------------------------------------------
2E2A|
2E2A|                       ENBLDRVS
2E2A| 117C 0088 0002                MOVE.B  #$88,CMD(A0)    ;enable both drives
2E30| 10BC 0086                     MOVE.B  #ENBLINT,(A0)
2E34| 6100 EFCE                     BSR     CMDCHK
2E38| 267C 00FC DD81                MOVE.L  #VIA1BASE,A3    ;and enable FDIR
2E3E| 08AB 0004 0004                BCLR    #FDIR,DDRB1(A3)
2E44| 4E75                          RTS
2E46|
2E46|                       ;------------------------------------------------------------------------
2E46|                       ;  CHKPOSN
2E46|                       ;
2E46|                       ;  Routine to check mouse position versus active rectangle table.
2E46|                       ;  If over a rectangle, inverts it and returns with its ID.
2E46|                       ;  If not over a rectangle, ensures all rectangles not inverted, and
2E46|                       ;  returns with D0 = 0.
2E46|                       ;
2E46|                       ;  Active rectangle table has following format:
2E46|                       ;
2E46|                       ;       Word 1 : number of entries in table
2E46|                       ;       Word 2 : ID for first entry, MSB = 1 if inverted on screen
2E46|                       ;       Next 4 words contain X,Y pixel coordinates for upper left
2E46|                       ;        and bottom right corners
2E46|                       ;       Each successive entry follows same format, with 5 words per entry
2E46|                       ;
2E46|                       ;       Register usage:
2E46|                       ;               A0 = ptr to rectangle table
2E46|                       ;               D0 = # of entries in table
2E46|                       ;               D1 = ID for current entry
2E46|                       ;               D2 = X-coordinate for upper left
2E46|                       ;               D3 = Y-coordinate for upper left
2E46|                       ;               D4 = X-coordinate for bottom right
2E46|                       ;               D5 = Y-coordinate for bottom right
2E46|                       ;               D6 = X-coordinate for current cursor location
2E46|                       ;               D7 = Y-coordinate for current cursor location
2E46|                       ;
2E46|                       ;       On exit, D0 = ID code of rectangle cursor is over or
2E46|                       ;                   = 0 if not over any rectangle
2E46|                       ;
2E46|                       ;-------------------------------------------------------------------------
2E46|
2E46| 48E7 7F80             CHKPOSN MOVEM.L D1-D7/A0,-(SP)
2E4A| 3C38 0496                     MOVE    CrsrX,D6        ;get current cursor location
2E4E| 3E38 0498                     MOVE    CrsrY,D7
2E52| 41F8 053A                     LEA     RectTable,A0    ;set ptr to table
2E56| 3018                          MOVE    (A0)+,D0        ;get count
2E58| 6742                          BEQ.S   CHKPXIT         ;exit if 0
2E5A| 4C98 003E             GETNTRY MOVEM   (A0)+,D1-D5     ;else get entry (5 words)
2E5E|
2E5E|                       ;  check if cursor over rectangle
2E5E|
2E5E| BC42                          CMP     D2,D6           ;CrsrX < upper left X?
2E60| 6D0E                          BLT.S   @1              ;branch if cursor to left of rectangle
2E62| BC44                          CMP     D4,D6           ;CrsrX > bottom right X?
2E64| 6E0A                          BGT.S   @1              ;branch if cursor to right of rectangle
2E66| BE43                          CMP     D3,D7           ;CrsrY < upper left Y?
2E68| 6D06                          BLT.S   @1              ;branch if cursor above rectangle
2E6A| BE45                          CMP     D5,D7           ;CrsrY > bottom right Y?
2E6C| 6E02                          BGT.S   @1              ;branch if cursor below rectangle
2E6E| 600E                          BRA.S   @3              ;cursor over this entry - go invert it
2E70|
2E70|                       ;  not over this entry - check if inverted, then continue through table
2E70| 4A41                  @1      TST     D1              ;entry inverted?
2E74| 6100 004C                     BSR     INVERT          ;else go reinvert
2E78| 5340                  @2      SUBQ    #1,D0           ;decrement entry count
2E7A| 66DE                          BNE.S   GETNTRY         ;check next entry if not done
2E7C| 601E                          BRA.S   CHKPXIT         ;else exit with D0 = 0
2E7E|
2E7E|                       ;  over the rectangle - if not already, invert it and data saved
2E7E|
2E7E| 4A41                  @3      TST     D1              ;already inverted?
2E80| 6B18                          BMI.S   @6              ;exit if yes
2E82| 6100 003E                     BSR     INVERT          ;go invert rectangle
2E86|
2E86|                       ;  check if any other entries previously inverted
2E86|
2E86| 5340                  @4      SUBQ    #1,D0           ;done?
2E88| 6710                          BEQ.S   @6              ;skip if yes
2E8A| 4A58                          TST     (A0)+           ;else check next entry
2E8C| 6B04                          BMI.S   @5              ;skip if inverted
2E8E| 5048                          ADDQ    #8,A0           ;else bump to next entry
2E90| 60F4                          BRA.S   @4              ;and continue loop
2E92|
2E92| 4C98 003C             @5      MOVEM   (A0)+,D2-D5     ;get coordinates
2E96| 6100 002A                     BSR     INVERT          ;and go reinvert and then exit
2E9A|                                                       ;since at most one rect inverted
2E9A|
2E9A| 3001                  @6      MOVE    D1,D0           ;set return code
2E9C|
2E9C| 4CDF 01FE             CHKPXIT MOVEM.L (SP)+,D1-D7/A0
2EA0| 4E75                          RTS                     ;and exit
2EA2|
2EA2|                       ;------------------------------------------------------------------------
2EA2|                       ;  CHKINPUT
2EA2|                       ;
2EA2|                       ;  Routine to check keyboard input versus active rectangle table.
2EA2|                       ;  If rectangle selected, inverts it and returns.
2EA2|                       ;
2EA2|                       ;  Active rectangle table has following format:
2EA2|                       ;
2EA2|                       ;       Word 1 : number of entries in table
2EA2|                       ;       Word 2 : ID for first entry, MSB = 1 if inverted on screen
2EA2|                       ;       Next 4 words contain X,Y pixel coordinates for upper left
2EA2|                       ;        and bottom right corners
2EA2|                       ;       Each successive entry follows same format, with 5 words per entry
2EA2|                       ;
2EA2|                       ;       Register usage:
2EA2|                       ;               A0 = ptr to rectangle table
2EA2|                       ;               D0 = keyboard input
2EA2|                       ;               D1 = ID for current entry
2EA2|                       ;               D2 = X-coordinate for upper left
2EA2|                       ;               D3 = Y-coordinate for upper left
2EA2|                       ;               D4 = X-coordinate for bottom right
2EA2|                       ;               D5 = Y-coordinate for bottom right
2EA2|                       ;               D6 = # of entries in table
2EA2|                       ;
2EA2|                       ;-------------------------------------------------------------------------
2EA2|
2EA2|                       CHKINPUT
2EA2| 48E7 7E80                     MOVEM.L D1-D6/A0,-(SP)
2EA6| 41F8 053A                     LEA     RectTable,A0    ;set ptr to table
2EAA| 3C18                          MOVE    (A0)+,D6        ;get count
2EAC| 4C98 003E             RDENTRY MOVEM   (A0)+,D1-D5     ;get entry (5 words)
2EB0| B200                          CMP.B   D0,D1           ;match with keyboard input?
2EB2| 6706                          BEQ.S   @1              ;skip if yes
2EB4| 5346                          SUBQ    #1,D6           ;else loop thru all entries
2EB6| 66F4                          BNE.S   RDENTRY
2EB8| 6002                          BRA.S   @2              ;skip to exit
2EBA|
2EBA| 6106                  @1      BSR.S   INVERT          ;go invert rectangle
2EBC|
2EBC| 4CDF 017E             @2      MOVEM.L (SP)+,D1-D6/A0  ;restore regs
2EC0| 4E75                          RTS                     ;and return
2EC2|                       ;-----------------------------------------------------------------------------
2EC2|                       ;  INVERT
2EC2|                       ;
2EC2|                       ;  Routine to invert buttons, menu or icon.  Computes upper left address,
2EC2|                       ;  width and heigth of rectangle, then calls INVERSE and other routines
2EC2|                       ;  as needed.
2EC2|                       ;
2EC2|                       ;  Register inputs: D2 = upper left X-coordinate
2EC2|                       ;                   D3 = upper left Y-coordinate
2EC2|                       ;                   D4 = bottom right X-coordinate
2EC2|                       ;                   D5 = bottom right Y-coordinate
2EC2|                       ;                   A0 = ptr to start of next entry in rectangle table
2EC2|                       ;
2EC2|                       ;-----------------------------------------------------------------------------
2EC2|
2EC2| 48E7 F840             INVERT  MOVEM.L D0-D4/A1,-(SP)
2EC6|
2EC6| 6100 0122                     BSR     CursorHide      ;remove cursor
2ECA|
2ECA| 0868 0007 FFF6                BCHG    #7,-10(A0)      ;flip the invert bit indicator for entry
2ED0|
2ED0| 3004                          MOVE    D4,D0           ;compute width
2ED2| 9042                          SUB     D2,D0
2ED4| 80FC 0008                     DIVU    #8,D0           ;convert to bytes
2ED8| 3205                          MOVE    D5,D1           ;compute height in pixel rows
2EDA| 9243                          SUB     D3,D1
2EDC| 5241                          ADDQ    #1,D1           ;bump by 1 to do bottom line also
2EDE|
2EDE| 93C9                          SUBA.L  A1,A1           ;use for upper left address
2EE0| E64A                          LSR     #3,D2           ;divide pixel column by 8 for bytes
2EE2| D2C2                          ADD     D2,A1           ;add to address
2EE4| 785A                          MOVEQ   #MaxX/8,D4      ;bytes per row on screen
2EE6| C6C4                          MULU    D4,D3           ; * pixel row
2EE8| D2C3                          ADD     D3,A1           ;address of upper left corner
2EEA|
2EEA| 0838 0007 02A2                BTST    #MENU,STATFLGS  ;doing menu item?
2EF0| 6706                          BEQ.S   @0              ;skip if not
2EF2| D2FC 005A                     ADDA    #ROWBYTES,A1    ;else add 1 scan line to avoid menu             RM000
2EF6|                                                       ; bar line inversion
2EF6| 5341                          SUBQ    #1,D1           ;and decr length to avoid inverting bottom line
2EF8|                                                       ; of menu box
2EF8|
2EF8| 74FF                  @0      MOVEQ   #-1,D2          ;set fill pattern
2EFA| 48E7 E040                     MOVEM.L D0-D2/A1,-(SP)  ;save args
2EFE| 6100 022E                     BSR     INVERSE         ;invert it
2F02|
2F02| 4CDF 0207                     MOVEM.L (SP)+,D0-D2/A1  ;restore args
2F06|
2F06| 0838 0006 02A2                BTST    #BTN,STATFLGS   ;doing buttons?
2F0C| 6706                          BEQ.S   @1              ;skip if not
2F0E| 6100 03E8                     BSR     DRAWBUTN        ;redraw button
2F12| 600C                          BRA.S   @9              ;and exit
2F14|
2F14| 0838 0007 02A2        @1      BTST    #MENU,STATFLGS  ;doing menu?
2F1A| 6704                          BEQ.S   @9              ;skip if not
2F1C| 6100 0424                     BSR     DRAWSIDES       ;just redraw sides
2F20|
2F20| 6100 00EC             @9      BSR     CursorDisplay   ;redisplay cursor
2F24|
2F24| 4CDF 021F                     MOVEM.L (SP)+,D0-D4/A1  ;restore regs
2F28| 4E75                          RTS                     ;and return
2F2A|
2F2A|                               .PAGE
2F2A|                       ;-----------------------------------------------------------------------------
2F2A|                       ;
2F2A|                       ;   Hardware Interface for the Mouse
2F2A|                       ;
2F2A|                       ;   Written by Rick Meyers
2F2A|                       ;   (c) Apple Computer Incorporated, 1983
2F2A|                       ;
2F2A|                       ;   The routines below provide an assembly language interface to the mouse.
2F2A|                       ;   Input parameters are passed in registers, output parameters are returned
2F2A|                       ;   in registers.  Unless otherwise noted, all registers are preserved.
2F2A|                       ;
2F2A|                       ;   The Mouse
2F2A|                       ;
2F2A|                       ;   The mouse is a pointing device used to indicate screen locations.  Mouse
2F2A|                       ;   coordinates are located between pixels on the screen.  Therefore, the
2F2A|                       ;   X-coordinate can range from 0 to 720, and the Y-coordinate from 0 to 364.
2F2A|                       ;   The initial mouse location is 0,0.
2F2A|                       ;
2F2A|                       ;   Mouse Scaling
2F2A|                       ;
2F2A|                       ;   The relationship between physical mouse movements and logical mouse
2F2A|                       ;   movements is not necessary a fixed linear mapping.  Three alternatives
2F2A|                       ;   are available: 1) unscaled, 2) scaled for fine movement and 3) scaled
2F2A|                       ;   for coarse movement.
2F2A|                       ;
2F2A|                       ;   When mouse movement is unscaled, a horizontal mouse movement of x units
2F2A|                       ;   yields a change in the mouse X-coordinate of x pixels.  Similiarly, a
2F2A|                       ;   vertical movement of y units yields a change is the mouse Y-coordinate
2F2A|                       ;   of y pixels.  These rules apply independent of the speed of the mouse
2F2A|                       ;   movement.
2F2A|                       ;
2F2A|                       ;   When mouse movement is scaled, horizontal movements are magnified by 3/2
2F2A|                       ;   relative to vertical movements.  This is intended to compensate for the
2F2A|                       ;   2/3 aspect ratio of pixels on the screen.  When scaling is in effect, a
2F2A|                       ;   distinction is made between fine (small) movements and coarse (large)
2F2A|                       ;   movements.  Fine movements are slightly reduced, while coarse movements
2F2A|                       ;   are magnified. For scaled fine movements, a horizontal mouse movement of
2F2A|                       ;   x units yields a change in the X-coordinate of x pixels, but a vertical
2F2A|                       ;   movement of y units yields a change of (2/3)*y pixels.  For scaled coarse
2F2A|                       ;   movements, a horizontal movement a x units yields a change of (3/2)*x
2F2A|                       ;   pixels, while a vertical movements of y units yields a change of y pixels.
2F2A|                       ;
2F2A|                       ;   The distinction between fine movements and coarse movements is determined
2F2A|                       ;   by the sum of the x and y movements each time the mouse location is
2F2A|                       ;   updated.  If this sum is at or below the 'threshold', the movement is
2F2A|                       ;   considered to be a fine movement.  Values of the threshold range from 0
2F2A|                       ;   (which yields all coarse movements) to 256 (which yields all fine
2F2A|                       ;   movements).  Given the default mouse updating frequency, a threshold of
2F2A|                       ;   about 8 (threshold's initial setting) gives a comfortable transition between
2F2A|                       ;   fine and coarse movements.
2F2A|                       ;---------------------------------------------------------------------------------
2F2A|
2F2A|
2F2A|                       ;-----------------------------------------------------------------------------
2F2A|                       ;
2F2A|                       ;   Mouse Movement
2F2A|                       ;
2F2A|                       ;   This routine is called by the GETINPUT routine when the COPS has
2F2A|                       ;   reported mouse movement.  All registers are preserved.
2F2A|                       ;
2F2A|                       ;
2F2A|                       ;   Register Assignments:
2F2A|                       ;
2F2A|                       ;       D0  --  Mouse X-Coordinate (integer)
2F2A|                       ;       D1  --  Mouse Y-Corrdinate (integer)
2F2A|                       ;       D2  --  Mouse Dx (integer)
2F2A|                       ;       D3  --  Mouse Dy (integer)
2F2A|                       ;
2F2A| 48E7 7C00             MouseMovement   MOVEM.L D1-D5,-(SP)         ; save registers
2F2E| 3038 0486                             MOVE.W  MousX,D0            ; mouse X-coordinate
2F32| 3238 0488                             MOVE.W  MousY,D1            ; mouse Y-coordinate
2F36| 1438 048A                             MOVE.B  MousDx,D2           ; mouse Dx (byte)
2F3A| 4882                                  EXT.W   D2                  ; mouse Dx (integer)
2F3C| 1638 048B                             MOVE.B  MousDy,D3           ; mouse Dy (byte)
2F40| 4883                                  EXT.W   D3                  ; mouse Dy (integer)
2F42|
2F42| 3802                  Scale           MOVE.W  D2,D4               ; mouse Dx
2F44| 6C02                                  BGE.S   @1                  ; branch if >= 0
2F46| 4444                                  NEG.W   D4                  ; ABS(mouse Dx)
2F48|
2F48| 3A03                  @1              MOVE.W  D3,D5               ; mouse Dy
2F4A| 6C02                                  BGE.S   @2                  ; branch if >= 0
2F4C| 4445                                  NEG.W   D5                  ; ABS(mouse Dy)
2F4E|
2F4E| D845                  @2              ADD.W   D5,D4               ; ABS(Dx) + ABS(Dy)
2F50| 9878 048E                             SUB.W   MousThresh,D4       ;  - MouseThreshold
2F54| 6E16                                  BGT.S   Coarse              ; branch if coarse movement
2F56|
2F56| D042                  Fine            ADD.W   D2,D0               ; new X-coordinate (scale 1)
2F58| 3403                                  MOVE.W  D3,D2               ; save Dy
2F5A| D643                                  ADD.W   D3,D3               ; Dy*2
2F5C| D643                                  ADD.W   D3,D3               ; Dy*4
2F5E| D642                                  ADD.W   D2,D3               ; Dy*5
2F60| 5443                                  ADDQ    #2,D3               ; (Dy*5)+2
2F62| 6D02                                  BLT.S   @3                  ; branch if negative
2F64| 5643                                  ADDQ    #3,D3               ; (Dy*5)+5
2F66| E643                  @3              ASR.W   #3,D3               ; Dy*(5/8) with rounding
2F68| D243                                  ADD.W   D3,D1               ; new Y-coordinate (scale 5/8)
2F6A| 6010                                  BRA.S   Bounds              ; continue
2F6C|
2F6C| D243                  Coarse          ADD.W   D3,D1               ; new Y-coordinate (scale 1)
2F6E| 3602                                  MOVE.W  D2,D3               ; save Dx
2F70| D443                                  ADD.W   D3,D2               ; Dx*2
2F72| D443                                  ADD.W   D3,D2               ; Dx*3
2F74| 6D02                                  BLT.S   @4                  ; branch if negative
2F76| 5242                                  ADDQ.W  #1,D2               ; (Dx*3)+1
2F78| E242                  @4              ASR.W   #1,D2               ; Dx*(3/2) with rounding
2F7A| D042                                  ADD.W   D2,D0               ; new X-coordinate (scale 3/2)
2F7C|
2F7C| 4A40                  Bounds          TST.W   D0                  ; new X-coordinate >= 0
2F7E| 6C02                                  BGE.S   @5                  ; branch if >= 0
2F80| 4240                                  MOVE.W  #0,D0               ; minimum X of 0
2F82|
2F82| 0C40 02D0             @5              CMP.W   #MaxX,D0            ; new X-coordinate <= 720
2F86| 6F04                                  BLE.S   @6                  ; branch if <= 720
2F88| 303C 02D0                             MOVE.W  #MaxX,D0            ; maximum X of 720
2F8C|
2F8C| 4A41                  @6              TST.W   D1                  ; new Y-coordinate >= 0
2F8E| 6C02                                  BGE.S   @7                  ; branch if >= 0
2F90| 4241                                  MOVE.W  #0,D1               ; minimum Y of 0
2F92|
2F92| 0C41 016C             @7              CMP.W   #MaxY,D1            ; new Y-coordinate <= 364
2F96| 6F04                                  BLE.S   @8                  ; branch if <= 364
2F98| 323C 016C                             MOVE.W  #MaxY,D1            ; maximum Y of 364
2F9C|
2F9C| 31C0 0486             @8              MOVE.W  D0,MousX            ; update Mouse X-coordinate
2FA0| 31C1 0488                             MOVE.W  D1,MousY            ; update Mouse Y-coordinate
2FA4| 31C0 0496                             MOVE.W  D0,CrsrX            ; also update cursor coordinates
2FA8| 31C1 0498                             MOVE.W  D1,CrsrY
2FAC| 4CDF 003E                             MOVEM.L (SP)+,D1-D5         ; restore registers
2FB0| 4E75                                  RTS                         ; return
2FB2|
2FB2|                       ;-----------------------------------------------------------------------------
2FB2|                       ;
2FB2|                       ;  Routine to initialize mouse handling
2FB2|                       ;
2FB2|                       ;-----------------------------------------------------------------------------
2FB2|
2FB2|                       MousInit
2FB2| 31FC 0168 0486                        MOVE.W  #360,MousX          ; set inital mouse location
2FB8| 31FC 00B6 0488                        MOVE.W  #182,MousY          ;  to center of screen
2FBE| 31FC 0008 048E                        MOVE.W  #8,MousThresh       ; set scaling threshold
2FC4| 707C                                  MOVEQ   #$7C,D0             ; and enable mouse data
2FC6| 6100 D98E                             BSR     COPSCMD
2FCA| 4E75                                  RTS
2FCC|
2FCC|                       ;-----------------------------------------------------------------------------
2FCC|                       ;
2FCC|                       ;   Hardware Interface for the Cursor
2FCC|                       ;
2FCC|                       ;   Written by Rick Meyers
2FCC|                       ;   (c) Apple Computer Incorporated, 1983
2FCC|                       ;
2FCC|                       ;
2FCC|                       ;   The routines below provide an assembly language interface to the cursor.
2FCC|                       ;   Input parameters are passed in registers, output parameters are returned
2FCC|                       ;   in registers.  Unless otherwise noted, all registers are preserved.
2FCC|                       ;
2FCC|                       ;   The Cursor
2FCC|                       ;
2FCC|                       ;   The cursor is a small image that is displayed on the screen.  It's shape
2FCC|                       ;   is specified by two bitmaps, called 'data' and 'mask'.  These bitmaps are
2FCC|                       ;   16 bits wide and from 0 to 32 bits high.  The rule used to combine the
2FCC|                       ;   bits already on the screen with the data and mask is
2FCC|                       ;
2FCC|                       ;       screen <- (screen and (not mask)) xor data.
2FCC|                       ;
2FCC|                       ;   The effect is that white areas of the screen are replaced with the cursor
2FCC|                       ;   data.  Black areas of the screen are replaced with (not mask) xor data.
2FCC|                       ;   If the data and mask bitmaps are identical, the effect is to 'or' the data
2FCC|                       ;   onto the screen.
2FCC|                       ;
2FCC|                       ;   The cursor has both a location and a hotspot.  The location is a position
2FCC|                       ;   on the screen, with X-coordinates of 0 to 720 and Y-coordinates of 0 to 364 .
2FCC|                       ;   The hotspot is a position within the cursor bitmaps, with X- and Y-coordi-
2FCC|                       ;   nates ranging from 0 to 16.  The cursor is displayed on the screen with it's
2FCC|                       ;   hotspot at location.  If the cursor's location is near an edge of the screen,
2FCC|                       ;   the cursor image may be partially or completely off the screen.
2FCC|                       ;
2FCC|                       ;------------------------------------------------------------------------------
2FCC|                       ;
2FCC|                       ;   Routine:    CursorInit
2FCC|                       ;   Arguments:  None
2FCC|                       ;   Function:   Sets up the initial defaults used by the ROM cursor.  Initial
2FCC|                       ;               position is set for center of the screen.
2FCC|                       ;
2FCC|                       ;------------------------------------------------------------------------------
2FCC|
2FCC| 4278 0490             CursorInit      MOVE.W  #0,CrsrHotX         ; cursor hotspot X-coordinate
2FD0| 4278 0492                             MOVE.W  #0,CrsrHotY         ; cursor hotspot Y-coordinate
2FD4| 31FC 0010 0494                        MOVE.W  #16,CrsrHeight      ; cursor hieght, 0-32
2FDA| 31FC 0168 0496                        MOVE.W  #360,CrsrX          ; initial cursor X-coordinate
2FE0| 31FC 00B6 0498                        MOVE.W  #182,CrsrY          ; initial cursor Y-coordinate
2FE6| 61CA                                  BSR.S   MousInit            ; init mouse for cursor control
2FE8| 4E75                                  RTS                         ; return
2FEA|
2FEA|                       ;-----------------------------------------------------------------------------
2FEA|                       ;
2FEA|                       ;   Cursor Hide and Display
2FEA|                       ;
2FEA|                       ;   Care must be taken when updating the screen image which is 'under' the
2FEA|                       ;   cursor.  The simplest approach is to remove the cursor from the screen
2FEA|                       ;   (hide), do the screen modification, then redisplay the cursor (display).
2FEA|                       ;   Each hide operation must be followed by a corresponding display
2FEA|                       ;   operation.  The operations are paired and can be nested.  The first of a
2FEA|                       ;   series of hides removes the cursor from the screen; it's corresponding
2FEA|                       ;   display redisplays the cursor.  Intervening operations have no apparent
2FEA|                       ;   effect.
2FEA|                       ;
2FEA|                       ;------------------------------------------------------------------------------
2FEA|
2FEA|                       ;---------------------------------------------------------------------------------
2FEA|                       ;   Routine:    CursorHide
2FEA|                       ;   Arguments:  None
2FEA|                       ;   Function:   Remove the cursor from the screen.  Note that every call to
2FEA|                       ;               CursorHide must be followed by exactly one call to CursorDisplay.
2FEA|                       ;---------------------------------------------------------------------------------
2FEA|
2FEA| 48E7 C0C0             CursorHide      MOVEM.L D0-D1/A0-A1,-(SP)   ; save registers
2FEE| 41F8 04A2                             LEA     SavedData,A0        ; saved data address
2FF2| 2278 0528                             MOVE.L  SavedAddr,A1        ; saved data screen address
2FF6| 3038 0526                             MOVE.W  SavedRows,D0        ; rows of saved data
2FFA| 323C 005A                             MOVE.W  #MaxX/8,D1          ; bytes per row on screen
2FFE| 6004                                  BRA.S   @2                  ; test of rows=0
3000|
3000| 2298                  @1              MOVE.L  (A0)+,(A1)          ; from saved to screen
3002| D2C1                                  ADD.W   D1,A1               ; screen address of next row
3004| 51C8 FFFA             @2              DBF     D0,@1               ; loop 'SavedRows' times
3008|
3008| 4CDF 0303                             MOVEM.L (SP)+,D0-D1/A0-A1   ; restore registers
300C| 4E75                                  RTS                         ; return
300E|
300E|                       ;------------------------------------------------------------------------------
300E|                       ;
300E|                       ;   Routine:    CursorDisplay
300E|                       ;   Arguments:    none
300E|                       ;   Function:   Redisplay the cursor.  Note that every call to CursorDisplay
300E|                       ;               must be preceeded by exactly one call to CursorHide.
300E|                       ;
300E|                       ;   Register Assignments:
300E|                       ;
300E|                       ;       D0  --  saved data X-coordinate, cursor data
300E|                       ;       D1  --  saved data Y-coordinate, cursor mask
300E|                       ;       D2  --  left shift count
300E|                       ;       D3  --  32-bit mask
300E|                       ;       D4  --  rows of saved data
300E|                       ;       D5  --  bytes per row on screen
300E|                       ;
300E|                       ;       A0  --  saved data address
300E|                       ;       A1  --  saved data screen address
300E|                       ;       A2  --  cursor data address
300E|                       ;       A3  --  cursor mask address
300E|                       ;------------------------------------------------------------------------------
300E|
300E| 48E7 FCF0             CursorDisplay   MOVEM.L D0-D5/A0-A3,-(SP)   ; save registers
3012|
3012| 41F8 04A2                             LEA     SavedData,A0        ; saved data address
3016| 2278 0110                             MOVE.L  ScrnBase,A1         ; screen memory address
301A| 45FA 0900                             LEA     CrsrData,A2         ; cursor data bitmap address
301E| 47FA 08FC                             LEA     CrsrMask,A3         ; cursor mask bitmap address
3022| 3038 0490                             MOVE.W  CrsrHotX,D0         ; cursor hotspot X-coordinate
3026| 3238 0492                             MOVE.W  CrsrHotY,D1         ; cursor hotspot Y-coordinate
302A| 3838 0494                             MOVE.W  CrsrHeight,D4       ; cursor height
302E|
302E|                       ;   Compute and bounds check the X-coordinate of the data under the cursor.
302E| 9078 0496             @11             SUB.W   CrsrX,D0            ;  cursor X-coordinate
3032| 4440                                  NEG.W   D0                  ;  - cursor hotspot X-coordinate
3034| 3400                                  MOVE.W  D0,D2               ; upper left X-coordinate
3036| 0242 000F                             AND.W   #$000F,D2           ; bit offset within word
303A| 4442                                  NEG.W   D2                  ;  negated and converted to
303C| 0642 0010                             ADD.W   #16,D2              ;  left shift count
3040| 4283                                  CLR.L   D3                  ; 32-bit mask                       RM000
3042| 4643                                  NOT     D3                  ; D3 = $0000FFFF                    RM000
3044| E5AB                                  LSL.L   D2,D3               ;  shifted into position
3046|
3046| 0240 FFF0                             AND.W   #$FFF0,D0           ; upper left X-coord rounded down
304A| 6C0A                                  BGE.S   @0                  ; branch if >= 0
304C|
304C| 4240                                  MOVE.W  #0,D0               ; minimum upper left X-coord of 0
304E| E18B                                  LSL.L   #8,D3               ; adjust 32-bit mask
3050| E18B                                  LSL.L   #8,D3               ; adjust 32-bit mask
3052| 0642 0010                             ADD.W   #16,D2              ; adjust left shift count
3056|
3056| 0C40 02B0             @0              CMP.W   #MaxX-32,D0         ; upper left X-coord <= 720-32
305A| 6F14                                  BLE.S   @2                  ; branch if <= 720-32
305C|
305C| 0C40 02D0                             CMP.W   #MaxX,D0            ; cursor off right edge ?
3060| 6602                                  BNE.S   @1                  ; branch if not off right edge
3062| 7600                                  MOVEQ   #0,D3               ; mask off all bits
3064|
3064| 303C 02B0             @1              MOVE.W  #MaxX-32,D0         ; maximum X-coord of 720-32
3068| E08B                                  LSR.L   #8,D3               ; adjust 32-bit mask
306A| E08B                                  LSR.L   #8,D3               ; adjust 32-bit mask
306C| 0642 0010                             ADD.W   #16,D2              ; adjust left shift count
3070|
3070|                       ;   Compute and bounds check the Y-coordinate of the data under the cursor.
3070|
3070| 9278 0498             @2              SUB.W   CrsrY,D1            ; cursor Y-coordinate
3074| 4441                                  NEG.W   D1                  ;  - cursor hotspot Y-coordinate
3076| 6C0C                                  BGE.S   @3                  ; branch if upper left Y >= 0
3078|
3078| D841                                  ADD.W   D1,D4               ; decrease rows of saved data
307A| D241                                  ADD.W   D1,D1               ; double for byte count
307C| 94C1                                  SUB.W   D1,A2               ; increase cursor data address
307E| 96C1                                  SUB.W   D1,A3               ; increase cursor mask address
3080| 4241                                  MOVE.W  #0,D1               ; minimum upper left Y of 0
3082| 6010                                  BRA.S   @4                  ; continue
3084|
3084| 3A3C 016C             @3              MOVE.W  #MaxY,D5            ; maximum Y-coordinate
3088| 9A44                                  SUB.W   D4,D5               ;  - cursor height
308A| B245                                  CMP.W   D5,D1               ; cursor bottom <= 364-CrsrHeight ?
308C| 6F0C                                  BLE.S   @5                  ; branch if <= 364-CrsrHeight
308E|
308E| 383C 016C                             MOVE.W  #MaxY,D4            ; last row on screen
3092| 9841                                  SUB.W   D1,D4               ; adjust rows of saved data
3094|
3094| 4A44                  @4              TST.W   D4                  ; rows of saved data >= 0 ?
3096| 6C02                                  BGE.S   @5                  ; branch if  >= 0
3098| 4244                                  MOVE.W  #0,D4               ; minimum rows of saved data
309A|
309A| 31C0 0522             @5              MOVE.W  D0,SavedX           ; saved data X-coordinate
309E| 31C1 0524                             MOVE.W  D1,SavedY           ; saved data Y-coordinate
30A2| 31C4 0526                             MOVE.W  D4,SavedRows        ; rows of saved data
30A6|
30A6|                       ;   Display the cursor on the screen.
30A6|
30A6| E648                                  LSR.W   #3,D0               ; convert X-coord to bytes
30A8| D2C0                                  ADD.W   D0,A1               ;  and add to screen address
30AA| 7A5A                                  MOVEQ   #MaxX/8,D5          ; bytes per row on screen
30AC| C2C5                                  MULU    D5,D1               ;  * Y-coord
30AE| D3C1                                  ADD.L   D1,A1               ;  added to screen address
30B0| 21C9 0528                             MOVE.L  A1,SavedAddr        ; saved data screen address
30B4| 6016                                  BRA.S   @7                  ; test for rows=0
30B6|
30B6| 301A                   @6             MOVE.W  (A2)+,D0            ; cursor data
30B8| E5B8                                  ROL.L   D2,D0               ; shift to proper bit position
30BA| C083                                  AND.L   D3,D0               ; eliminate unwanted bits
30BC| 321B                                  MOVE.W  (A3)+,D1            ; cursor mask
30BE| E5B9                                  ROL.L   D2,D1               ; shift to proper bit position
30C0| C283                                  AND.L   D3,D1               ; eliminate unwanted bits
30C2| 4681                                  NOT.L   D1                  ; invert cursor mask
30C4|
30C4| 20D1                                  MOVE.L  (A1),(A0)+          ; from screen to saved data
30C6| C391                                  AND.L   D1,(A1)             ; screen and (not mask)
30C8| B191                                  EOR.L   D0,(A1)             ;  xor cursor data
30CA| D2C5                                  ADD.W   D5,A1               ; screen address of next row
30CC| 51CC FFE8             @7              DBF     D4,@6               ; loop 'SavedRows' times
30D0|
30D0| 4CDF 0F3F                             MOVEM.L (SP)+,D0-D5/A0-A3   ; restore registers
30D4| 4E75                                  RTS                         ; return
30D6|
30D6|                               .ENDC                   ;{USERINT}
30D6|                               .IF  AAPL = 1
30D6|                               .ENDC                   ;{USERINT}
30D6|                               .IF  AAPL = 1
30D6|                               .ENDC
30D6|                               .ENDC                   ;{ROM4K}
30D6|
30D6|
30D6|                               .INCLUDE RM248.G.TEXT
30D6|
30D6|                               .PAGE
30D6|                               .IF     EXTERNAL = 1
30D6|                               .IF  USERINT = 1
30D6|                       ;**********************************
30D6|                       ;  Mini-Graphics Package          *
30D6|                       ;  Contributed by Mike Urquhart   *
30D6|                       ;  Copyright 1983, 1984 Apple     *
30D6|                       ;**********************************
30D6|
30D6|                       ;________________________________________________________________________________
30D6|                       ;
30D6|                       ;       DRAWDESK:
30D6|                       ;
30D6|                       ;               this routine performs the following sequences:
30D6|                       ;
30D6|                       ;               1.      clears the screen to a white background.
30D6|                       ;               2.      makes a menu bar by drawing a single pixel horizontal
30D6|                       ;                       line across the screen.
30D6|                       ;               3.      fills the screen area below the menu bar with the stantard
30D6|                       ;                       gray shade.
30D6|                       ;
30D6|                       ;               Also has an entry point called CLRDESK that only does item (3).
30D6|                       ;
30D6|                       ;   Destroys regs D0-D2,A1,A5-A6
30D6|                       ;________________________________________________________________________________
30D6|
30D6|
30D6|                       ;
30D6|                       ;       1.      clear screen to white background
30D6|                       DRAWDESK
30D6| 4282                          clr.l   d2
30D8| 612E                          bsr.s   whiten
30DA|                       ;
30DA|                       ;       2.      make menu bar border
30DA|
30DA| 705A                  CLRDESK moveq   #ROWBYTES,d0    ;set length of line = 90 bytes
30DC| 74FF                          moveq   #-1,d2          ;draw a black pattern
30DE| 327C 05A0                     move.w  #MENULINE,A1    ;start at offset 1440 address
30E2| 7201                          moveq   #1,d1           ;draw only 1 pixel line
30E4| 6142                          bsr.s   paint_box
30E6|
30E6|                       ;
30E6|                       ;       set a6 to starting pixel address for grey routine below
30E6|                       ;       set a5 to limit
30E6|                       ;
30E6| 3C7C 05FA                     move    #DESKLINE,a6
30EA| 3A7C 7FF8                     move    #DESKLMT,a5     ;set limit
30EE|
30EE|                       ;
30EE|                       ;       3.      make the grey background: to make the gray background, alternating
30EE|                       ;               rows of $5555 and $AAAA starting with $AAAA are written to the
30EE|                       ;               screen area.
30EE|                       ;
30EE|
30EE| 243C AAAA 5555        gray    MOVE.L  #DESKPATRN,D2   ;set up grey pattern
30F4|
30F4| 4842                  gray1   swap    d2              ;start with the $AAAA pattern
30F6| 7201                          moveq   #1,d1           ;draw a one pixel high line
30F8| 224E                          move.l  a6,a1           ;starting pixel address must be in a1 for call
30FA| 6100 002C                     bsr     paint_box
30FE|
30FE| DCC0                  @1      add     d0,a6           ;bump to next pixel line
3100| BCCD                          cmp.w   a5,a6           ;is a6 less then max?
3102| 6DF0                          blt.s   gray1                 ;loop if yes
3104| 4E75                          rts                           ;else done
3106|
3106|                       ;_________________________________________________________________________
3106|                       ;
3106|                       ;       subroutine blacken and whiten: clears full screen to black or white
3106|                       ;
3106|                       ;       Calls:  bsr     blacken         (no parameters)
3106|                       ;
3106|                       ;               clr.l   d2
3106|                       ;               bsr     whiten
3106|                       ;
3106|                       ;       registers used:   d2.l - contains either FFFFFFFF or 0 on return
3106|                       ;                         d0.b - destroyed but contains $5A (90) on return
3106|                       ;                         d1.w - destroyed-->should contain 0 on return
3106|                       ;                         a1.l - destroyed
3106|                       ;
3106|                       ;
3106|                       ;       This routine calls paint_box, so other registers may be destroyed.
3106|                       ;
3106|                       ;
3106|                       ;_________________________________________________________________________
3106|
3106|                       BLACKEN
3106| 74FF                          moveq   #-1,d2                  ;black fill pattern
3108|
3108|                       whiten
3108| 323C 016B                     move.w  #MaxY-1,d1              ;number of pixels in screen box heigth
310C| 705A                          moveq   #ROWBYTES,d0            ;length of screen box is 90 bytes
310E| 93C9                          suba.l  A1,A1                   ;clear A1
3110| 6116                          bsr.s   paint_box
3112| 4E75                          rts
3114|
3114|                       ;------------------------------------------------------------------------
3114|                       ;  Subroutine to clear only menu bar on desktop
3114|                       ;  Inputs:
3114|                       ;       None
3114|                       ;  Outputs:
3114|                       ;       None
3114|                       ;  Side Effects:
3114|                       ;       None
3114|                       ;------------------------------------------------------------------------
3114|
3114| 48E7 E040             CLRMENU MOVEM.L D0-D2/A1,-(SP)  ;save regs
3118| 705A                          MOVEQ   #ROWBYTES,D0    ;width of menu bar is 90 bytes
311A| 7210                          MOVEQ   #MBARLEN,D1     ;heigth is 15 pixels
311C| 7400                          MOVEQ   #0,D2           ;set fill pattern
311E| 93C9                          SUBA.L  A1,A1           ;upper left corner is at offset 0
3120| 6106                          BSR.S   PAINT_BOX       ;go do it
3122| 4CDF 0207                     MOVEM.L (SP)+,D0-D2/A1  ;restore and
3126| 4E75                          RTS                     ; exit
3128|
3128|                       ;________________________________________________________________________________
3128|                       ;
3128|                       ;       Routine paint_box
3128|                       ;
3128|                       ;       Call:        BSR   paint_box
3128|                       ;                 or
3128|                       ;                    BSR   paintb2
3128|                       ;
3128|                       ;       register setup:
3128|                       ;
3128|                       ;       D2 must contain a one word fill pattern.
3128|                       ;       D0 must contain the width of the box(horizontally) or the length of
3128|                       ;                       the line.
3128|                       ;       D1 must contain the heigth(vertically of the box) in horizontal pixel
3128|                       ;                       rows:
3128|                       ;       A1 must contains the screen displacement in the range 0..32670
3128|                       ;
3128|                       ;       __________________________________
3128|                       ;       .                                .
3128|                       ;       .           fill pattern         . <-------heigth in pixels
3128|                       ;       __________________________________
3128|                       ;                       ^
3128|                       ;                       ........... length horizontally
3128|                       ;
3128|                       ;       Assumptions:  location SCRNBASE contains the video address
3128|                       ;       registers used-->D0-D3,A0-A2
3128|                       ;________________________________________________________________________________
3128|
3128|
3128|                       PAINT_BOX
3128|
3128| 49FA 0020             paintb1 lea     movinst,A4
312C| 6004                          bra.s   cont
312E|
312E| 49FA 001E             inverse lea     exclusive,A4
3132| D3F8 0110             cont    ADD.L   SCRNBASE,A1     ;add video address to starting pixel address offset.
3136|
3136|                       paintb2
3136| 2F0A                          MOVE.L  A2,-(SP)        ;save reg
3138|                       ;       do some setup steps
3138|                       ;
3138| 4283                          CLR.L   D3              ;clear for use
313A| 3600                          MOVE.W  D0,D3           ;modify width/length
313C| 4483                          NEG.l   D3              ;negate the width/length (D3 = -width/length)
313E|                       ;
313E|                       ;       add the length of one horizontal pixel row-2 to the -width/length
313E|                       ;       to derive an offset which can be added to the updated address pointer
313E|                       ;       (when it reflects the right corner or end point of the box/line)
313E|                       ;       in order to arrive at the next row starting address.
313E|                       ;
313E| 0683 0000 005A                ADDI.l   #ROWBYTES,D3   ;create displacement for following sequence
3144|                       ;
3144|                       ;
3144| 2449                          MOVE.L  A1,A2           ;create ending column check address
3146| D5C0                          ADD.L   D0,A2           ;add length of line to obtain ending column address
3148|                       ;
3148|                       ;       A1 now points to the left top coordinate of the box or line.
3148|                       ;       A2 now points to the right top coordinate of the box or line.
3148|                       ;
3148|                       startop
3148| 4ED4                          jmp     (A4)            ;execute the correct operation (EOR or MOVE)
314A|
314A|                       movinst
314A| 32C2                          MOVE.w  D2,(A1)+        ;start the sequence
314C| 6002                          bra.s   compare
314E|
314E|                       exclusive
314E| B559                          eor.w   D2,(A1)+
3150|
3150| B5C9                  compare CMP.L   A1,A2           ;reached the right most point?
3152| 6702                          BEQ.S   nextline        ;yes
3154| 60F2                          BRA.S   startop
3156|                       ;
3156|                       ;       YES
3156|                       ;
3156|                       nextline
3156| D3C3                          ADD.L   D3,A1           ;add 1 horizontal line length (5A) minus line length
3158| D4FC 005A                     ADDA    #ROWBYTES,A2    ;to reach the left most point of the box on the         RM000
315C| 5341                          SUBQ.W  #1,D1           ;next horizontal scan line.
315E| 66E8                          BNE.S   startop         ;loop until done.
3160|                       ;
3160| 245F                          MOVE.L (SP)+,A2         ;restore and
3162| 4E75                          RTS                     ;return
3164|
3164|                       ;------------------------------------------------------------------------
3164|                       ;  Entry point to set cursor ptrs and make alert box for power cycling
3164|                       ;------------------------------------------------------------------------
3164|
3164|                       MAKEPCALRT
3164| 7A59                          MOVEQ   #PCROW,D5       ;set row ptr
3166| 7C0C                          MOVEQ   #PCCOL,D6       ;and col ptr
3168|                                                       ;then drop into alert box routine
3168|                       ;________________________________________________________________________
3168|                       ;
3168|                       ;       MAKEALERT
3168|                       ;
3168|                       ;               This routine creates an alert box with no title.
3168|                       ;________________________________________________________________________
3168|
3168|                       MAKEALERT
3168| 48E7 C040                     movem.l d0-d1/a1,-(sp)
316C|
316C| 704E                          MOVEQ   #ALRTWIDTH,D0           ;set parameters for box
316E| 223C 0000 00A4                MOVE.L  #ALRTHIGH,D1
3174| 327C 1140                     MOVEA   #ALRTSTRT,A1
3178| 616C                          bsr.s   makebox
317A|
317A| 4CDF 0203                     movem.l (sp)+,d0-d1/a1
317E| 4E75                          rts
3180|
3180|                       ;________________________________________________________________________
3180|                       ;
3180|                       ;       MAKETEST
3180|                       ;
3180|                       ;               This routine creates an alert box for test icon display.
3180|                       ;________________________________________________________________________
3180|
3180|                       MAKETEST
3180| 48E7 C040                     movem.l d0-d1/a1,-(sp)
3184|
3184| 7046                          MOVEQ   #TSTWWIDTH,D0           ;set parameters for alert box
3186| 7254                          MOVEQ   #TSTWHIGH,D1
3188| 327C 1144                     MOVEA   #TSTWSTRT,A1
318C| 6158                          BSR.S   MAKEBOX                 ;go draw box
318E|
318E| 7A40                          MOVEQ   #TSTMROW,D5             ;set cursor ptrs
3190| 7C0E                          MOVEQ   #TSTMCOL,D6
3192| 47FA 0CA6                     LEA     CHKMSG,A3               ;set message ptr
3196| 72FF                          MOVEQ   #-1,D1                  ;append '...' string
3198| 6100 049A                     BSR     DSPSTRING               ;and go display it
319C|
319C| 6100 03EA                     BSR     DSPCPU                  ;display test icons
31A0| 6100 03FA                     BSR     DSPIOB
31A4| 6100 03EC                     BSR     DSPMBRD
31A8| 6100 03FC                     BSR     DSPXCRD
31AC|
31AC| 4CDF 0203                     movem.l (sp)+,d0-d1/a1
31B0| 4E75                          rts
31B2|
31B2|                       ;________________________________________________________________________
31B2|                       ;
31B2|                       ;       MAKEDBOX
31B2|                       ;
31B2|                       ;               This routine creates a dialog box.
31B2|                       ;________________________________________________________________________
31B2|
31B2|                       MAKEDBOX
31B2| 48E7 C040                     movem.l d0-d1/a1,-(sp)
31B6|
31B6| 7042                          MOVEQ   #DBOXWIDTH,D0           ;set parameters for dialog box
31B8| 7214                          MOVEQ   #DBOXHIGH,D1
31BA| 327C 071E                     MOVEA   #DBOXSTRT,A1
31BE| 6126                          bsr.s   makebox
31C0|
31C0| 4CDF 0203                     movem.l (sp)+,d0-d1/a1
31C4| 4E75                          rts
31C6|
31C6|                       ;________________________________________________________________________
31C6|                       ;
31C6|                       ;       routine makewindow
31C6|                       ;
31C6|                       ;               This routine creates a fixed window of the folder type.
31C6|                       ;               The calling routine must provide the address of the
31C6|                       ;               string which will be used to fill in the title box.
31C6|                       ;
31C6|                       ;       Call:
31C6|                       ;               move    ,d0
31C6|                       ;               move    ,d1
31C6|                       ;               move    ,a1
31C6|                       ;               lea     ,a3
31C6|                       ;               bsr     makewindow
31C6|                       ;
31C6|                       ;       This routine calls makebox
31C6|                       ;
31C6|                       ;________________________________________________________________________
31C6|
31C6|                       MAKEWINDOW
31C6| 48E7 C040                     movem.l d0-d1/a1,-(sp)
31CA|
31CA| 611A                          bsr.s   makebox
31CC|
31CC|                       ;
31CC|                       ;       now draw the title box by drawing a single black line across
31CC|                       ;       the width of the window about 17 pixels from the top edge
31CC|                       ;
31CC|
31CC| 2F09                          MOVE.L  A1,-(SP)        ;save start point
31CE| D2FC 05A0                     add.w   #MENULINE,a1
31D2| 7201                          moveq   #1,d1           ;set heigth of one pixel
31D4| 74FF                          moveq   #-1,d2
31D6| 6100 FF50                     bsr.s   paint_box
31DA|
31DA| 225F                          MOVE.L  (SP)+,A1        ;restore start point
31DC| 6100 01DA                     bsr     writetitle
31E0|
31E0| 4CDF 0203                     movem.l (sp)+,d0-d1/a1  ;restore and return
31E4| 4E75                          rts
31E6|
31E6|                       ;________________________________________________________________________
31E6|                       ;
31E6|                       ;       Routine makebox;
31E6|                       ;
31E6|                       ;               This routine creates a window of either the folder type
31E6|                       ;               or the dialog box type.  Is is the responsibility of
31E6|                       ;               the calling process to append the title box and title
31E6|                       ;               to the window if it is the folder type.
31E6|                       ;
31E6|                       ;       Call:
31E6|                       ;               move.w  ,d0               (range 0..90) even
31E6|                       ;               move.w  ,d1              (range 0..364)
31E6|                       ;               move.w  ,a1       (range 0..32670)
31E6|                       ;               bsr     makebox
31E6|                       ;
31E6|                       ;       registers used: d0,d1,d2,d3,d4,a1,a2
31E6|                       ;________________________________________________________________________
31E6|
31E6|
31E6|                       MAKEBOX
31E6|                       ;
31E6|                       ;       make the basic window--->no edges  D2 must be set to 0 on call
31E6|                       ;                                          d0 must be set to the width (90 maximum)
31E6|                       ;                                          d1 must be set to the heigth (364 maximum)
31E6|                       ;                                          A1 must be the offset address (0..32670)
31E6|                       ;
31E6|                       ;
31E6| 48E7 F878                     movem.l d0-d4/a1-a4,-(sp)
31EA| 48E7 C040                     movem.l d0-d1/a1,-(sp)     ;save the heigth and the starting pixel address
31EE|
31EE| 4282                          clr.l   d2                 ;the pattern
31F0| 6100 FF36                     bsr     paint_box
31F4|                       ;
31F4|                       ;       now draw the individual edges including the shadow edges on the right
31F4|                       ;       and bottom of the window
31F4|                       ;
31F4|
31F4|                       ;
31F4|                       ;       draw bottom horizontal edge
31F4|                       ;
31F4| 93C3                          sub.l   d3,a1
31F6| 93C0                          sub.l   d0,a1           ;a1 is currently equal to the lower right point
31F8|                                                       ; of the box so we can subtract the width to
31F8|                                                       ; calculate the lower left point of the box.
31F8|
31F8| 7201                          moveq   #1,d1           ;set 1 pixel heigth
31FA| 74FF                          moveq   #-1,d2          ;set the line pattern
31FC| 6100 FF38                     bsr     paintb2         ;remember a4 is set up to point to the move.w
3200|                                                       ; instruction
3200|                       ;
3200|                       ;       draw bottom horizontal shadow
3200| 5449                  @1      addq    #2,a1           ;shadow begin offset by 2
3202| 7201                          moveq   #1,d1           ;draw a one pixel line
3204| 5540                          subq    #2,d0
3206| 6100 FF2E                     bsr     paintb2         ;go
320A|                       ;
320A|                       ;       draw top horizontal edge
320A|                       ;
320A| 4CDF 0203             @2      movem.l  (sp)+,d0-d1/a1 ;restore original parameters
320E| 48E7 4040                     movem.l  d1/a1,-(sp)
3212| 7201                          moveq   #1,d1           ;draw a 1 pixel line
3214| 6100 FF12                     bsr     paint_box
3218|                       ;
3218|                       ;       now draw the right edge plus the right edge's shadow, use a1
3218|                       ;       with a column parameter of 0
3218|                       ;
3218| 4CDF 0410                     movem.l  (sp)+,d4/a2
321C| 7401                          moveq   #1,d2
321E| 5544                          subq    #2,d4
3220| 5540                          subq    #2,d0
3222| D3C0                          add.l   d0,a1
3224|
3224| 2204                          move.l  d4,d1
3226| 4280                          clr.l   d0
3228| 6130                          bsr.s   paint_v
322A|
322A| 303C 00B6                     move.w  #182,d0         ;set one byte offset from right edge
322E| 7407                          moveq   #7,d2
3230| 2204                          move.l  d4,d1
3232| 6136                          bsr.s   paintbit        ;draw first pixel line of the right shadow
3234|
3234| 303C 0110                     move.w  #272,d0
3238| 7406                          moveq   #6,d2
323A| 2204                          move.l  d4,d1
323C| 5341                          subq    #1,d1           ;reduce heigth by 1 to compensate for shadow offset
323E| 612A                          bsr.s   paintbit
3240|
3240|                       ;
3240|                       ;       now draw the left vertical edge of the box
3240|                       ;
3240| 224A                          move.l  a2,a1           ;restore the starting pixel address
3242| D3F8 0110                     add.l   SCRNBASE,a1     ;add in video address
3246| 705A                          moveq   #90,d0
3248| D3C0                          add.l   d0,a1
324A| 343C 8000                     move    #32768,d2       ;set the pattern
324E|
324E| 2204                          move.l  d4,d1           ;the heigth minus two
3250| 4280                          clr.l   d0              ;column 0 offset
3252| 6106                          bsr.s   paint_v
3254| 4CDF 1E1F                     movem.l (sp)+,d0-d4/a1-a4
3258|
3258| 4E75                          rts
325A|
325A|                       ;_________________________________________________________________________
325A|                       ;
325A|                       ;       Routine paint_v
325A|                       ;
325A|                       ;       This routine "paints" a vertical column one word wide.
325A|                       ;
325A|                       ;       Call:   BSR     paint_v
325A|                       ;
325A|                       ;       register setup:
325A|                       ;
325A|                       ;       A1 must contain the screen base address.
325A|                       ;       D2 must contain a one word pattern.
325A|                       ;       D1 must contain the number of pixels in the vertical length of the line
325A|                       ;         in the range 1..364
325A|                       ;       D0 must contain the screen word column in the range 0..44
325A|                       ;
325A|                       ;       Assumptions:  location SCRNBASE contains the video address
325A|                       ;
325A|                       ;       registers used: D0-D1
325A|                       ;________________________________________________________________________
325A|                       ;
325A|
325A|                       PAINT_V
325A|                       paintv1
325A|
325A| 3382 0000             @1      MOVE.W  D2,0(A1,D0.W)   ;write to screen
325E| 5341                          SUBQ.W  #1,D1           ;decrement count
3260| 6706                          BEQ.S   @2              ;return
3262| 0640 005A                     ADDI.W  #ROWBYTES,D0    ;bump to next horizontal line
3266| 60F2                          BRA.S   @1              ;loop to continue writing vertical.
3268|                       ;
3268| 4E75                  @2      RTS                     ;return
326A|
326A|                       ;_________________________________________________________________________
326A|                       ;
326A|                       ;       Routine paintbit
326A|                       ;
326A|                       ;       This routine "paints" a vertical line one bit wide.
326A|                       ;
326A|                       ;       Call:   BSR     paintbit
326A|                       ;       register setup:
326A|                       ;
326A|                       ;       A1 must contain the screen base address.
326A|                       ;       D2 must contain the bit number to set
326A|                       ;       D1 must contain the number of pixels in the vertical length of the line
326A|                       ;         in the range 1..364
326A|                       ;       D0 must contain the screen word column in the range 0..44
326A|                       ;
326A|                       ;       Assumptions:  location SCRNBASE contains the video address
326A|                       ;
326A|                       ;       registers used: D0-D1
326A|                       ;________________________________________________________________________
326A|
326A|                       PAINTBIT
326A|
326A| 05F1 0000             @1      bset    d2,0(a1,d0.w)
326E| 5341                          subq.w  #1,d1           ;subtract one from heigth
3270| 6706                          beq.s   @2              ;done
3272|
3272| 0640 005A                     addi.w  #ROWBYTES,d0    ;increment to next pixel row.
3276| 60F2                          bra.s   @1
3278|
3278| 4E75                  @2      RTS                     ;return
327A|
327A|                       ;______________________________________________________________________
327A|                       ;
327A|                       ;       Routine makebutton --> creates a black lined box of the size
327A|                       ;                              specified by the parameters with button
327A|                       ;                              "label" and description if specified.
327A|                       ;                              Also makes entries in active rectangle
327A|                       ;                              table for later use with mouse.
327A|                       ;
327A|                       ;                              the left top corner is addressed by a1,
327A|                       ;                              the alternate keycode is contained in d0.
327A|                       ;                              the description is in A3.
327A|                       ;                              description location is in A2.
327A|                       ;                              '...' string appended to message if d1 nonzero
327A|                       ;
327A|                       ;
327A|                       ;       Call:
327A|                       ;
327A|                       ;               move.w  ,a1
327A|                       ;               move.b  ,d0
327A|                       ;               lea