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