Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3) M68000 Hi-Performance Microprocessor Division
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4) M68060 Software Package
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5) Production Release P1.00 -- October 10, 1994
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7) M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) THE SOFTWARE is provided on an "AS IS" basis and without warranty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) To the maximum extent permitted by applicable law,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) and any warranty against infringement with regard to the SOFTWARE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) (INCLUDING ANY MODIFIED VERSIONS THEREOF) and any accompanying written materials.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) To the maximum extent permitted by applicable law,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) Motorola assumes no responsibility for the maintenance and support of the SOFTWARE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) You are hereby granted a copyright license to use, modify, and distribute the SOFTWARE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) so long as this entire notice is retained without alteration in any modified and/or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) redistributed versions, and that such modified versions are clearly identified as such.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) No licenses are granted by implication, estoppel or otherwise under any patents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) or trademarks of Motorola, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) # ireal.s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #	This file is appended to the top of the 060ISP package
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) # and contains the entry points into the package. The user, in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) # effect, branches to one of the branch table entries located
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) # after _060ISP_TABLE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #	Also, subroutine stubs exist in this file (_isp_done for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) # example) that are referenced by the ISP package itself in order
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) # to call a given routine. The stub routine actually performs the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) # callout. The ISP code does a "bsr" to the stub routine. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) # extra layer of hierarchy adds a slight performance penalty but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) # it makes the ISP code easier to read and more mainatinable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) set	_off_chk,	0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) set	_off_divbyzero,	0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) set	_off_trace,	0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) set	_off_access,	0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) set	_off_done,	0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) set	_off_cas,	0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) set	_off_cas2,	0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) set	_off_lock,	0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) set	_off_unlock,	0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) set	_off_imr,	0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) set	_off_dmr,	0x44
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) set	_off_dmw,	0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) set	_off_irw,	0x4c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) set	_off_irl,	0x50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) set	_off_drb,	0x54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) set	_off_drw,	0x58
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) set	_off_drl,	0x5c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) set	_off_dwb,	0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) set	_off_dww,	0x64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) set	_off_dwl,	0x68
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) _060ISP_TABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) # Here's the table of ENTRY POINTS for those linking the package.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 	bra.l		_isp_unimp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 	short		0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 	bra.l		_isp_cas
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 	short		0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 	bra.l		_isp_cas2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 	short		0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 	bra.l		_isp_cas_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 	short		0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 	bra.l		_isp_cas2_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 	short		0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 	bra.l		_isp_cas_inrange
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 	short		0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	bra.l		_isp_cas_terminate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	short		0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	bra.l		_isp_cas_restart
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	short		0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 	space		64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) #############################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	global		_real_chk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) _real_chk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	mov.l		(_060ISP_TABLE-0x80+_off_chk,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	pea.l		(_060ISP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	global		_real_divbyzero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) _real_divbyzero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	mov.l		(_060ISP_TABLE-0x80+_off_divbyzero,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	pea.l		(_060ISP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	global		_real_trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) _real_trace:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	mov.l		(_060ISP_TABLE-0x80+_off_trace,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	pea.l		(_060ISP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	global		_real_access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) _real_access:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	mov.l		(_060ISP_TABLE-0x80+_off_access,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	pea.l		(_060ISP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	global		_isp_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) _isp_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	mov.l		(_060ISP_TABLE-0x80+_off_done,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	pea.l		(_060ISP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) #######################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	global		_real_cas
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) _real_cas:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	mov.l		(_060ISP_TABLE-0x80+_off_cas,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	pea.l		(_060ISP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	global		_real_cas2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) _real_cas2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 	mov.l		(_060ISP_TABLE-0x80+_off_cas2,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	pea.l		(_060ISP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	global		_real_lock_page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) _real_lock_page:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 	mov.l		(_060ISP_TABLE-0x80+_off_lock,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	pea.l		(_060ISP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	global		_real_unlock_page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) _real_unlock_page:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	mov.l		(_060ISP_TABLE-0x80+_off_unlock,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	pea.l		(_060ISP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) #######################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	global		_imem_read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) _imem_read:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	mov.l		(_060ISP_TABLE-0x80+_off_imr,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	pea.l		(_060ISP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	global		_dmem_read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) _dmem_read:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	mov.l		(_060ISP_TABLE-0x80+_off_dmr,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	pea.l		(_060ISP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	global		_dmem_write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) _dmem_write:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	mov.l		(_060ISP_TABLE-0x80+_off_dmw,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	pea.l		(_060ISP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	global		_imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) _imem_read_word:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	mov.l		(_060ISP_TABLE-0x80+_off_irw,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	pea.l		(_060ISP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	global		_imem_read_long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) _imem_read_long:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	mov.l		(_060ISP_TABLE-0x80+_off_irl,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	pea.l		(_060ISP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	global		_dmem_read_byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) _dmem_read_byte:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	mov.l		(_060ISP_TABLE-0x80+_off_drb,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	pea.l		(_060ISP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	global		_dmem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) _dmem_read_word:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	mov.l		(_060ISP_TABLE-0x80+_off_drw,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	pea.l		(_060ISP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	global		_dmem_read_long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) _dmem_read_long:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	mov.l		(_060ISP_TABLE-0x80+_off_drl,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	pea.l		(_060ISP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	global		_dmem_write_byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) _dmem_write_byte:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	mov.l		(_060ISP_TABLE-0x80+_off_dwb,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	pea.l		(_060ISP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	global		_dmem_write_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) _dmem_write_word:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	mov.l		(_060ISP_TABLE-0x80+_off_dww,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	pea.l		(_060ISP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	global		_dmem_write_long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) _dmem_write_long:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	mov.l		(_060ISP_TABLE-0x80+_off_dwl,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	pea.l		(_060ISP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) # This file contains a set of define statements for constants
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) # in oreder to promote readability within the core code itself.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) set LOCAL_SIZE,		96			# stack frame size(bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) set LV,			-LOCAL_SIZE		# stack offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) set EXC_ISR,		0x4			# stack status register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) set EXC_IPC,		0x6			# stack pc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) set EXC_IVOFF,		0xa			# stacked vector offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) set EXC_AREGS,		LV+64			# offset of all address regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) set EXC_DREGS,		LV+32			# offset of all data regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) set EXC_A7,		EXC_AREGS+(7*4)		# offset of a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) set EXC_A6,		EXC_AREGS+(6*4)		# offset of a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) set EXC_A5,		EXC_AREGS+(5*4)		# offset of a5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) set EXC_A4,		EXC_AREGS+(4*4)		# offset of a4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) set EXC_A3,		EXC_AREGS+(3*4)		# offset of a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) set EXC_A2,		EXC_AREGS+(2*4)		# offset of a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) set EXC_A1,		EXC_AREGS+(1*4)		# offset of a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) set EXC_A0,		EXC_AREGS+(0*4)		# offset of a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) set EXC_D7,		EXC_DREGS+(7*4)		# offset of d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) set EXC_D6,		EXC_DREGS+(6*4)		# offset of d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) set EXC_D5,		EXC_DREGS+(5*4)		# offset of d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) set EXC_D4,		EXC_DREGS+(4*4)		# offset of d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) set EXC_D3,		EXC_DREGS+(3*4)		# offset of d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) set EXC_D2,		EXC_DREGS+(2*4)		# offset of d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) set EXC_D1,		EXC_DREGS+(1*4)		# offset of d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) set EXC_D0,		EXC_DREGS+(0*4)		# offset of d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) set EXC_TEMP,		LV+16			# offset of temp stack space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) set EXC_SAVVAL,		LV+12			# offset of old areg value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) set EXC_SAVREG,		LV+11			# offset of old areg index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) set SPCOND_FLG,		LV+10			# offset of spc condition flg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) set EXC_CC,		LV+8			# offset of cc register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) set EXC_EXTWPTR,	LV+4			# offset of current PC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) set EXC_EXTWORD,	LV+2			# offset of current ext opword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) set EXC_OPWORD,		LV+0			# offset of current opword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) ###########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) # SPecial CONDition FLaGs #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) ###########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) set mia7_flg,		0x04			# (a7)+ flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) set mda7_flg,		0x08			# -(a7) flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) set ichk_flg,		0x10			# chk exception flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) set idbyz_flg,		0x20			# divbyzero flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) set restore_flg,	0x40			# restore -(an)+ flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) set immed_flg,		0x80			# immediate data flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) set mia7_bit,		0x2			# (a7)+ bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) set mda7_bit,		0x3			# -(a7) bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) set ichk_bit,		0x4			# chk exception bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) set idbyz_bit,		0x5			# divbyzero bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) set restore_bit,	0x6			# restore -(a7)+ bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) set immed_bit,		0x7			# immediate data bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) #########
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) # Misc. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) #########
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) set BYTE,		1			# len(byte) == 1 byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) set WORD,		2			# len(word) == 2 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) set LONG,		4			# len(longword) == 4 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) #	_isp_unimp(): 060ISP entry point for Unimplemented Instruction	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) #	This handler should be the first code executed upon taking the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) #	"Unimplemented Integer Instruction" exception in an operating	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) #	system.								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) #	_imem_read_{word,long}() - read instruction word/longword	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) #	_mul64() - emulate 64-bit multiply				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) #	_div64() - emulate 64-bit divide				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) #	_moveperipheral() - emulate "movep"				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) #	_compandset() - emulate misaligned "cas"			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) #	_compandset2() - emulate "cas2"					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) #	_chk2_cmp2() - emulate "cmp2" and "chk2"			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) #	_isp_done() - "callout" for normal final exit			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) #	_real_trace() - "callout" for Trace exception			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) #	_real_chk() - "callout" for Chk exception			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) #	_real_divbyzero() - "callout" for DZ exception			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) #	_real_access() - "callout" for access error exception		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) #	- The system stack contains the Unimp Int Instr stack frame	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) #	If Trace exception:						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) #	- The system stack changed to contain Trace exc stack frame	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) #	If Chk exception:						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) #	- The system stack changed to contain Chk exc stack frame	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) #	If DZ exception:						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) #	- The system stack changed to contain DZ exc stack frame	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) #	If access error exception:					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) #	- The system stack changed to contain access err exc stk frame	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) #	Else:								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) #	- Results saved as appropriate					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) #	This handler fetches the first instruction longword from	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) # memory and decodes it to determine which of the unimplemented		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) # integer instructions caused this exception. This handler then calls	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) # one of _mul64(), _div64(), _moveperipheral(), _compandset(),		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) # _compandset2(), or _chk2_cmp2() as appropriate.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) #	Some of these instructions, by their nature, may produce other	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) # types of exceptions. "div" can produce a divide-by-zero exception,	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) # and "chk2" can cause a "Chk" exception. In both cases, the current	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) # exception stack frame must be converted to an exception stack frame	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) # of the correct exception type and an exit must be made through	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) # _real_divbyzero() or _real_chk() as appropriate. In addition, all	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) # instructions may be executing while Trace is enabled. If so, then	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) # a Trace exception stack frame must be created and an exit made	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) # through _real_trace().						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) #	Meanwhile, if any read or write to memory using the		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) # _mem_{read,write}() "callout"s returns a failing value, then an	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) # access error frame must be created and an exit made through		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) # _real_access().							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) #	If none of these occur, then a normal exit is made through	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) # _isp_done().								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) #	This handler, upon entry, saves almost all user-visible		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) # address and data registers to the stack. Although this may seem to	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) # cause excess memory traffic, it was found that due to having to	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) # access these register files for things like data retrieval and <ea>	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) # calculations, it was more efficient to have them on the stack where	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) # they could be accessed by indexing rather than to make subroutine	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) # calls to retrieve a register of a particular index.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	global		_isp_unimp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) _isp_unimp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	link.w		%a6,&-LOCAL_SIZE	# create room for stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	movm.l		&0x3fff,EXC_DREGS(%a6)	# store d0-d7/a0-a5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	mov.l		(%a6),EXC_A6(%a6)	# store a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	btst		&0x5,EXC_ISR(%a6)	# from s or u mode?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	bne.b		uieh_s			# supervisor mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) uieh_u:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 	mov.l		%usp,%a0		# fetch user stack pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	mov.l		%a0,EXC_A7(%a6)		# store a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	bra.b		uieh_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) uieh_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 	lea		0xc(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	mov.l		%a0,EXC_A7(%a6)		# store corrected sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) ###############################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) uieh_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	clr.b		SPCOND_FLG(%a6)		# clear "special case" flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 	mov.w		EXC_ISR(%a6),EXC_CC(%a6) # store cc copy on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	mov.l		EXC_IPC(%a6),EXC_EXTWPTR(%a6) # store extwptr on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) # fetch the opword and first extension word pointed to by the stacked pc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) # and store them to the stack for now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 	bsr.l		_imem_read_long		# fetch opword & extword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 	mov.l		%d0,EXC_OPWORD(%a6)	# store extword on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) # muls.l	0100 1100 00 |<ea>|	0*** 1100 0000 0***		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) # mulu.l	0100 1100 00 |<ea>|	0*** 0100 0000 0***		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) # divs.l	0100 1100 01 |<ea>|	0*** 1100 0000 0***		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) # divu.l	0100 1100 01 |<ea>|	0*** 0100 0000 0***		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) # movep.w m2r	0000 ***1 00 001***	| <displacement>  |		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) # movep.l m2r	0000 ***1 01 001***	| <displacement>  |		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) # movep.w r2m	0000 ***1 10 001***	| <displacement>  |		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) # movep.l r2m	0000 ***1 11 001***	| <displacement>  |		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) # cas.w		0000 1100 11 |<ea>|	0000 000* **00 0***		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) # cas.l		0000 1110 11 |<ea>|	0000 000* **00 0***		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) # cas2.w	0000 1100 11 111100	**** 000* **00 0***		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) #					**** 000* **00 0***		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) # cas2.l	0000 1110 11 111100	**** 000* **00 0***		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) #					**** 000* **00 0***		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) # chk2.b	0000 0000 11 |<ea>|	**** 1000 0000 0000		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) # chk2.w	0000 0010 11 |<ea>|	**** 1000 0000 0000		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) # chk2.l	0000 0100 11 |<ea>|	**** 1000 0000 0000		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) # cmp2.b	0000 0000 11 |<ea>|	**** 0000 0000 0000		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) # cmp2.w	0000 0010 11 |<ea>|	**** 0000 0000 0000		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) # cmp2.l	0000 0100 11 |<ea>|	**** 0000 0000 0000		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) # using bit 14 of the operation word, separate into 2 groups:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) # (group1) mul64, div64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) # (group2) movep, chk2, cmp2, cas2, cas
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	btst		&0x1e,%d0		# group1 or group2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	beq.b		uieh_group2		# go handle group2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) # now, w/ group1, make mul64's decode the fastest since it will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) # most likely be used the most.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) uieh_group1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	btst		&0x16,%d0		# test for div64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	bne.b		uieh_div64		# go handle div64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) uieh_mul64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) # mul64() may use ()+ addressing and may, therefore, alter a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	bsr.l		_mul64			# _mul64()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	btst		&0x5,EXC_ISR(%a6)	# supervisor mode?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	beq.w		uieh_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	btst		&mia7_bit,SPCOND_FLG(%a6) # was a7 changed?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 	beq.w		uieh_done		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 	btst		&0x7,EXC_ISR(%a6)	# is trace enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	bne.w		uieh_trace_a7		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	bra.w		uieh_a7			# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) uieh_div64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) # div64() may use ()+ addressing and may, therefore, alter a7.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) # div64() may take a divide by zero exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	bsr.l		_div64			# _div64()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) # here, we sort out all of the special cases that may have happened.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	btst		&mia7_bit,SPCOND_FLG(%a6) # was a7 changed?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	bne.b		uieh_div64_a7		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) uieh_div64_dbyz:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	btst		&idbyz_bit,SPCOND_FLG(%a6) # did divide-by-zero occur?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	bne.w		uieh_divbyzero		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	bra.w		uieh_done		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) uieh_div64_a7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	btst		&0x5,EXC_ISR(%a6)	# supervisor mode?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	beq.b		uieh_div64_dbyz		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) # here, a7 has been incremented by 4 bytes in supervisor mode. we still
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) # may have the following 3 cases:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) #	(i)	(a7)+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) #	(ii)	(a7)+; trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) #	(iii)	(a7)+; divide-by-zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	btst		&idbyz_bit,SPCOND_FLG(%a6) # did divide-by-zero occur?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 	bne.w		uieh_divbyzero_a7	# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	tst.b		EXC_ISR(%a6)		# no; is trace enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	bmi.w		uieh_trace_a7		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	bra.w		uieh_a7			# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) # now, w/ group2, make movep's decode the fastest since it will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) # most likely be used the most.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) uieh_group2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	btst		&0x18,%d0		# test for not movep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	beq.b		uieh_not_movep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	bsr.l		_moveperipheral		# _movep()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	bra.w		uieh_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) uieh_not_movep:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	btst		&0x1b,%d0		# test for chk2,cmp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	beq.b		uieh_chk2cmp2		# go handle chk2,cmp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	swap		%d0			# put opword in lo word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 	cmpi.b		%d0,&0xfc		# test for cas2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	beq.b		uieh_cas2		# go handle cas2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) uieh_cas:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 	bsr.l		_compandset		# _cas()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) # the cases of "cas Dc,Du,(a7)+" and "cas Dc,Du,-(a7)" used from supervisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) # mode are simply not considered valid and therefore are not handled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	bra.w		uieh_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) uieh_cas2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	bsr.l		_imem_read_word		# read extension word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	tst.l		%d1			# ifetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	bne.w		isp_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	bsr.l		_compandset2		# _cas2()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	bra.w		uieh_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) uieh_chk2cmp2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) # chk2 may take a chk exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	bsr.l		_chk2_cmp2		# _chk2_cmp2()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) # here we check to see if a chk trap should be taken
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	cmpi.b		SPCOND_FLG(%a6),&ichk_flg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	bne.w		uieh_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	bra.b		uieh_chk_trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) ###########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) # the required emulation has been completed. now, clean up the necessary stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) # info and prepare for rte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) uieh_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	mov.b		EXC_CC+1(%a6),EXC_ISR+1(%a6) # insert new ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) # if exception occurred in user mode, then we have to restore a7 in case it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) # changed. we don't have to update a7  for supervisor mose because that case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) # doesn't flow through here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	btst		&0x5,EXC_ISR(%a6)	# user or supervisor?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	bne.b		uieh_finish		# supervisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	mov.l		EXC_A7(%a6),%a0		# fetch user stack pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	mov.l		%a0,%usp		# restore it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) uieh_finish:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	movm.l		EXC_DREGS(%a6),&0x3fff	# restore d0-d7/a0-a5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	btst		&0x7,EXC_ISR(%a6)	# is trace mode on?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	bne.b		uieh_trace		# yes;go handle trace mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	mov.l		EXC_EXTWPTR(%a6),EXC_IPC(%a6) # new pc on stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	mov.l		EXC_A6(%a6),(%a6)	# prepare new a6 for unlink
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	unlk		%a6			# unlink stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	bra.l		_isp_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) # The instruction that was just emulated was also being traced. The trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) # trap for this instruction will be lost unless we jump to the trace handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) # So, here we create a Trace Exception format number two exception stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) # frame from the Unimplemented Integer Intruction Exception stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) # format number zero and jump to the user supplied hook "_real_trace()".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) #		   UIEH FRAME		   TRACE FRAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) #		*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) #		* 0x0 *  0x0f4	*	*    Current	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) #		*****************	*      PC	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) #		*    Current	*	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) #		*      PC	*	* 0x2 *  0x024	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) #		*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) #		*      SR	*	*     Next	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) #		*****************	*      PC	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) #	      ->*     Old	*	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) #  from link -->*      A6	*	*      SR	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) #	        *****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) #	       /*      A7	*	*      New	* <-- for final unlink
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) #	      / *		*	*      A6	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) # link frame <  *****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) #	      \ ~		~	~		~
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) #	       \*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) uieh_trace:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	mov.l		EXC_A6(%a6),-0x4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	mov.w		EXC_ISR(%a6),0x0(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	mov.l		EXC_IPC(%a6),0x8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	mov.l		EXC_EXTWPTR(%a6),0x2(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	mov.w		&0x2024,0x6(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	sub.l		&0x4,%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	unlk		%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 	bra.l		_real_trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) #	   UIEH FRAME		    CHK FRAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) #	*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) #	* 0x0 *  0x0f4	*	*    Current	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) #	*****************	*      PC	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) #	*    Current	*	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) #	*      PC	*	* 0x2 *  0x018	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) #	*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) #	*      SR	*	*     Next	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) #	*****************	*      PC	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) #	    (4 words)		*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) #				*      SR	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) #				*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) #				    (6 words)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) # the chk2 instruction should take a chk trap. so, here we must create a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) # chk stack frame from an unimplemented integer instruction exception frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) # and jump to the user supplied entry point "_real_chk()".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) uieh_chk_trap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	mov.b		EXC_CC+1(%a6),EXC_ISR+1(%a6) # insert new ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	movm.l		EXC_DREGS(%a6),&0x3fff	# restore d0-d7/a0-a5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	mov.w		EXC_ISR(%a6),(%a6)	# put new SR on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	mov.l		EXC_IPC(%a6),0x8(%a6)	# put "Current PC" on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 	mov.l		EXC_EXTWPTR(%a6),0x2(%a6) # put "Next PC" on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 	mov.w		&0x2018,0x6(%a6)	# put Vector Offset on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 	mov.l		EXC_A6(%a6),%a6		# restore a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 	add.l		&LOCAL_SIZE,%sp		# clear stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	bra.l		_real_chk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) #	   UIEH FRAME		 DIVBYZERO FRAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) #	*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) #	* 0x0 *  0x0f4	*	*    Current	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) #	*****************	*      PC	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) #	*    Current	*	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) #	*      PC	*	* 0x2 *  0x014	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) #	*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) #	*      SR	*	*     Next	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) #	*****************	*      PC	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) #	    (4 words)		*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) #				*      SR	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) #				*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) #				    (6 words)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) # the divide instruction should take an integer divide by zero trap. so, here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) # we must create a divbyzero stack frame from an unimplemented integer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) # instruction exception frame and jump to the user supplied entry point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) # "_real_divbyzero()".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) uieh_divbyzero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	mov.b		EXC_CC+1(%a6),EXC_ISR+1(%a6) # insert new ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	movm.l		EXC_DREGS(%a6),&0x3fff	# restore d0-d7/a0-a5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	mov.w		EXC_ISR(%a6),(%a6)	# put new SR on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	mov.l		EXC_IPC(%a6),0x8(%a6)	# put "Current PC" on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	mov.l		EXC_EXTWPTR(%a6),0x2(%a6) # put "Next PC" on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 	mov.w		&0x2014,0x6(%a6)	# put Vector Offset on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	mov.l		EXC_A6(%a6),%a6		# restore a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	add.l		&LOCAL_SIZE,%sp		# clear stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	bra.l		_real_divbyzero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) #				 DIVBYZERO FRAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) #				*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) #				*    Current	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) #	   UIEH FRAME		*      PC	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) #	*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) #	* 0x0 *  0x0f4	*	* 0x2 * 0x014	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) #	*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) #	*    Current	*	*     Next	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) #	*      PC	*	*      PC	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) #	*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) #	*      SR	*	*      SR	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) #	*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) #	    (4 words)		    (6 words)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) # the divide instruction should take an integer divide by zero trap. so, here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) # we must create a divbyzero stack frame from an unimplemented integer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) # instruction exception frame and jump to the user supplied entry point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) # "_real_divbyzero()".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) # However, we must also deal with the fact that (a7)+ was used from supervisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) # mode, thereby shifting the stack frame up 4 bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) uieh_divbyzero_a7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	mov.b		EXC_CC+1(%a6),EXC_ISR+1(%a6) # insert new ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	movm.l		EXC_DREGS(%a6),&0x3fff	# restore d0-d7/a0-a5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 	mov.l		EXC_IPC(%a6),0xc(%a6)	# put "Current PC" on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 	mov.w		&0x2014,0xa(%a6)	# put Vector Offset on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	mov.l		EXC_EXTWPTR(%a6),0x6(%a6) # put "Next PC" on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	mov.l		EXC_A6(%a6),%a6		# restore a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	add.l		&4+LOCAL_SIZE,%sp	# clear stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	bra.l		_real_divbyzero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) #				   TRACE FRAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) #				*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) #				*    Current	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) #	   UIEH FRAME		*      PC	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) #	*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) #	* 0x0 *  0x0f4	*	* 0x2 * 0x024	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) #	*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) #	*    Current	*	*     Next	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) #	*      PC	*	*      PC	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) #	*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) #	*      SR	*	*      SR	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) #	*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) #	    (4 words)		    (6 words)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) # The instruction that was just emulated was also being traced. The trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) # trap for this instruction will be lost unless we jump to the trace handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) # So, here we create a Trace Exception format number two exception stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) # frame from the Unimplemented Integer Intruction Exception stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) # format number zero and jump to the user supplied hook "_real_trace()".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) # However, we must also deal with the fact that (a7)+ was used from supervisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) # mode, thereby shifting the stack frame up 4 bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) uieh_trace_a7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	mov.b		EXC_CC+1(%a6),EXC_ISR+1(%a6) # insert new ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 	movm.l		EXC_DREGS(%a6),&0x3fff	# restore d0-d7/a0-a5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	mov.l		EXC_IPC(%a6),0xc(%a6)	# put "Current PC" on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	mov.w		&0x2024,0xa(%a6)	# put Vector Offset on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	mov.l		EXC_EXTWPTR(%a6),0x6(%a6) # put "Next PC" on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 	mov.l		EXC_A6(%a6),%a6		# restore a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 	add.l		&4+LOCAL_SIZE,%sp	# clear stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 	bra.l		_real_trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) #				   UIEH FRAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) #				*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) #				* 0x0 * 0x0f4	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) #	   UIEH FRAME		*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) #	*****************	*     Next	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) #	* 0x0 *  0x0f4	*	*      PC	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) #	*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) #	*    Current	*	*      SR	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) #	*      PC	*	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) #	*****************	    (4 words)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) #	*      SR	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) #	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) #	    (4 words)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) uieh_a7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	mov.b		EXC_CC+1(%a6),EXC_ISR+1(%a6) # insert new ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	movm.l		EXC_DREGS(%a6),&0x3fff	# restore d0-d7/a0-a5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	mov.w		&0x00f4,0xe(%a6)	# put Vector Offset on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	mov.l		EXC_EXTWPTR(%a6),0xa(%a6) # put "Next PC" on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	mov.w		EXC_ISR(%a6),0x8(%a6)	# put SR on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 	mov.l		EXC_A6(%a6),%a6		# restore a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 	add.l		&8+LOCAL_SIZE,%sp	# clear stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	bra.l		_isp_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) ##########
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) # this is the exit point if a data read or write fails.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) # a0 = failing address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) # d0 = fslw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) isp_dacc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 	mov.l		%a0,(%a6)		# save address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	mov.l		%d0,-0x4(%a6)		# save partial fslw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	lea		-64(%a6),%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	movm.l		(%sp)+,&0x7fff		# restore d0-d7/a0-a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 	mov.l		0xc(%sp),-(%sp)		# move voff,hi(pc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	mov.l		0x4(%sp),0x10(%sp)	# store fslw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	mov.l		0xc(%sp),0x4(%sp)	# store sr,lo(pc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	mov.l		0x8(%sp),0xc(%sp)	# store address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 	mov.l		(%sp)+,0x4(%sp)		# store voff,hi(pc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	mov.w		&0x4008,0x6(%sp)	# store new voff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	bra.b		isp_acc_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) # this is the exit point if an instruction word read fails.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) # FSLW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) #	misaligned = true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) #	read = true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) #	size = word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) #	instruction = true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) #	software emulation error = true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) isp_iacc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	movm.l		EXC_DREGS(%a6),&0x3fff	# restore d0-d7/a0-a5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	unlk		%a6			# unlink frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	sub.w		&0x8,%sp		# make room for acc frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 	mov.l		0x8(%sp),(%sp)		# store sr,lo(pc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	mov.w		0xc(%sp),0x4(%sp)	# store hi(pc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	mov.w		&0x4008,0x6(%sp)	# store new voff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	mov.l		0x2(%sp),0x8(%sp)	# store address (=pc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	mov.l		&0x09428001,0xc(%sp)	# store fslw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) isp_acc_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	btst		&0x5,(%sp)		# user or supervisor?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	beq.b		isp_acc_exit2		# user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 	bset		&0x2,0xd(%sp)		# set supervisor TM bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) isp_acc_exit2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	bra.l		_real_access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) # if the addressing mode was (an)+ or -(an), the address register must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) # be restored to its pre-exception value before entering _real_access.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) isp_restore:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	cmpi.b		SPCOND_FLG(%a6),&restore_flg # do we need a restore?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	bne.b		isp_restore_done	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	clr.l		%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	mov.b		EXC_SAVREG(%a6),%d0	# regno to restore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	mov.l		EXC_SAVVAL(%a6),(EXC_AREGS,%a6,%d0.l*4) # restore value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) isp_restore_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) #	_calc_ea(): routine to calculate effective address		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) #	_imem_read_word() - read instruction word			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) #	_imem_read_long() - read instruction longword			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) #	_dmem_read_long() - read data longword (for memory indirect)	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) #	isp_iacc() - handle instruction access error exception		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) #	isp_dacc() - handle data access error exception			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) #	d0 = number of bytes related to effective address (w,l)		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) #	If exiting through isp_dacc...					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) #		a0 = failing address					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) #		d0 = FSLW						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) #	elsif exiting though isp_iacc...				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) #		none							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) #	else								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) #		a0 = effective address					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) #	The effective address type is decoded from the opword residing	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) # on the stack. A jump table is used to vector to a routine for the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) # appropriate mode. Since none of the emulated integer instructions	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) # uses byte-sized operands, only handle word and long operations.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) #	Dn,An	- shouldn't enter here					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) #	(An)	- fetch An value from stack				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) #	-(An)	- fetch An value from stack; return decr value;		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) #		  place decr value on stack; store old value in case of	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) #		  future access error; if -(a7), set mda7_flg in	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) #		  SPCOND_FLG						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) #	(An)+	- fetch An value from stack; return value;		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) #		  place incr value on stack; store old value in case of	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) #		  future access error; if (a7)+, set mia7_flg in	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) #		  SPCOND_FLG						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) #	(d16,An) - fetch An value from stack; read d16 using		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) #		  _imem_read_word(); fetch may fail -> branch to	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) #		  isp_iacc()						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) #	(xxx).w,(xxx).l - use _imem_read_{word,long}() to fetch		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) #		  address; fetch may fail				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) #	#<data> - return address of immediate value; set immed_flg	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) #		  in SPCOND_FLG						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) #	(d16,PC) - fetch stacked PC value; read d16 using		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) #		  _imem_read_word(); fetch may fail -> branch to	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) #		  isp_iacc()						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) #	everything else - read needed displacements as appropriate w/	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) #		  _imem_read_{word,long}(); read may fail; if memory	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) #		  indirect, read indirect address using			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) #		  _dmem_read_long() which may also fail			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	global		_calc_ea
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) _calc_ea:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 	mov.l		%d0,%a0			# move # bytes to a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) # MODE and REG are taken from the EXC_OPWORD.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	mov.w		EXC_OPWORD(%a6),%d0	# fetch opcode word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	mov.w		%d0,%d1			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	andi.w		&0x3f,%d0		# extract mode field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	andi.l		&0x7,%d1		# extract reg  field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) # jump to the corresponding function for each {MODE,REG} pair.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	mov.w		(tbl_ea_mode.b,%pc,%d0.w*2), %d0 # fetch jmp distance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	jmp		(tbl_ea_mode.b,%pc,%d0.w*1) # jmp to correct ea mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	swbeg		&64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) tbl_ea_mode:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	short		tbl_ea_mode	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	short		tbl_ea_mode	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	short		tbl_ea_mode	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	short		tbl_ea_mode	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	short		tbl_ea_mode	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	short		tbl_ea_mode	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	short		tbl_ea_mode	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	short		tbl_ea_mode	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	short		tbl_ea_mode	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	short		tbl_ea_mode	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	short		tbl_ea_mode	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	short		tbl_ea_mode	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	short		tbl_ea_mode	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	short		tbl_ea_mode	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	short		tbl_ea_mode	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	short		tbl_ea_mode	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	short		addr_ind_a0	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	short		addr_ind_a1	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	short		addr_ind_a2	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	short		addr_ind_a3	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	short		addr_ind_a4	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	short		addr_ind_a5	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	short		addr_ind_a6	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	short		addr_ind_a7	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	short		addr_ind_p_a0	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	short		addr_ind_p_a1	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	short		addr_ind_p_a2	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	short		addr_ind_p_a3	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	short		addr_ind_p_a4	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	short		addr_ind_p_a5	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	short		addr_ind_p_a6	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	short		addr_ind_p_a7	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	short		addr_ind_m_a0		-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	short		addr_ind_m_a1		-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	short		addr_ind_m_a2		-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	short		addr_ind_m_a3		-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	short		addr_ind_m_a4		-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	short		addr_ind_m_a5		-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 	short		addr_ind_m_a6		-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	short		addr_ind_m_a7		-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	short		addr_ind_disp_a0	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	short		addr_ind_disp_a1	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	short		addr_ind_disp_a2	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	short		addr_ind_disp_a3	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	short		addr_ind_disp_a4	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	short		addr_ind_disp_a5	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	short		addr_ind_disp_a6	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	short		addr_ind_disp_a7	-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	short		_addr_ind_ext		-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	short		_addr_ind_ext		-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	short		_addr_ind_ext		-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	short		_addr_ind_ext		-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	short		_addr_ind_ext		-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	short		_addr_ind_ext		-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	short		_addr_ind_ext		-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	short		_addr_ind_ext		-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	short		abs_short		-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	short		abs_long		-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	short		pc_ind			-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	short		pc_ind_ext		-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	short		immediate		-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	short		tbl_ea_mode		-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	short		tbl_ea_mode		-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 	short		tbl_ea_mode		-	tbl_ea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) ###################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) # Address register indirect: (An) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) ###################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) addr_ind_a0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	mov.l		EXC_A0(%a6),%a0		# Get current a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) addr_ind_a1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	mov.l		EXC_A1(%a6),%a0		# Get current a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) addr_ind_a2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	mov.l		EXC_A2(%a6),%a0		# Get current a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) addr_ind_a3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	mov.l		EXC_A3(%a6),%a0		# Get current a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) addr_ind_a4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	mov.l		EXC_A4(%a6),%a0		# Get current a4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) addr_ind_a5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	mov.l		EXC_A5(%a6),%a0		# Get current a5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) addr_ind_a6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	mov.l		EXC_A6(%a6),%a0		# Get current a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) addr_ind_a7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	mov.l		EXC_A7(%a6),%a0		# Get current a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) #####################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) # Address register indirect w/ postincrement: (An)+ #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) #####################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) addr_ind_p_a0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	mov.l		%a0,%d0			# copy no. bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	mov.l		EXC_A0(%a6),%a0		# load current value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	add.l		%a0,%d0			# increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	mov.l		%d0,EXC_A0(%a6)		# save incremented value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 	mov.l		%a0,EXC_SAVVAL(%a6)	# save in case of access error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 	mov.b		&0x0,EXC_SAVREG(%a6)	# save regno, too
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	mov.b		&restore_flg,SPCOND_FLG(%a6) # set flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) addr_ind_p_a1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	mov.l		%a0,%d0			# copy no. bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	mov.l		EXC_A1(%a6),%a0		# load current value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	add.l		%a0,%d0			# increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	mov.l		%d0,EXC_A1(%a6)		# save incremented value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	mov.l		%a0,EXC_SAVVAL(%a6)	# save in case of access error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	mov.b		&0x1,EXC_SAVREG(%a6)	# save regno, too
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	mov.b		&restore_flg,SPCOND_FLG(%a6) # set flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) addr_ind_p_a2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	mov.l		%a0,%d0			# copy no. bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	mov.l		EXC_A2(%a6),%a0		# load current value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 	add.l		%a0,%d0			# increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	mov.l		%d0,EXC_A2(%a6)		# save incremented value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	mov.l		%a0,EXC_SAVVAL(%a6)	# save in case of access error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 	mov.b		&0x2,EXC_SAVREG(%a6)	# save regno, too
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	mov.b		&restore_flg,SPCOND_FLG(%a6) # set flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) addr_ind_p_a3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	mov.l		%a0,%d0			# copy no. bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 	mov.l		EXC_A3(%a6),%a0		# load current value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	add.l		%a0,%d0			# increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	mov.l		%d0,EXC_A3(%a6)		# save incremented value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	mov.l		%a0,EXC_SAVVAL(%a6)	# save in case of access error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 	mov.b		&0x3,EXC_SAVREG(%a6)	# save regno, too
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	mov.b		&restore_flg,SPCOND_FLG(%a6) # set flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) addr_ind_p_a4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	mov.l		%a0,%d0			# copy no. bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	mov.l		EXC_A4(%a6),%a0		# load current value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 	add.l		%a0,%d0			# increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	mov.l		%d0,EXC_A4(%a6)		# save incremented value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	mov.l		%a0,EXC_SAVVAL(%a6)	# save in case of access error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	mov.b		&0x4,EXC_SAVREG(%a6)	# save regno, too
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	mov.b		&restore_flg,SPCOND_FLG(%a6) # set flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) addr_ind_p_a5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	mov.l		%a0,%d0			# copy no. bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 	mov.l		EXC_A5(%a6),%a0		# load current value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	add.l		%a0,%d0			# increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	mov.l		%d0,EXC_A5(%a6)		# save incremented value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	mov.l		%a0,EXC_SAVVAL(%a6)	# save in case of access error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	mov.b		&0x5,EXC_SAVREG(%a6)	# save regno, too
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	mov.b		&restore_flg,SPCOND_FLG(%a6) # set flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) addr_ind_p_a6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	mov.l		%a0,%d0			# copy no. bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	mov.l		EXC_A6(%a6),%a0		# load current value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	add.l		%a0,%d0			# increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	mov.l		%d0,EXC_A6(%a6)		# save incremented value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	mov.l		%a0,EXC_SAVVAL(%a6)	# save in case of access error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	mov.b		&0x6,EXC_SAVREG(%a6)	# save regno, too
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	mov.b		&restore_flg,SPCOND_FLG(%a6) # set flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) addr_ind_p_a7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	mov.b		&mia7_flg,SPCOND_FLG(%a6) # set "special case" flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 	mov.l		%a0,%d0			# copy no. bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	mov.l		EXC_A7(%a6),%a0		# load current value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 	add.l		%a0,%d0			# increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 	mov.l		%d0,EXC_A7(%a6)		# save incremented value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) ####################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) # Address register indirect w/ predecrement: -(An) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) ####################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) addr_ind_m_a0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	mov.l		EXC_A0(%a6),%d0		# Get current a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 	mov.l		%d0,EXC_SAVVAL(%a6)	# save in case of access error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 	sub.l		%a0,%d0			# Decrement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 	mov.l		%d0,EXC_A0(%a6)		# Save decr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	mov.l		%d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 	mov.b		&0x0,EXC_SAVREG(%a6)	# save regno, too
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 	mov.b		&restore_flg,SPCOND_FLG(%a6) # set flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) addr_ind_m_a1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 	mov.l		EXC_A1(%a6),%d0		# Get current a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 	mov.l		%d0,EXC_SAVVAL(%a6)	# save in case of access error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 	sub.l		%a0,%d0			# Decrement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 	mov.l		%d0,EXC_A1(%a6)		# Save decr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 	mov.l		%d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	mov.b		&0x1,EXC_SAVREG(%a6)	# save regno, too
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	mov.b		&restore_flg,SPCOND_FLG(%a6) # set flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) addr_ind_m_a2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 	mov.l		EXC_A2(%a6),%d0		# Get current a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	mov.l		%d0,EXC_SAVVAL(%a6)	# save in case of access error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	sub.l		%a0,%d0			# Decrement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	mov.l		%d0,EXC_A2(%a6)		# Save decr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	mov.l		%d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	mov.b		&0x2,EXC_SAVREG(%a6)	# save regno, too
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	mov.b		&restore_flg,SPCOND_FLG(%a6) # set flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) addr_ind_m_a3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	mov.l		EXC_A3(%a6),%d0		# Get current a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	mov.l		%d0,EXC_SAVVAL(%a6)	# save in case of access error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	sub.l		%a0,%d0			# Decrement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 	mov.l		%d0,EXC_A3(%a6)		# Save decr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	mov.l		%d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 	mov.b		&0x3,EXC_SAVREG(%a6)	# save regno, too
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 	mov.b		&restore_flg,SPCOND_FLG(%a6) # set flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) addr_ind_m_a4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 	mov.l		EXC_A4(%a6),%d0		# Get current a4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 	mov.l		%d0,EXC_SAVVAL(%a6)	# save in case of access error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 	sub.l		%a0,%d0			# Decrement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 	mov.l		%d0,EXC_A4(%a6)		# Save decr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	mov.l		%d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 	mov.b		&0x4,EXC_SAVREG(%a6)	# save regno, too
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 	mov.b		&restore_flg,SPCOND_FLG(%a6) # set flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) addr_ind_m_a5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 	mov.l		EXC_A5(%a6),%d0		# Get current a5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 	mov.l		%d0,EXC_SAVVAL(%a6)	# save in case of access error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 	sub.l		%a0,%d0			# Decrement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 	mov.l		%d0,EXC_A5(%a6)		# Save decr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	mov.l		%d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 	mov.b		&0x5,EXC_SAVREG(%a6)	# save regno, too
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 	mov.b		&restore_flg,SPCOND_FLG(%a6) # set flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) addr_ind_m_a6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 	mov.l		EXC_A6(%a6),%d0		# Get current a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 	mov.l		%d0,EXC_SAVVAL(%a6)	# save in case of access error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 	sub.l		%a0,%d0			# Decrement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	mov.l		%d0,EXC_A6(%a6)		# Save decr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	mov.l		%d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	mov.b		&0x6,EXC_SAVREG(%a6)	# save regno, too
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	mov.b		&restore_flg,SPCOND_FLG(%a6) # set flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) addr_ind_m_a7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	mov.b		&mda7_flg,SPCOND_FLG(%a6) # set "special case" flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 	mov.l		EXC_A7(%a6),%d0		# Get current a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 	sub.l		%a0,%d0			# Decrement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 	mov.l		%d0,EXC_A7(%a6)		# Save decr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 	mov.l		%d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) ########################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) # Address register indirect w/ displacement: (d16, An) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) ########################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) addr_ind_disp_a0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 	bsr.l		_imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 	tst.l		%d1			# ifetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 	bne.l		isp_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 	mov.w		%d0,%a0			# sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 	add.l		EXC_A0(%a6),%a0		# a0 + d16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) addr_ind_disp_a1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 	bsr.l		_imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 	tst.l		%d1			# ifetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 	bne.l		isp_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 	mov.w		%d0,%a0			# sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 	add.l		EXC_A1(%a6),%a0		# a1 + d16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) addr_ind_disp_a2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 	bsr.l		_imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 	tst.l		%d1			# ifetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 	bne.l		isp_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 	mov.w		%d0,%a0			# sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 	add.l		EXC_A2(%a6),%a0		# a2 + d16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) addr_ind_disp_a3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 	bsr.l		_imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 	tst.l		%d1			# ifetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 	bne.l		isp_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 	mov.w		%d0,%a0			# sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 	add.l		EXC_A3(%a6),%a0		# a3 + d16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) addr_ind_disp_a4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 	bsr.l		_imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 	tst.l		%d1			# ifetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 	bne.l		isp_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 	mov.w		%d0,%a0			# sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	add.l		EXC_A4(%a6),%a0		# a4 + d16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) addr_ind_disp_a5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 	bsr.l		_imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	tst.l		%d1			# ifetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	bne.l		isp_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 	mov.w		%d0,%a0			# sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 	add.l		EXC_A5(%a6),%a0		# a5 + d16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) addr_ind_disp_a6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 	bsr.l		_imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 	tst.l		%d1			# ifetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 	bne.l		isp_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 	mov.w		%d0,%a0			# sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 	add.l		EXC_A6(%a6),%a0		# a6 + d16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) addr_ind_disp_a7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 	bsr.l		_imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 	tst.l		%d1			# ifetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 	bne.l		isp_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 	mov.w		%d0,%a0			# sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 	add.l		EXC_A7(%a6),%a0		# a7 + d16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) ########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) # Address register indirect w/ index(8-bit displacement): (dn, An, Xn) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) #    "       "         "    w/   "  (base displacement): (bd, An, Xn)  #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) # Memory indirect postindexed: ([bd, An], Xn, od)		       #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) # Memory indirect preindexed: ([bd, An, Xn], od)		       #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) ########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) _addr_ind_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 	mov.l		%d1,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	bsr.l		_imem_read_word		# fetch extword in d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 	tst.l		%d1			# ifetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 	bne.l		isp_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 	mov.l		(%sp)+,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 	mov.l		(EXC_AREGS,%a6,%d1.w*4),%a0 # put base in a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 	btst		&0x8,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 	beq.b		addr_ind_index_8bit	# for ext word or not?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 	movm.l		&0x3c00,-(%sp)		# save d2-d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	mov.l		%d0,%d5			# put extword in d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 	mov.l		%a0,%d3			# put base in d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 	bra.l		calc_mem_ind		# calc memory indirect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) addr_ind_index_8bit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 	mov.l		%d2,-(%sp)		# save old d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 	mov.l		%d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 	rol.w		&0x4,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	andi.w		&0xf,%d1		# extract index regno
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	mov.l		(EXC_DREGS,%a6,%d1.w*4),%d1 # fetch index reg value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 	btst		&0xb,%d0		# is it word or long?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 	bne.b		aii8_long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 	ext.l		%d1			# sign extend word index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) aii8_long:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 	mov.l		%d0,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 	rol.w		&0x7,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 	andi.l		&0x3,%d2		# extract scale value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 	lsl.l		%d2,%d1			# shift index by scale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 	extb.l		%d0			# sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 	add.l		%d1,%d0			# index + disp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 	add.l		%d0,%a0			# An + (index + disp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 	mov.l		(%sp)+,%d2		# restore old d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) ######################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) # Immediate: #<data> #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) # word, long: <ea> of the data is the current extension word		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) #	pointer value. new extension word pointer is simply the old	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) #	plus the number of bytes in the data type(2 or 4).		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) immediate:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 	mov.b		&immed_flg,SPCOND_FLG(%a6) # set immediate flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch extension word ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) ###########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) # Absolute short: (XXX).W #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) ###########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) abs_short:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 	bsr.l		_imem_read_word		# fetch short address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 	tst.l		%d1			# ifetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 	bne.l		isp_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 	mov.w		%d0,%a0			# return <ea> in a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) ##########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) # Absolute long: (XXX).L #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) ##########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) abs_long:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 	bsr.l		_imem_read_long		# fetch long address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 	tst.l		%d1			# ifetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 	bne.l		isp_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 	mov.l		%d0,%a0			# return <ea> in a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) #######################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) # Program counter indirect w/ displacement: (d16, PC) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) #######################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) pc_ind:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 	bsr.l		_imem_read_word		# fetch word displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 	tst.l		%d1			# ifetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 	bne.l		isp_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 	mov.w		%d0,%a0			# sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 	add.l		EXC_EXTWPTR(%a6),%a0	# pc + d16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) # _imem_read_word() increased the extwptr by 2. need to adjust here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 	subq.l		&0x2,%a0		# adjust <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) ##########################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) # PC indirect w/ index(8-bit displacement): (d8, PC, An) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) # "     "     w/   "  (base displacement): (bd, PC, An)  #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) # PC memory indirect postindexed: ([bd, PC], Xn, od)     #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) # PC memory indirect preindexed: ([bd, PC, Xn], od)      #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) ##########################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) pc_ind_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 	bsr.l		_imem_read_word		# fetch ext word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 	tst.l		%d1			# ifetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 	bne.l		isp_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 	mov.l		EXC_EXTWPTR(%a6),%a0	# put base in a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 	subq.l		&0x2,%a0		# adjust base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 	btst		&0x8,%d0		# is disp only 8 bits?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 	beq.b		pc_ind_index_8bit	# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) # the indexed addressing mode uses a base displacement of size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) # word or long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 	movm.l		&0x3c00,-(%sp)		# save d2-d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 	mov.l		%d0,%d5			# put extword in d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 	mov.l		%a0,%d3			# put base in d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 	bra.l		calc_mem_ind		# calc memory indirect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) pc_ind_index_8bit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 	mov.l		%d2,-(%sp)		# create a temp register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 	mov.l		%d0,%d1			# make extword copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 	rol.w		&0x4,%d1		# rotate reg num into place
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 	andi.w		&0xf,%d1		# extract register number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 	mov.l		(EXC_DREGS,%a6,%d1.w*4),%d1 # fetch index reg value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 	btst		&0xb,%d0		# is index word or long?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 	bne.b		pii8_long		# long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 	ext.l		%d1			# sign extend word index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) pii8_long:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 	mov.l		%d0,%d2			# make extword copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 	rol.w		&0x7,%d2		# rotate scale value into place
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 	andi.l		&0x3,%d2		# extract scale value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 	lsl.l		%d2,%d1			# shift index by scale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 	extb.l		%d0			# sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 	add.l		%d1,%d0			# index + disp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 	add.l		%d0,%a0			# An + (index + disp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 	mov.l		(%sp)+,%d2		# restore temp register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) # a5 = exc_extwptr	(global to uaeh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) # a4 = exc_opword	(global to uaeh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) # a3 = exc_dregs	(global to uaeh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) # d2 = index		(internal "     "    )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) # d3 = base		(internal "     "    )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) # d4 = od		(internal "     "    )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) # d5 = extword		(internal "     "    )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) calc_mem_ind:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 	btst		&0x6,%d5		# is the index suppressed?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 	beq.b		calc_index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 	clr.l		%d2			# yes, so index = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 	bra.b		base_supp_ck
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) calc_index:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 	bfextu		%d5{&16:&4},%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 	mov.l		(EXC_DREGS,%a6,%d2.w*4),%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 	btst		&0xb,%d5		# is index word or long?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 	bne.b		no_ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 	ext.l		%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) no_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 	bfextu		%d5{&21:&2},%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 	lsl.l		%d0,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) base_supp_ck:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 	btst		&0x7,%d5		# is the bd suppressed?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 	beq.b		no_base_sup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 	clr.l		%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) no_base_sup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 	bfextu		%d5{&26:&2},%d0	# get bd size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) #	beq.l		_error			# if (size == 0) it's reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 	cmpi.b		%d0,&2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 	blt.b		no_bd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 	beq.b		get_word_bd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 	bsr.l		_imem_read_long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 	tst.l		%d1			# ifetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 	bne.l		isp_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 	bra.b		chk_ind
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) get_word_bd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 	bsr.l		_imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 	tst.l		%d1			# ifetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 	bne.l		isp_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 	ext.l		%d0			# sign extend bd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) chk_ind:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 	add.l		%d0,%d3			# base += bd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) no_bd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 	bfextu		%d5{&30:&2},%d0		# is od suppressed?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 	beq.w		aii_bd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 	cmpi.b		%d0,&0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 	blt.b		null_od
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 	beq.b		word_od
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 	bsr.l		_imem_read_long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 	tst.l		%d1			# ifetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 	bne.l		isp_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 	bra.b		add_them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) word_od:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 	bsr.l		_imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 	tst.l		%d1			# ifetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 	bne.l		isp_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 	ext.l		%d0			# sign extend od
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 	bra.b		add_them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) null_od:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 	clr.l		%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) add_them:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 	mov.l		%d0,%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 	btst		&0x2,%d5		# pre or post indexing?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 	beq.b		pre_indexed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 	mov.l		%d3,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 	bsr.l		_dmem_read_long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 	tst.l		%d1			# dfetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 	bne.b		calc_ea_err		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 	add.l		%d2,%d0			# <ea> += index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 	add.l		%d4,%d0			# <ea> += od
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 	bra.b		done_ea
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) pre_indexed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 	add.l		%d2,%d3			# preindexing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 	mov.l		%d3,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 	bsr.l		_dmem_read_long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 	tst.l		%d1			# ifetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 	bne.b		calc_ea_err		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 	add.l		%d4,%d0			# ea += od
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 	bra.b		done_ea
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) aii_bd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 	add.l		%d2,%d3			# ea = (base + bd) + index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 	mov.l		%d3,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) done_ea:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 	mov.l		%d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 	movm.l		(%sp)+,&0x003c		# restore d2-d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) # if dmem_read_long() returns a fail message in d1, the package
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) # must create an access error frame. here, we pass a skeleton fslw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) # and the failing address to the routine that creates the new frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) # FSLW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) #	read = true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) #	size = longword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) #	TM = data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) #	software emulation error = true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) calc_ea_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 	mov.l		%d3,%a0			# pass failing address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 	mov.l		&0x01010001,%d0		# pass fslw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 	bra.l		isp_dacc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) #	_moveperipheral(): routine to emulate movep instruction		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) #	_dmem_read_byte() - read byte from memory			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) #	_dmem_write_byte() - write byte to memory			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) #	isp_dacc() - handle data access error exception			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) #	none								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) #	If exiting through isp_dacc...					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) #		a0 = failing address					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) #		d0 = FSLW						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) #	else								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) #		none							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) #	Decode the movep instruction words stored at EXC_OPWORD and	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) # either read or write the required bytes from/to memory. Use the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) # _dmem_{read,write}_byte() routines. If one of the memory routines	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) # returns a failing value, we must pass the failing address and	a FSLW	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) # to the _isp_dacc() routine.						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) #	Since this instruction is used to access peripherals, make sure	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) # to only access the required bytes.					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) ###########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) # movep.(w,l)	Dx,(d,Ay) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) # movep.(w,l)	(d,Ay),Dx #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) ###########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 	global		_moveperipheral
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) _moveperipheral:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 	mov.w		EXC_OPWORD(%a6),%d1	# fetch the opcode word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 	mov.b		%d1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 	and.w		&0x7,%d0		# extract Ay from opcode word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 	mov.l		(EXC_AREGS,%a6,%d0.w*4),%a0 # fetch ay
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 	add.w		EXC_EXTWORD(%a6),%a0	# add: an + sgn_ext(disp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 	btst		&0x7,%d1		# (reg 2 mem) or (mem 2 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 	beq.w		mem2reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) # reg2mem: fetch dx, then write it to memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) reg2mem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 	mov.w		%d1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 	rol.w		&0x7,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 	and.w		&0x7,%d0		# extract Dx from opcode word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 	mov.l		(EXC_DREGS,%a6,%d0.w*4), %d0 # fetch dx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 	btst		&0x6,%d1		# word or long operation?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 	beq.b		r2mwtrans
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) # a0 = dst addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) # d0 = Dx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) r2mltrans:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 	mov.l		%d0,%d2			# store data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 	mov.l		%a0,%a2			# store addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 	rol.l		&0x8,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 	mov.l		%d2,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 	bsr.l		_dmem_write_byte	# os  : write hi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 	tst.l		%d1			# dfetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 	bne.w		movp_write_err		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 	add.w		&0x2,%a2		# incr addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 	mov.l		%a2,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 	rol.l		&0x8,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 	mov.l		%d2,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 	bsr.l		_dmem_write_byte	# os  : write lo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 	tst.l		%d1			# dfetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 	bne.w		movp_write_err		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 	add.w		&0x2,%a2		# incr addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 	mov.l		%a2,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 	rol.l		&0x8,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 	mov.l		%d2,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 	bsr.l		_dmem_write_byte	# os  : write lo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 	tst.l		%d1			# dfetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 	bne.w		movp_write_err		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 	add.w		&0x2,%a2		# incr addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 	mov.l		%a2,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 	rol.l		&0x8,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 	mov.l		%d2,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 	bsr.l		_dmem_write_byte	# os  : write lo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 	tst.l		%d1			# dfetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 	bne.w		movp_write_err		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) # a0 = dst addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) # d0 = Dx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) r2mwtrans:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 	mov.l		%d0,%d2			# store data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 	mov.l		%a0,%a2			# store addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 	lsr.w		&0x8,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 	bsr.l		_dmem_write_byte	# os  : write hi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 	tst.l		%d1			# dfetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 	bne.w		movp_write_err		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 	add.w		&0x2,%a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 	mov.l		%a2,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 	mov.l		%d2,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 	bsr.l		_dmem_write_byte	# os  : write lo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 	tst.l		%d1			# dfetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 	bne.w		movp_write_err		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) # mem2reg: read bytes from memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) # determines the dest register, and then writes the bytes into it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) mem2reg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 	btst		&0x6,%d1		# word or long operation?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 	beq.b		m2rwtrans
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) # a0 = dst addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) m2rltrans:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 	mov.l		%a0,%a2			# store addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 	bsr.l		_dmem_read_byte		# read first byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 	tst.l		%d1			# dfetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 	bne.w		movp_read_err		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 	mov.l		%d0,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 	add.w		&0x2,%a2		# incr addr by 2 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 	mov.l		%a2,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 	bsr.l		_dmem_read_byte		# read second byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 	tst.l		%d1			# dfetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 	bne.w		movp_read_err		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 	lsl.w		&0x8,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 	mov.b		%d0,%d2			# append bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 	add.w		&0x2,%a2		# incr addr by 2 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 	mov.l		%a2,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 	bsr.l		_dmem_read_byte		# read second byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 	tst.l		%d1			# dfetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 	bne.w		movp_read_err		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 	lsl.l		&0x8,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 	mov.b		%d0,%d2			# append bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 	add.w		&0x2,%a2		# incr addr by 2 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) 	mov.l		%a2,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 	bsr.l		_dmem_read_byte		# read second byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 	tst.l		%d1			# dfetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) 	bne.w		movp_read_err		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 	lsl.l		&0x8,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 	mov.b		%d0,%d2			# append bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 	mov.b		EXC_OPWORD(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 	lsr.b		&0x1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 	and.w		&0x7,%d1		# extract Dx from opcode word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 	mov.l		%d2,(EXC_DREGS,%a6,%d1.w*4) # store dx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) # a0 = dst addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) m2rwtrans:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 	mov.l		%a0,%a2			# store addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 	bsr.l		_dmem_read_byte		# read first byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 	tst.l		%d1			# dfetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 	bne.w		movp_read_err		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 	mov.l		%d0,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 	add.w		&0x2,%a2		# incr addr by 2 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 	mov.l		%a2,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 	bsr.l		_dmem_read_byte		# read second byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 	tst.l		%d1			# dfetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 	bne.w		movp_read_err		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 	lsl.w		&0x8,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) 	mov.b		%d0,%d2			# append bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 	mov.b		EXC_OPWORD(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 	lsr.b		&0x1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 	and.w		&0x7,%d1		# extract Dx from opcode word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 	mov.w		%d2,(EXC_DREGS+2,%a6,%d1.w*4) # store dx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) # if dmem_{read,write}_byte() returns a fail message in d1, the package
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) # must create an access error frame. here, we pass a skeleton fslw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) # and the failing address to the routine that creates the new frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) # FSLW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) #	write = true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) #	size = byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) #	TM = data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) #	software emulation error = true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) movp_write_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 	mov.l		%a2,%a0			# pass failing address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 	mov.l		&0x00a10001,%d0		# pass fslw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 	bra.l		isp_dacc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) # FSLW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) #	read = true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) #	size = byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) #	TM = data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) #	software emulation error = true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) movp_read_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 	mov.l		%a2,%a0			# pass failing address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) 	mov.l		&0x01210001,%d0		# pass fslw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 	bra.l		isp_dacc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) #	_chk2_cmp2(): routine to emulate chk2/cmp2 instructions		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) #	_calc_ea(): calculate effective address				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) #	_dmem_read_long(): read operands				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) #	_dmem_read_word(): read operands				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) #	isp_dacc(): handle data access error exception			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) #	none								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) #	If exiting through isp_dacc...					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) #		a0 = failing address					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) #		d0 = FSLW						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) #	else								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) #		none							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) #	First, calculate the effective address, then fetch the byte,	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) # word, or longword sized operands. Then, in the interest of		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) # simplicity, all operands are converted to longword size whether the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) # operation is byte, word, or long. The bounds are sign extended	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) # accordingly. If Rn is a data register, Rn is also sign extended. If	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) # Rn is an address register, it need not be sign extended since the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) # full register is always used.						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) #	The comparisons are made and the condition codes calculated.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) # If the instruction is chk2 and the Rn value is out-of-bounds, set	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) # the ichk_flg in SPCOND_FLG.						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) #	If the memory fetch returns a failing value, pass the failing	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) # address and FSLW to the isp_dacc() routine.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 	global		_chk2_cmp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) _chk2_cmp2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) # passing size parameter doesn't matter since chk2 & cmp2 can't do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) # either predecrement, postincrement, or immediate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 	bsr.l		_calc_ea		# calculate <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 	mov.b		EXC_EXTWORD(%a6), %d0	# fetch hi extension word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 	rol.b		&0x4, %d0		# rotate reg bits into lo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 	and.w		&0xf, %d0		# extract reg bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 	mov.l		(EXC_DREGS,%a6,%d0.w*4), %d2 # get regval
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) 	cmpi.b		EXC_OPWORD(%a6), &0x2	# what size is operation?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 	blt.b		chk2_cmp2_byte		# size == byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) 	beq.b		chk2_cmp2_word		# size == word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) # the bounds are longword size. call routine to read the lower
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) # bound into d0 and the higher bound into d1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) chk2_cmp2_long:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 	mov.l		%a0,%a2			# save copy of <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 	bsr.l		_dmem_read_long		# fetch long lower bound
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 	tst.l		%d1			# dfetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 	bne.w		chk2_cmp2_err_l		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 	mov.l		%d0,%d3			# save long lower bound
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 	addq.l		&0x4,%a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 	mov.l		%a2,%a0			# pass <ea> of long upper bound
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 	bsr.l		_dmem_read_long		# fetch long upper bound
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 	tst.l		%d1			# dfetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 	bne.w		chk2_cmp2_err_l		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 	mov.l		%d0,%d1			# long upper bound in d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 	mov.l		%d3,%d0			# long lower bound in d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 	bra.w		chk2_cmp2_compare	# go do the compare emulation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) # the bounds are word size. fetch them in one subroutine call by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) # reading a longword. sign extend both. if it's a data operation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) # sign extend Rn to long, also.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) chk2_cmp2_word:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 	mov.l		%a0,%a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 	bsr.l		_dmem_read_long		# fetch 2 word bounds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 	tst.l		%d1			# dfetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 	bne.w		chk2_cmp2_err_l		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 	mov.w		%d0, %d1		# place hi in %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 	swap		%d0			# place lo in %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 	ext.l		%d0			# sign extend lo bnd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 	ext.l		%d1			# sign extend hi bnd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 	btst		&0x7, EXC_EXTWORD(%a6)	# address compare?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 	bne.w		chk2_cmp2_compare	# yes; don't sign extend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) # operation is a data register compare.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) # sign extend word to long so we can do simple longword compares.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 	ext.l		%d2			# sign extend data word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 	bra.w		chk2_cmp2_compare	# go emulate compare
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) # the bounds are byte size. fetch them in one subroutine call by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) # reading a word. sign extend both. if it's a data operation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) # sign extend Rn to long, also.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) chk2_cmp2_byte:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 	mov.l		%a0,%a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 	bsr.l		_dmem_read_word		# fetch 2 byte bounds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 	tst.l		%d1			# dfetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 	bne.w		chk2_cmp2_err_w		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 	mov.b		%d0, %d1		# place hi in %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 	lsr.w		&0x8, %d0		# place lo in %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) 	extb.l		%d0			# sign extend lo bnd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 	extb.l		%d1			# sign extend hi bnd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 	btst		&0x7, EXC_EXTWORD(%a6)	# address compare?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) 	bne.b		chk2_cmp2_compare	# yes; don't sign extend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) # operation is a data register compare.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) # sign extend byte to long so we can do simple longword compares.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 	extb.l		%d2			# sign extend data byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) # To set the ccodes correctly:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) #	(1) save 'Z' bit from (Rn - lo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) #	(2) save 'Z' and 'N' bits from ((hi - lo) - (Rn - hi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) #	(3) keep 'X', 'N', and 'V' from before instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) #	(4) combine ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) chk2_cmp2_compare:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 	sub.l		%d0, %d2		# (Rn - lo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) 	mov.w		%cc, %d3		# fetch resulting ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) 	andi.b		&0x4, %d3		# keep 'Z' bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) 	sub.l		%d0, %d1		# (hi - lo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 	cmp.l		%d1,%d2			# ((hi - lo) - (Rn - hi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) 	mov.w		%cc, %d4		# fetch resulting ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 	or.b		%d4, %d3		# combine w/ earlier ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 	andi.b		&0x5, %d3		# keep 'Z' and 'N'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 	mov.w		EXC_CC(%a6), %d4	# fetch old ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 	andi.b		&0x1a, %d4		# keep 'X','N','V' bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 	or.b		%d3, %d4		# insert new ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 	mov.w		%d4, EXC_CC(%a6)	# save new ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 	btst		&0x3, EXC_EXTWORD(%a6)	# separate chk2,cmp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) 	bne.b		chk2_finish		# it's a chk2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) # this code handles the only difference between chk2 and cmp2. chk2 would
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) # have trapped out if the value was out of bounds. we check this by seeing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) # if the 'N' bit was set by the operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) chk2_finish:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 	btst		&0x0, %d4		# is 'N' bit set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 	bne.b		chk2_trap		# yes;chk2 should trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) chk2_trap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 	mov.b		&ichk_flg,SPCOND_FLG(%a6) # set "special case" flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) # if dmem_read_{long,word}() returns a fail message in d1, the package
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) # must create an access error frame. here, we pass a skeleton fslw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) # and the failing address to the routine that creates the new frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) # FSLW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) #	read = true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) #	size = longword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) #	TM = data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) #	software emulation error = true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) chk2_cmp2_err_l:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 	mov.l		%a2,%a0			# pass failing address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) 	mov.l		&0x01010001,%d0		# pass fslw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 	bra.l		isp_dacc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) # FSLW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) #	read = true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) #	size = word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) #	TM = data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) #	software emulation error = true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) chk2_cmp2_err_w:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 	mov.l		%a2,%a0			# pass failing address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 	mov.l		&0x01410001,%d0		# pass fslw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 	bra.l		isp_dacc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) #	_div64(): routine to emulate div{u,s}.l <ea>,Dr:Dq		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) #							64/32->32r:32q	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) #	_calc_ea() - calculate effective address			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) #	isp_iacc() - handle instruction access error exception		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) #	isp_dacc() - handle data access error exception			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) #	isp_restore() - restore An on access error w/ -() or ()+	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) #	none								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) #	If exiting through isp_dacc...					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) #		a0 = failing address					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) #		d0 = FSLW						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) #	else								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) #		none							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) #	First, decode the operand location. If it's in Dn, fetch from	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) # the stack. If it's in memory, use _calc_ea() to calculate the		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) # effective address. Use _dmem_read_long() to fetch at that address.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) # Unless the operand is immediate data. Then use _imem_read_long().	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) # Send failures to isp_dacc() or isp_iacc() as appropriate.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) #	If the operands are signed, make them unsigned and save	the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) # sign info for later. Separate out special cases like divide-by-zero	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) # or 32-bit divides if possible. Else, use a special math algorithm	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) # to calculate the result.						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) #	Restore sign info if signed instruction. Set the condition	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) # codes. Set idbyz_flg in SPCOND_FLG if divisor was zero. Store the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) # quotient and remainder in the appropriate data registers on the stack.#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) set	NDIVISOR,	EXC_TEMP+0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) set	NDIVIDEND,	EXC_TEMP+0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) set	NDRSAVE,	EXC_TEMP+0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) set	NDQSAVE,	EXC_TEMP+0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) set	DDSECOND,	EXC_TEMP+0x6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) set	DDQUOTIENT,	EXC_TEMP+0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) set	DDNORMAL,	EXC_TEMP+0xc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) 	global		_div64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) #############
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) # div(u,s)l #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) #############
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) _div64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) 	mov.b		EXC_OPWORD+1(%a6), %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 	andi.b		&0x38, %d0		# extract src mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) 	bne.w		dcontrolmodel_s		# %dn dest or control mode?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) 	mov.b		EXC_OPWORD+1(%a6), %d0	# extract Dn from opcode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 	andi.w		&0x7, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) 	mov.l		(EXC_DREGS,%a6,%d0.w*4), %d7 # fetch divisor from register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) dgotsrcl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 	beq.w		div64eq0		# divisor is = 0!!!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 	mov.b		EXC_EXTWORD+1(%a6), %d0	# extract Dr from extword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 	mov.b		EXC_EXTWORD(%a6), %d1	# extract Dq from extword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 	and.w		&0x7, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 	lsr.b		&0x4, %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) 	and.w		&0x7, %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 	mov.w		%d0, NDRSAVE(%a6)	# save Dr for later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 	mov.w		%d1, NDQSAVE(%a6)	# save Dq for later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) # fetch %dr and %dq directly off stack since all regs are saved there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) 	mov.l		(EXC_DREGS,%a6,%d0.w*4), %d5 # get dividend hi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 	mov.l		(EXC_DREGS,%a6,%d1.w*4), %d6 # get dividend lo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) # separate signed and unsigned divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) 	btst		&0x3, EXC_EXTWORD(%a6)	# signed or unsigned?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) 	beq.b		dspecialcases		# use positive divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) # save the sign of the divisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) # make divisor unsigned if it's negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) 	tst.l		%d7			# chk sign of divisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) 	slt		NDIVISOR(%a6)		# save sign of divisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) 	bpl.b		dsgndividend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) 	neg.l		%d7			# complement negative divisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) # save the sign of the dividend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) # make dividend unsigned if it's negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) dsgndividend:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) 	tst.l		%d5			# chk sign of hi(dividend)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) 	slt		NDIVIDEND(%a6)		# save sign of dividend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) 	bpl.b		dspecialcases
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) 	mov.w		&0x0, %cc		# clear 'X' cc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) 	negx.l		%d6			# complement signed dividend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) 	negx.l		%d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) # extract some special cases:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) #	- is (dividend == 0) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) #	- is (hi(dividend) == 0 && (divisor <= lo(dividend))) ? (32-bit div)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) dspecialcases:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) 	tst.l		%d5			# is (hi(dividend) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 	bne.b		dnormaldivide		# no, so try it the long way
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) 	tst.l		%d6			# is (lo(dividend) == 0), too
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) 	beq.w		ddone			# yes, so (dividend == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) 	cmp.l		%d7,%d6			# is (divisor <= lo(dividend))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) 	bls.b		d32bitdivide		# yes, so use 32 bit divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) 	exg		%d5,%d6			# q = 0, r = dividend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) 	bra.w		divfinish		# can't divide, we're done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) d32bitdivide:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) 	tdivu.l		%d7, %d5:%d6		# it's only a 32/32 bit div!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) 	bra.b		divfinish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) dnormaldivide:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) # last special case:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) #	- is hi(dividend) >= divisor ? if yes, then overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) 	cmp.l		%d7,%d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) 	bls.b		ddovf			# answer won't fit in 32 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) # perform the divide algorithm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) 	bsr.l		dclassical		# do int divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) # separate into signed and unsigned finishes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) divfinish:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) 	btst		&0x3, EXC_EXTWORD(%a6)	# do divs, divu separately
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) 	beq.b		ddone			# divu has no processing!!!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) # it was a divs.l, so ccode setting is a little more complicated...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) 	tst.b		NDIVIDEND(%a6)		# remainder has same sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) 	beq.b		dcc			# as dividend.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) 	neg.l		%d5			# sgn(rem) = sgn(dividend)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) dcc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) 	mov.b		NDIVISOR(%a6), %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) 	eor.b		%d0, NDIVIDEND(%a6)	# chk if quotient is negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) 	beq.b		dqpos			# branch to quot positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) # 0x80000000 is the largest number representable as a 32-bit negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) # number. the negative of 0x80000000 is 0x80000000.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) 	cmpi.l		%d6, &0x80000000	# will (-quot) fit in 32 bits?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) 	bhi.b		ddovf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) 	neg.l		%d6			# make (-quot) 2's comp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) 	bra.b		ddone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) dqpos:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) 	btst		&0x1f, %d6		# will (+quot) fit in 32 bits?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) 	bne.b		ddovf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) ddone:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) # at this point, result is normal so ccodes are set based on result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) 	mov.w		EXC_CC(%a6), %cc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 	tst.l		%d6			# set %ccode bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) 	mov.w		%cc, EXC_CC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) 	mov.w		NDRSAVE(%a6), %d0	# get Dr off stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 	mov.w		NDQSAVE(%a6), %d1	# get Dq off stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) # if the register numbers are the same, only the quotient gets saved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) # so, if we always save the quotient second, we save ourselves a cmp&beq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) 	mov.l		%d5, (EXC_DREGS,%a6,%d0.w*4) # save remainder
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) 	mov.l		%d6, (EXC_DREGS,%a6,%d1.w*4) # save quotient
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) ddovf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) 	bset		&0x1, EXC_CC+1(%a6)	# 'V' set on overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) 	bclr		&0x0, EXC_CC+1(%a6)	# 'C' cleared on overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) div64eq0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) 	andi.b		&0x1e, EXC_CC+1(%a6)	# clear 'C' bit on divbyzero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 	ori.b		&idbyz_flg,SPCOND_FLG(%a6) # set "special case" flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) ###########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) # This routine uses the 'classical' Algorithm D from Donald Knuth's	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) # Art of Computer Programming, vol II, Seminumerical Algorithms.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) # For this implementation b=2**16, and the target is U1U2U3U4/V1V2,	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) # where U,V are words of the quadword dividend and longword divisor,	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) # and U1, V1 are the most significant words.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) # The most sig. longword of the 64 bit dividend must be in %d5, least	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) # in %d6. The divisor must be in the variable ddivisor, and the		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) # signed/unsigned flag ddusign must be set (0=unsigned,1=signed).	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) # The quotient is returned in %d6, remainder in %d5, unless the		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) # v (overflow) bit is set in the saved %ccr. If overflow, the dividend	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) # is unchanged.								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) dclassical:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) # if the divisor msw is 0, use simpler algorithm then the full blown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) # one at ddknuth:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 	cmpi.l		%d7, &0xffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 	bhi.b		ddknuth			# go use D. Knuth algorithm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) # Since the divisor is only a word (and larger than the mslw of the dividend),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) # a simpler algorithm may be used :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) # In the general case, four quotient words would be created by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) # dividing the divisor word into each dividend word. In this case,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) # the first two quotient words must be zero, or overflow would occur.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) # Since we already checked this case above, we can treat the most significant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) # longword of the dividend as (0) remainder (see Knuth) and merely complete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) # the last two divisions to get a quotient longword and word remainder:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) 	clr.l		%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) 	swap		%d5			# same as r*b if previous step rqd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) 	swap		%d6			# get u3 to lsw position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 	mov.w		%d6, %d5		# rb + u3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) 	divu.w		%d7, %d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) 	mov.w		%d5, %d1		# first quotient word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) 	swap		%d6			# get u4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) 	mov.w		%d6, %d5		# rb + u4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) 	divu.w		%d7, %d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) 	swap		%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) 	mov.w		%d5, %d1		# 2nd quotient 'digit'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) 	clr.w		%d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) 	swap		%d5			# now remainder
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) 	mov.l		%d1, %d6		# and quotient
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) ddknuth:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) # In this algorithm, the divisor is treated as a 2 digit (word) number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) # which is divided into a 3 digit (word) dividend to get one quotient
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) # digit (word). After subtraction, the dividend is shifted and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) # process repeated. Before beginning, the divisor and quotient are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) # 'normalized' so that the process of estimating the quotient digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) # will yield verifiably correct results..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) 	clr.l		DDNORMAL(%a6)		# count of shifts for normalization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) 	clr.b		DDSECOND(%a6)		# clear flag for quotient digits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) 	clr.l		%d1			# %d1 will hold trial quotient
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) ddnchk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) 	btst		&31, %d7		# must we normalize? first word of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) 	bne.b		ddnormalized		# divisor (V1) must be >= 65536/2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) 	addq.l		&0x1, DDNORMAL(%a6)	# count normalization shifts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) 	lsl.l		&0x1, %d7		# shift the divisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) 	lsl.l		&0x1, %d6		# shift u4,u3 with overflow to u2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 	roxl.l		&0x1, %d5		# shift u1,u2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) 	bra.w		ddnchk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) ddnormalized:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) # Now calculate an estimate of the quotient words (msw first, then lsw).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) # The comments use subscripts for the first quotient digit determination.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 	mov.l		%d7, %d3		# divisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) 	mov.l		%d5, %d2		# dividend mslw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) 	swap		%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) 	swap		%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) 	cmp.w		%d2, %d3		# V1 = U1 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) 	bne.b		ddqcalc1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) 	mov.w		&0xffff, %d1		# use max trial quotient word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) 	bra.b		ddadj0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) ddqcalc1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 	mov.l		%d5, %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 	divu.w		%d3, %d1		# use quotient of mslw/msw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) 	andi.l		&0x0000ffff, %d1	# zero any remainder
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) ddadj0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) # now test the trial quotient and adjust. This step plus the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) # normalization assures (according to Knuth) that the trial
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) # quotient will be at worst 1 too large.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) 	mov.l		%d6, -(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) 	clr.w		%d6			# word u3 left
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) 	swap		%d6			# in lsw position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) ddadj1: mov.l		%d7, %d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 	mov.l		%d1, %d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 	mulu.w		%d7, %d2		# V2q
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 	swap		%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 	mulu.w		%d1, %d3		# V1q
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) 	mov.l		%d5, %d4		# U1U2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 	sub.l		%d3, %d4		# U1U2 - V1q
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) 	swap		%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) 	mov.w		%d4,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) 	mov.w		%d6,%d4			# insert lower word (U3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) 	tst.w		%d0			# is upper word set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) 	bne.w		ddadjd1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) #	add.l		%d6, %d4		# (U1U2 - V1q) + U3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) 	cmp.l		%d2, %d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) 	bls.b		ddadjd1			# is V2q > (U1U2-V1q) + U3 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) 	subq.l		&0x1, %d1		# yes, decrement and recheck
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) 	bra.b		ddadj1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) ddadjd1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) # now test the word by multiplying it by the divisor (V1V2) and comparing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) # the 3 digit (word) result with the current dividend words
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 	mov.l		%d5, -(%sp)		# save %d5 (%d6 already saved)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) 	mov.l		%d1, %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) 	swap		%d6			# shift answer to ms 3 words
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 	mov.l		%d7, %d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) 	bsr.l		dmm2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) 	mov.l		%d5, %d2		# now %d2,%d3 are trial*divisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) 	mov.l		%d6, %d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) 	mov.l		(%sp)+, %d5		# restore dividend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) 	mov.l		(%sp)+, %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) 	sub.l		%d3, %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) 	subx.l		%d2, %d5		# subtract double precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) 	bcc		dd2nd			# no carry, do next quotient digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) 	subq.l		&0x1, %d1		# q is one too large
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) # need to add back divisor longword to current ms 3 digits of dividend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) # - according to Knuth, this is done only 2 out of 65536 times for random
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) # divisor, dividend selection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) 	clr.l		%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) 	mov.l		%d7, %d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) 	swap		%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 	clr.w		%d3			# %d3 now ls word of divisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) 	add.l		%d3, %d6		# aligned with 3rd word of dividend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) 	addx.l		%d2, %d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) 	mov.l		%d7, %d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) 	clr.w		%d3			# %d3 now ms word of divisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 	swap		%d3			# aligned with 2nd word of dividend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) 	add.l		%d3, %d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) dd2nd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) 	tst.b		DDSECOND(%a6)		# both q words done?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) 	bne.b		ddremain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) # first quotient digit now correct. store digit and shift the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) # (subtracted) dividend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) 	mov.w		%d1, DDQUOTIENT(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) 	clr.l		%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) 	swap		%d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) 	swap		%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) 	mov.w		%d6, %d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) 	clr.w		%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 	st		DDSECOND(%a6)		# second digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) 	bra.w		ddnormalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) ddremain:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) # add 2nd word to quotient, get the remainder.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 	mov.w		%d1, DDQUOTIENT+2(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) # shift down one word/digit to renormalize remainder.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 	mov.w		%d5, %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 	swap		%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) 	swap		%d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) 	mov.l		DDNORMAL(%a6), %d7	# get norm shift count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) 	beq.b		ddrn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) 	subq.l		&0x1, %d7		# set for loop count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) ddnlp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) 	lsr.l		&0x1, %d5		# shift into %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) 	roxr.l		&0x1, %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 	dbf		%d7, ddnlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) ddrn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) 	mov.l		%d6, %d5		# remainder
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) 	mov.l		DDQUOTIENT(%a6), %d6	# quotient
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) dmm2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) # factors for the 32X32->64 multiplication are in %d5 and %d6.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) # returns 64 bit result in %d5 (hi) %d6(lo).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) # destroys %d2,%d3,%d4.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) # multiply hi,lo words of each factor to get 4 intermediate products
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) 	mov.l		%d6, %d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) 	mov.l		%d6, %d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) 	mov.l		%d5, %d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) 	swap		%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) 	swap		%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) 	mulu.w		%d5, %d6		# %d6 <- lsw*lsw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 	mulu.w		%d3, %d5		# %d5 <- msw-dest*lsw-source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) 	mulu.w		%d4, %d2		# %d2 <- msw-source*lsw-dest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) 	mulu.w		%d4, %d3		# %d3 <- msw*msw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) # now use swap and addx to consolidate to two longwords
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) 	clr.l		%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) 	swap		%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) 	add.w		%d5, %d6		# add msw of l*l to lsw of m*l product
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) 	addx.w		%d4, %d3		# add any carry to m*m product
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) 	add.w		%d2, %d6		# add in lsw of other m*l product
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 	addx.w		%d4, %d3		# add any carry to m*m product
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) 	swap		%d6			# %d6 is low 32 bits of final product
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 	clr.w		%d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) 	clr.w		%d2			# lsw of two mixed products used,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 	swap		%d5			# now use msws of longwords
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 	swap		%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) 	add.l		%d2, %d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 	add.l		%d3, %d5		# %d5 now ms 32 bits of final product
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) ##########
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) dcontrolmodel_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 	movq.l		&LONG,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) 	bsr.l		_calc_ea		# calc <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) 	cmpi.b		SPCOND_FLG(%a6),&immed_flg # immediate addressing mode?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) 	beq.b		dimmed			# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) 	mov.l		%a0,%a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) 	bsr.l		_dmem_read_long		# fetch divisor from <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) 	tst.l		%d1			# dfetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) 	bne.b		div64_err		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) 	mov.l		%d0, %d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) 	bra.w		dgotsrcl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) # we have to split out immediate data here because it must be read using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) # imem_read() instead of dmem_read(). this becomes especially important
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) # if the fetch runs into some deadly fault.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) dimmed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) 	addq.l		&0x4,EXC_EXTWPTR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) 	bsr.l		_imem_read_long		# read immediate value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) 	tst.l		%d1			# ifetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) 	bne.l		isp_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) 	mov.l		%d0,%d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) 	bra.w		dgotsrcl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) ##########
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) # if dmem_read_long() returns a fail message in d1, the package
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) # must create an access error frame. here, we pass a skeleton fslw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) # and the failing address to the routine that creates the new frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) # also, we call isp_restore in case the effective addressing mode was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) # (an)+ or -(an) in which case the previous "an" value must be restored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) # FSLW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) #	read = true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) #	size = longword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) #	TM = data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) #	software emulation error = true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) div64_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) 	bsr.l		isp_restore		# restore addr reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) 	mov.l		%a2,%a0			# pass failing address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) 	mov.l		&0x01010001,%d0		# pass fslw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) 	bra.l		isp_dacc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) #	_mul64(): routine to emulate mul{u,s}.l <ea>,Dh:Dl 32x32->64	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) #	_calc_ea() - calculate effective address			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) #	isp_iacc() - handle instruction access error exception		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) #	isp_dacc() - handle data access error exception			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) #	isp_restore() - restore An on access error w/ -() or ()+	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) #	none								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) #	If exiting through isp_dacc...					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) #		a0 = failing address					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) #		d0 = FSLW						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) #	else								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) #		none							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) #	First, decode the operand location. If it's in Dn, fetch from	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) # the stack. If it's in memory, use _calc_ea() to calculate the		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) # effective address. Use _dmem_read_long() to fetch at that address.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) # Unless the operand is immediate data. Then use _imem_read_long().	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) # Send failures to isp_dacc() or isp_iacc() as appropriate.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) #	If the operands are signed, make them unsigned and save the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) # sign info for later. Perform the multiplication using 16x16->32	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) # unsigned multiplies and "add" instructions. Store the high and low	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) # portions of the result in the appropriate data registers on the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) # stack. Calculate the condition codes, also.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) #############
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) # mul(u,s)l #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) #############
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) 	global		_mul64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) _mul64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) 	mov.b		EXC_OPWORD+1(%a6), %d0	# extract src {mode,reg}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) 	cmpi.b		%d0, &0x7		# is src mode Dn or other?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) 	bgt.w		mul64_memop		# src is in memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) # multiplier operand in the data register file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) # must extract the register number and fetch the operand from the stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) mul64_regop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) 	andi.w		&0x7, %d0		# extract Dn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) 	mov.l		(EXC_DREGS,%a6,%d0.w*4), %d3 # fetch multiplier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) # multiplier is in %d3. now, extract Dl and Dh fields and fetch the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) # multiplicand from the data register specified by Dl.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) mul64_multiplicand:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 	mov.w		EXC_EXTWORD(%a6), %d2	# fetch ext word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) 	clr.w		%d1			# clear Dh reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) 	mov.b		%d2, %d1		# grab Dh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 	rol.w		&0x4, %d2		# align Dl byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) 	andi.w		&0x7, %d2		# extract Dl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) 	mov.l		(EXC_DREGS,%a6,%d2.w*4), %d4 # get multiplicand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) # check for the case of "zero" result early
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) 	tst.l		%d4			# test multiplicand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) 	beq.w		mul64_zero		# handle zero separately
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) 	tst.l		%d3			# test multiplier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) 	beq.w		mul64_zero		# handle zero separately
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) # multiplier is in %d3 and multiplicand is in %d4.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) # if the operation is to be signed, then the operands are converted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) # to unsigned and the result sign is saved for the end.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) 	clr.b		EXC_TEMP(%a6)		# clear temp space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) 	btst		&0x3, EXC_EXTWORD(%a6)	# signed or unsigned?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) 	beq.b		mul64_alg		# unsigned; skip sgn calc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) 	tst.l		%d3			# is multiplier negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) 	bge.b		mul64_chk_md_sgn	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) 	neg.l		%d3			# make multiplier positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) 	ori.b		&0x1, EXC_TEMP(%a6)	# save multiplier sgn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) # the result sign is the exclusive or of the operand sign bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) mul64_chk_md_sgn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 	tst.l		%d4			# is multiplicand negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) 	bge.b		mul64_alg		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) 	neg.l		%d4			# make multiplicand positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) 	eori.b		&0x1, EXC_TEMP(%a6)	# calculate correct sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) #	63			   32				0	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) #	----------------------------					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) #	| hi(mplier) * hi(mplicand)|					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) #	----------------------------					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) #		     -----------------------------			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) #		     | hi(mplier) * lo(mplicand) |			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) #		     -----------------------------			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) #		     -----------------------------			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) #		     | lo(mplier) * hi(mplicand) |			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) #		     -----------------------------			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) #	  |			   -----------------------------	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) #	--|--			   | lo(mplier) * lo(mplicand) |	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) #	  |			   -----------------------------	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) #	========================================================	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) #	--------------------------------------------------------	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) #	|	hi(result)	   |	    lo(result)         |	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) #	--------------------------------------------------------	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) mul64_alg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) # load temp registers with operands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) 	mov.l		%d3, %d5		# mr in %d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) 	mov.l		%d3, %d6		# mr in %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) 	mov.l		%d4, %d7		# md in %d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) 	swap		%d6			# hi(mr) in lo %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) 	swap		%d7			# hi(md) in lo %d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) # complete necessary multiplies:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) 	mulu.w		%d4, %d3		# [1] lo(mr) * lo(md)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) 	mulu.w		%d6, %d4		# [2] hi(mr) * lo(md)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) 	mulu.w		%d7, %d5		# [3] lo(mr) * hi(md)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) 	mulu.w		%d7, %d6		# [4] hi(mr) * hi(md)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) # add lo portions of [2],[3] to hi portion of [1].
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) # add carries produced from these adds to [4].
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) # lo([1]) is the final lo 16 bits of the result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) 	clr.l		%d7			# load %d7 w/ zero value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) 	swap		%d3			# hi([1]) <==> lo([1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) 	add.w		%d4, %d3		# hi([1]) + lo([2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) 	addx.l		%d7, %d6		#    [4]  + carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) 	add.w		%d5, %d3		# hi([1]) + lo([3])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) 	addx.l		%d7, %d6		#    [4]  + carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) 	swap		%d3			# lo([1]) <==> hi([1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) # lo portions of [2],[3] have been added in to final result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) # now, clear lo, put hi in lo reg, and add to [4]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) 	clr.w		%d4			# clear lo([2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) 	clr.w		%d5			# clear hi([3])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) 	swap		%d4			# hi([2]) in lo %d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) 	swap		%d5			# hi([3]) in lo %d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) 	add.l		%d5, %d4		#    [4]  + hi([2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) 	add.l		%d6, %d4		#    [4]  + hi([3])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) # unsigned result is now in {%d4,%d3}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) 	tst.b		EXC_TEMP(%a6)		# should result be signed?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) 	beq.b		mul64_done		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) # result should be a signed negative number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) # compute 2's complement of the unsigned number:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) #   -negate all bits and add 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) mul64_neg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) 	not.l		%d3			# negate lo(result) bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) 	not.l		%d4			# negate hi(result) bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) 	addq.l		&1, %d3			# add 1 to lo(result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) 	addx.l		%d7, %d4		# add carry to hi(result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) # the result is saved to the register file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) # for '040 compatibility, if Dl == Dh then only the hi(result) is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) # saved. so, saving hi after lo accomplishes this without need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) # check Dl,Dh equality.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) mul64_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) 	mov.l		%d3, (EXC_DREGS,%a6,%d2.w*4) # save lo(result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) 	mov.w		&0x0, %cc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) 	mov.l		%d4, (EXC_DREGS,%a6,%d1.w*4) # save hi(result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) # now, grab the condition codes. only one that can be set is 'N'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) # 'N' CAN be set if the operation is unsigned if bit 63 is set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) 	mov.w		%cc, %d7		# fetch %ccr to see if 'N' set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) 	andi.b		&0x8, %d7		# extract 'N' bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) mul64_ccode_set:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) 	mov.b		EXC_CC+1(%a6), %d6	# fetch previous %ccr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) 	andi.b		&0x10, %d6		# all but 'X' bit changes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) 	or.b		%d7, %d6		# group 'X' and 'N'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) 	mov.b		%d6, EXC_CC+1(%a6)	# save new %ccr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) # one or both of the operands is zero so the result is also zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) # save the zero result to the register file and set the 'Z' ccode bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) mul64_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) 	clr.l		(EXC_DREGS,%a6,%d2.w*4) # save lo(result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) 	clr.l		(EXC_DREGS,%a6,%d1.w*4) # save hi(result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) 	movq.l		&0x4, %d7		# set 'Z' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) 	bra.b		mul64_ccode_set		# finish ccode set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) ##########
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) # multiplier operand is in memory at the effective address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) # must calculate the <ea> and go fetch the 32-bit operand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) mul64_memop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) 	movq.l		&LONG, %d0		# pass # of bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) 	bsr.l		_calc_ea		# calculate <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) 	cmpi.b		SPCOND_FLG(%a6),&immed_flg # immediate addressing mode?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) 	beq.b		mul64_immed		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) 	mov.l		%a0,%a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) 	bsr.l		_dmem_read_long		# fetch src from addr (%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) 	tst.l		%d1			# dfetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) 	bne.w		mul64_err		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) 	mov.l		%d0, %d3		# store multiplier in %d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) 	bra.w		mul64_multiplicand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) # we have to split out immediate data here because it must be read using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) # imem_read() instead of dmem_read(). this becomes especially important
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) # if the fetch runs into some deadly fault.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) mul64_immed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) 	addq.l		&0x4,EXC_EXTWPTR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) 	bsr.l		_imem_read_long		# read immediate value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) 	tst.l		%d1			# ifetch error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) 	bne.l		isp_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) 	mov.l		%d0,%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) 	bra.w		mul64_multiplicand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) ##########
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) # if dmem_read_long() returns a fail message in d1, the package
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) # must create an access error frame. here, we pass a skeleton fslw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) # and the failing address to the routine that creates the new frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) # also, we call isp_restore in case the effective addressing mode was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) # (an)+ or -(an) in which case the previous "an" value must be restored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) # FSLW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) #	read = true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) #	size = longword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) #	TM = data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) #	software emulation error = true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) mul64_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) 	bsr.l		isp_restore		# restore addr reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) 	mov.l		%a2,%a0			# pass failing address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) 	mov.l		&0x01010001,%d0		# pass fslw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) 	bra.l		isp_dacc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) #	_compandset2(): routine to emulate cas2()			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) #			(internal to package)				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) #	_isp_cas2_finish(): store ccodes, store compare regs		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) #			    (external to package)			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) #	_real_lock_page() - "callout" to lock op's page from page-outs	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) #	_cas_terminate2() - access error exit				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) #	_real_cas2() - "callout" to core cas2 emulation code		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) #	_real_unlock_page() - "callout" to unlock page			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) # _compandset2():							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) #	d0 = instruction extension word					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) # _isp_cas2_finish():							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) #	see cas2 core emulation code					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) # _compandset2():							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) #	see cas2 core emulation code					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) # _isp_cas_finish():							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) #	None (register file or memroy changed as appropriate)		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) # compandset2():							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) #	Decode the instruction and fetch the appropriate Update and	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) # Compare operands. Then call the "callout" _real_lock_page() for each	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) # memory operand address so that the operating system can keep these	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) # pages from being paged out. If either _real_lock_page() fails, exit	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) # through _cas_terminate2(). Don't forget to unlock the 1st locked page	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) # using _real_unlock_paged() if the 2nd lock-page fails.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) # Finally, branch to the core cas2 emulation code by calling the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) # "callout" _real_cas2().						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) # _isp_cas2_finish():							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) #	Re-perform the comparison so we can determine the condition	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) # codes which were too much trouble to keep around during the locked	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) # emulation. Then unlock each operands page by calling the "callout"	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) # _real_unlock_page().							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) set ADDR1,	EXC_TEMP+0xc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) set ADDR2,	EXC_TEMP+0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) set DC2,	EXC_TEMP+0xa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) set DC1,	EXC_TEMP+0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) 	global		_compandset2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) _compandset2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) 	mov.l		%d0,EXC_TEMP+0x4(%a6)		# store for possible restart
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) 	mov.l		%d0,%d1			# extension word in d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) 	rol.w		&0x4,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) 	andi.w		&0xf,%d0		# extract Rn2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) 	mov.l		(EXC_DREGS,%a6,%d0.w*4),%a1 # fetch ADDR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) 	mov.l		%a1,ADDR2(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) 	mov.l		%d1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) 	lsr.w		&0x6,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) 	andi.w		&0x7,%d1		# extract Du2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) 	mov.l		(EXC_DREGS,%a6,%d1.w*4),%d5 # fetch Update2 Op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) 	andi.w		&0x7,%d0		# extract Dc2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) 	mov.l		(EXC_DREGS,%a6,%d0.w*4),%d3 # fetch Compare2 Op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) 	mov.w		%d0,DC2(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) 	mov.w		EXC_EXTWORD(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) 	mov.l		%d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) 	rol.w		&0x4,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) 	andi.w		&0xf,%d0		# extract Rn1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) 	mov.l		(EXC_DREGS,%a6,%d0.w*4),%a0 # fetch ADDR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) 	mov.l		%a0,ADDR1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) 	mov.l		%d1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) 	lsr.w		&0x6,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) 	andi.w		&0x7,%d1		# extract Du1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) 	mov.l		(EXC_DREGS,%a6,%d1.w*4),%d4 # fetch Update1 Op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) 	andi.w		&0x7,%d0		# extract Dc1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) 	mov.l		(EXC_DREGS,%a6,%d0.w*4),%d2 # fetch Compare1 Op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) 	mov.w		%d0,DC1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) 	btst		&0x1,EXC_OPWORD(%a6)	# word or long?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) 	sne		%d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) 	btst		&0x5,EXC_ISR(%a6)	# user or supervisor?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) 	sne		%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) 	mov.l		%a0,%a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) 	mov.l		%a1,%a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) 	mov.l		%d7,%d1			# pass size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) 	mov.l		%d6,%d0			# pass mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) 	bsr.l		_real_lock_page		# lock page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) 	mov.l		%a2,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) 	tst.l		%d0			# error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) 	bne.l		_cas_terminate2		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) 	mov.l		%d7,%d1			# pass size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) 	mov.l		%d6,%d0			# pass mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) 	mov.l		%a3,%a0			# pass addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) 	bsr.l		_real_lock_page		# lock page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) 	mov.l		%a3,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) 	tst.l		%d0			# error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) 	bne.b		cas_preterm		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) 	mov.l		%a2,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) 	mov.l		%a3,%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) 	bra.l		_real_cas2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) # if the 2nd lock attempt fails, then we must still unlock the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) # first page(s).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) cas_preterm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) 	mov.l		%d0,-(%sp)		# save FSLW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) 	mov.l		%d7,%d1			# pass size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) 	mov.l		%d6,%d0			# pass mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) 	mov.l		%a2,%a0			# pass ADDR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) 	bsr.l		_real_unlock_page	# unlock first page(s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) 	mov.l		(%sp)+,%d0		# restore FSLW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) 	mov.l		%a3,%a0			# pass failing addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) 	bra.l		_cas_terminate2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) #############################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) 	global		_isp_cas2_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) _isp_cas2_finish:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) 	btst		&0x1,EXC_OPWORD(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) 	bne.b		cas2_finish_l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) 	mov.w		EXC_CC(%a6),%cc		# load old ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) 	cmp.w		%d0,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) 	bne.b		cas2_finish_w_save
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) 	cmp.w		%d1,%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) cas2_finish_w_save:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) 	mov.w		%cc,EXC_CC(%a6)		# save new ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) 	tst.b		%d4			# update compare reg?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) 	bne.b		cas2_finish_w_done	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) 	mov.w		DC2(%a6),%d3		# fetch Dc2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) 	mov.w		%d1,(2+EXC_DREGS,%a6,%d3.w*4) # store new Compare2 Op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) 	mov.w		DC1(%a6),%d2		# fetch Dc1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) 	mov.w		%d0,(2+EXC_DREGS,%a6,%d2.w*4) # store new Compare1 Op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) cas2_finish_w_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) 	btst		&0x5,EXC_ISR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) 	sne		%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) 	mov.l		%d2,%d0			# pass mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) 	sf		%d1			# pass size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) 	mov.l		ADDR1(%a6),%a0		# pass ADDR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) 	bsr.l		_real_unlock_page	# unlock page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) 	mov.l		%d2,%d0			# pass mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) 	sf		%d1			# pass size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) 	mov.l		ADDR2(%a6),%a0		# pass ADDR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) 	bsr.l		_real_unlock_page	# unlock page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) cas2_finish_l:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) 	mov.w		EXC_CC(%a6),%cc		# load old ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) 	cmp.l		%d0,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) 	bne.b		cas2_finish_l_save
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) 	cmp.l		%d1,%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) cas2_finish_l_save:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) 	mov.w		%cc,EXC_CC(%a6)		# save new ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) 	tst.b		%d4			# update compare reg?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) 	bne.b		cas2_finish_l_done	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) 	mov.w		DC2(%a6),%d3		# fetch Dc2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) 	mov.l		%d1,(EXC_DREGS,%a6,%d3.w*4) # store new Compare2 Op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) 	mov.w		DC1(%a6),%d2		# fetch Dc1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) 	mov.l		%d0,(EXC_DREGS,%a6,%d2.w*4) # store new Compare1 Op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) cas2_finish_l_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) 	btst		&0x5,EXC_ISR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) 	sne		%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) 	mov.l		%d2,%d0			# pass mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) 	st		%d1			# pass size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) 	mov.l		ADDR1(%a6),%a0		# pass ADDR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) 	bsr.l		_real_unlock_page	# unlock page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) 	mov.l		%d2,%d0			# pass mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) 	st		%d1			# pass size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) 	mov.l		ADDR2(%a6),%a0		# pass ADDR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) 	bsr.l		_real_unlock_page	# unlock page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) ########
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) 	global		cr_cas2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) cr_cas2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) 	mov.l		EXC_TEMP+0x4(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) 	bra.w		_compandset2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) #	_compandset(): routine to emulate cas w/ misaligned <ea>	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) #		       (internal to package)				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) #	_isp_cas_finish(): routine called when cas emulation completes	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) #			   (external and internal to package)		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) #	_isp_cas_restart(): restart cas emulation after a fault		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) #			    (external to package)			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) #	_isp_cas_terminate(): create access error stack frame on fault	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) #			      (external and internal to package)	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) #	_isp_cas_inrange(): checks whether instr addess is within range	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) #			    of core cas/cas2emulation code		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) #			    (external to package)			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) #	_calc_ea(): calculate effective address				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) # compandset():								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) #	none								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) # _isp_cas_restart():							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) #	d6 = previous sfc/dfc						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) # _isp_cas_finish():							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) # _isp_cas_terminate():							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) #	a0 = failing address						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) #	d0 = FSLW							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) #	d6 = previous sfc/dfc						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) # _isp_cas_inrange():							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) #	a0 = instruction address to be checked				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) # compandset():								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) #		none							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) # _isp_cas_restart():							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) #	a0 = effective address						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) #	d7 = word or longword flag					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) # _isp_cas_finish():							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) #	a0 = effective address						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) # _isp_cas_terminate():							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) #	initial register set before emulation exception			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) # _isp_cas_inrange():							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) #	d0 = 0 => in range; -1 => out of range				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) # compandset():								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) #	First, calculate the effective address. Then, decode the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) # instruction word and fetch the "compare" (DC) and "update" (Du)	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) # operands.								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) #	Next, call the external routine _real_lock_page() so that the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) # operating system can keep this page from being paged out while we're	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) # in this routine. If this call fails, jump to _cas_terminate2().	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) #	The routine then branches to _real_cas(). This external routine	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) # that actually emulates cas can be supplied by the external os or	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) # made to point directly back into the 060ISP which has a routine for	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) # this purpose.								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) # _isp_cas_finish():							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) #	Either way, after emulation, the package is re-entered at	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) # _isp_cas_finish(). This routine re-compares the operands in order to	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) # set the condition codes. Finally, these routines will call		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) # _real_unlock_page() in order to unlock the pages that were previously	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) # locked.								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) # _isp_cas_restart():							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) #	This routine can be entered from an access error handler where	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) # the emulation sequence should be re-started from the beginning.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) # _isp_cas_terminate():							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) #	This routine can be entered from an access error handler where	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) # an emulation operand access failed and the operating system would	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) # like an access error stack frame created instead of the current	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) # unimplemented integer instruction frame.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) #	Also, the package enters here if a call to _real_lock_page()	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) # fails.								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) # _isp_cas_inrange():							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) #	Checks to see whether the instruction address passed to it in	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) # a0 is within the software package cas/cas2 emulation routines. This	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) # can be helpful for an operating system to determine whether an access	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) # error during emulation was due to a cas/cas2 emulation access.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) set DC,		EXC_TEMP+0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) set ADDR,	EXC_TEMP+0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) 	global		_compandset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) _compandset:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) 	btst		&0x1,EXC_OPWORD(%a6)	# word or long operation?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) 	bne.b		compandsetl		# long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) compandsetw:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) 	movq.l		&0x2,%d0		# size = 2 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) 	bsr.l		_calc_ea		# a0 = calculated <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) 	mov.l		%a0,ADDR(%a6)		# save <ea> for possible restart
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) 	sf		%d7			# clear d7 for word size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) 	bra.b		compandsetfetch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) compandsetl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) 	movq.l		&0x4,%d0		# size = 4 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) 	bsr.l		_calc_ea		# a0 = calculated <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) 	mov.l		%a0,ADDR(%a6)		# save <ea> for possible restart
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) 	st		%d7			# set d7 for longword size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) compandsetfetch:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) 	mov.w		EXC_EXTWORD(%a6),%d0	# fetch cas extension word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) 	mov.l		%d0,%d1			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) 	lsr.w		&0x6,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) 	andi.w		&0x7,%d0		# extract Du
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) 	mov.l		(EXC_DREGS,%a6,%d0.w*4),%d2 # get update operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) 	andi.w		&0x7,%d1		# extract Dc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) 	mov.l		(EXC_DREGS,%a6,%d1.w*4),%d4 # get compare operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) 	mov.w		%d1,DC(%a6)		# save Dc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) 	btst		&0x5,EXC_ISR(%a6)	# which mode for exception?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) 	sne		%d6			# set on supervisor mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) 	mov.l		%a0,%a2			# save temporarily
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) 	mov.l		%d7,%d1			# pass size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) 	mov.l		%d6,%d0			# pass mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) 	bsr.l		_real_lock_page		# lock page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) 	tst.l		%d0			# did error occur?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) 	bne.w		_cas_terminate2		# yes, clean up the mess
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) 	mov.l		%a2,%a0			# pass addr in a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) 	bra.l		_real_cas
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) ########
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) 	global		_isp_cas_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) _isp_cas_finish:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) 	btst		&0x1,EXC_OPWORD(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) 	bne.b		cas_finish_l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) # just do the compare again since it's faster than saving the ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) # from the locked routine...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) cas_finish_w:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) 	mov.w		EXC_CC(%a6),%cc		# restore cc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) 	cmp.w		%d0,%d4			# do word compare
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) 	mov.w		%cc,EXC_CC(%a6)		# save cc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) 	tst.b		%d1			# update compare reg?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) 	bne.b		cas_finish_w_done	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) 	mov.w		DC(%a6),%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) 	mov.w		%d0,(EXC_DREGS+2,%a6,%d3.w*4) # Dc = destination
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) cas_finish_w_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) 	mov.l		ADDR(%a6),%a0		# pass addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) 	sf		%d1			# pass size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) 	btst		&0x5,EXC_ISR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) 	sne		%d0			# pass mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) 	bsr.l		_real_unlock_page	# unlock page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) # just do the compare again since it's faster than saving the ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) # from the locked routine...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) cas_finish_l:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) 	mov.w		EXC_CC(%a6),%cc		# restore cc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) 	cmp.l		%d0,%d4			# do longword compare
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) 	mov.w		%cc,EXC_CC(%a6)		# save cc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) 	tst.b		%d1			# update compare reg?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) 	bne.b		cas_finish_l_done	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) 	mov.w		DC(%a6),%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) 	mov.l		%d0,(EXC_DREGS,%a6,%d3.w*4) # Dc = destination
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) cas_finish_l_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) 	mov.l		ADDR(%a6),%a0		# pass addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) 	st		%d1			# pass size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) 	btst		&0x5,EXC_ISR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) 	sne		%d0			# pass mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) 	bsr.l		_real_unlock_page	# unlock page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) ########
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) 	global		_isp_cas_restart
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) _isp_cas_restart:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) 	mov.l		%d6,%sfc		# restore previous sfc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) 	mov.l		%d6,%dfc		# restore previous dfc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) 	cmpi.b		EXC_OPWORD+1(%a6),&0xfc	# cas or cas2?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) 	beq.l		cr_cas2			# cas2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) cr_cas:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) 	mov.l		ADDR(%a6),%a0		# load <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) 	btst		&0x1,EXC_OPWORD(%a6)	# word or long operation?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) 	sne		%d7			# set d7 accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) 	bra.w		compandsetfetch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) ########
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) # At this stage, it would be nice if d0 held the FSLW.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) 	global		_isp_cas_terminate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) _isp_cas_terminate:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) 	mov.l		%d6,%sfc		# restore previous sfc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) 	mov.l		%d6,%dfc		# restore previous dfc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) 	global		_cas_terminate2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) _cas_terminate2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) 	mov.l		%a0,%a2			# copy failing addr to a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) 	bsr.l		isp_restore		# restore An (if ()+ or -())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) 	mov.l		(%sp)+,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) 	addq.l		&0x4,%sp		# remove sub return addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) 	subq.l		&0x8,%sp		# make room for bigger stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) 	subq.l		&0x8,%a6		# shift frame ptr down, too
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) 	mov.l		&26,%d1			# want to move 51 longwords
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) 	lea		0x8(%sp),%a0		# get address of old stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) 	lea		0x0(%sp),%a1		# get address of new stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) cas_term_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) 	mov.l		(%a0)+,(%a1)+		# move a longword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) 	dbra.w		%d1,cas_term_cont	# keep going
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) 	mov.w		&0x4008,EXC_IVOFF(%a6)	# put new stk fmt, voff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) 	mov.l		%a2,EXC_IVOFF+0x2(%a6)	# put faulting addr on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) 	mov.l		%d0,EXC_IVOFF+0x6(%a6)	# put FSLW on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) 	movm.l		EXC_DREGS(%a6),&0x3fff	# restore user regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) 	unlk		%a6			# unlink stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) 	bra.l		_real_access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) ########
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) 	global		_isp_cas_inrange
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) _isp_cas_inrange:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) 	clr.l		%d0			# clear return result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) 	lea		_CASHI(%pc),%a1		# load end of CAS core code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) 	cmp.l		%a1,%a0			# is PC in range?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) 	blt.b		cin_no			# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) 	lea		_CASLO(%pc),%a1		# load begin of CAS core code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) 	cmp.l		%a0,%a1			# is PC in range?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) 	blt.b		cin_no			# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) 	rts					# yes; return d0 = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) cin_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) 	mov.l		&-0x1,%d0		# out of range; return d0 = -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) # This is the start of the cas and cas2 "core" emulation code.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) # This is the section that may need to be replaced by the host	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) # OS if it is too operating system-specific.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) # Please refer to the package documentation to see how to	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) # "replace" this section, if necessary.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) #       ######      ##      ######     ####
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) #       #	   #  #     #         #    #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) #	#	  ######    ######        #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) #	#	  #    #         #      #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) #       ######    #    #    ######    ######
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) #	_isp_cas2(): "core" emulation code for the cas2 instruction	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) #	_isp_cas2_finish() - only exit point for this emulation code;	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) #			     do clean-up; calculate ccodes; store	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) #			     Compare Ops if appropriate.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) #	*see chart below*						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) #	*see chart below*						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) #	(1) Make several copies of the effective address.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) #	(2) Save current SR; Then mask off all maskable interrupts.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) #	(3) Save current SFC/DFC (ASSUMED TO BE EQUAL!!!); Then set	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) #	    according to whether exception occurred in user or		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) #	    supervisor mode.						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) #	(4) Use "plpaw" instruction to pre-load ATC with effective	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) #	    address pages(s). THIS SHOULD NOT FAULT!!! The relevant	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) #	    page(s) should have already been made resident prior to	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) #	    entering this routine.					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) #	(5) Push the operand lines from the cache w/ "cpushl".		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) #	    In the 68040, this was done within the locked region. In	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) #	    the 68060, it is done outside of the locked region.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) #	(6) Use "plpar" instruction to do a re-load of ATC entries for	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) #	    ADDR1 since ADDR2 entries may have pushed ADDR1 out of the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) #	    ATC.							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) #	(7) Pre-fetch the core emulation instructions by executing	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) #	    one branch within each physical line (16 bytes) of the code	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) #	    before actually executing the code.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) #	(8) Load the BUSCR w/ the bus lock value.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) #	(9) Fetch the source operands using "moves".			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) #	(10)Do the compares. If both equal, go to step (13).		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) #	(11)Unequal. No update occurs. But, we do write the DST1 op	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) #	    back to itself (as w/ the '040) so we can gracefully unlock	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) #	    the bus (and assert LOCKE*) using BUSCR and the final move.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) #	(12)Exit.							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) #	(13)Write update operand to the DST locations. Use BUSCR to	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) #	    assert LOCKE* for the final write operation.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) #	(14)Exit.							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) #	The algorithm is actually implemented slightly differently	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) # depending on the size of the operation and the misalignment of the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) # operands. A misaligned operand must be written in aligned chunks or	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) # else the BUSCR register control gets confused.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) # THIS IS THE STATE OF THE INTEGER REGISTER FILE UPON		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) # ENTERING _isp_cas2().						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) #								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) # D0 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) # D1 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) # D2 = cmp operand 1						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) # D3 = cmp operand 2						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) # D4 = update oper 1						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) # D5 = update oper 2						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) # D6 = 'xxxxxxff if supervisor mode; 'xxxxxx00 if user mode	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) # D7 = 'xxxxxxff if longword operation; 'xxxxxx00 if word	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) # A0 = ADDR1							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) # A1 = ADDR2							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) # A2 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) # A3 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) # A4 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) # A5 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) # A6 = frame pointer						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) # A7 = stack pointer						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) #	align		0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) # beginning label used by _isp_cas_inrange()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) 	global		_CASLO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) _CASLO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) 	global		_isp_cas2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) _isp_cas2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) 	tst.b		%d6			# user or supervisor mode?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) 	bne.b		cas2_supervisor		# supervisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) cas2_user:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) 	movq.l		&0x1,%d0		# load user data fc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) 	bra.b		cas2_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) cas2_supervisor:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) 	movq.l		&0x5,%d0		# load supervisor data fc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) cas2_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) 	tst.b		%d7			# word or longword?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) 	beq.w		cas2w			# word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) ####
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) cas2l:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) 	mov.l		%a0,%a2			# copy ADDR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) 	mov.l		%a1,%a3			# copy ADDR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) 	mov.l		%a0,%a4			# copy ADDR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) 	mov.l		%a1,%a5			# copy ADDR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) 	addq.l		&0x3,%a4		# ADDR1+3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) 	addq.l		&0x3,%a5		# ADDR2+3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) 	mov.l		%a2,%d1			# ADDR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) # mask interrupts levels 0-6. save old mask value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) 	mov.w		%sr,%d7			# save current SR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) 	ori.w		&0x0700,%sr		# inhibit interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) # load the SFC and DFC with the appropriate mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) 	movc		%sfc,%d6		# save old SFC/DFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) 	movc		%d0,%sfc		# store new SFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) 	movc		%d0,%dfc		# store new DFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) # pre-load the operand ATC. no page faults should occur here because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) # _real_lock_page() should have taken care of this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) 	plpaw		(%a2)			# load atc for ADDR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) 	plpaw		(%a4)			# load atc for ADDR1+3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) 	plpaw		(%a3)			# load atc for ADDR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) 	plpaw		(%a5)			# load atc for ADDR2+3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) # push the operand lines from the cache if they exist.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) 	cpushl		%dc,(%a2)		# push line for ADDR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) 	cpushl		%dc,(%a4)		# push line for ADDR1+3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) 	cpushl		%dc,(%a3)		# push line for ADDR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) 	cpushl		%dc,(%a5)		# push line for ADDR2+2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) 	mov.l		%d1,%a2			# ADDR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) 	addq.l		&0x3,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) 	mov.l		%d1,%a4			# ADDR1+3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) # if ADDR1 was ATC resident before the above "plpaw" and was executed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) # and it was the next entry scheduled for replacement and ADDR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) # shares the same set, then the "plpaw" for ADDR2 can push the ADDR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) # entries from the ATC. so, we do a second set of "plpa"s.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) 	plpar		(%a2)			# load atc for ADDR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) 	plpar		(%a4)			# load atc for ADDR1+3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) # load the BUSCR values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) 	mov.l		&0x80000000,%a2		# assert LOCK* buscr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) 	mov.l		&0xa0000000,%a3		# assert LOCKE* buscr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) 	mov.l		&0x00000000,%a4		# buscr unlock value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) # there are three possible mis-aligned cases for longword cas. they
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) # are separated because the final write which asserts LOCKE* must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) # be aligned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) 	mov.l		%a0,%d0			# is ADDR1 misaligned?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) 	andi.b		&0x3,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) 	beq.b		CAS2L_ENTER		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) 	cmpi.b		%d0,&0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) 	beq.w		CAS2L2_ENTER		# yes; word misaligned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) 	bra.w		CAS2L3_ENTER		# yes; byte misaligned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) # D0 = dst operand 1 <-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) # D1 = dst operand 2 <-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) # D2 = cmp operand 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) # D3 = cmp operand 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) # D4 = update oper 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) # D5 = update oper 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) # D6 = old SFC/DFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) # D7 = old SR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) # A0 = ADDR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) # A1 = ADDR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) # A2 = bus LOCK*  value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) # A3 = bus LOCKE* value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) # A4 = bus unlock value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) # A5 = xxxxxxxx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) 	align		0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) CAS2L_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) 	movc		%a2,%buscr		# assert LOCK*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) 	movs.l		(%a1),%d1		# fetch Dest2[31:0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) 	movs.l		(%a0),%d0		# fetch Dest1[31:0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) 	bra.b		CAS2L_CONT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) CAS2L_ENTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) CAS2L_CONT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) 	cmp.l		%d0,%d2			# Dest1 - Compare1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) 	bne.b		CAS2L_NOUPDATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) 	cmp.l		%d1,%d3			# Dest2 - Compare2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) 	bne.b		CAS2L_NOUPDATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) 	movs.l		%d5,(%a1)		# Update2[31:0] -> DEST2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) 	bra.b		CAS2L_UPDATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) CAS2L_UPDATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) 	movc		%a3,%buscr		# assert LOCKE*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) 	movs.l		%d4,(%a0)		# Update1[31:0] -> DEST1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) 	movc		%a4,%buscr		# unlock the bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) 	bra.b		cas2l_update_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) CAS2L_NOUPDATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) 	movc		%a3,%buscr		# assert LOCKE*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) 	movs.l		%d0,(%a0)		# Dest1[31:0] -> DEST1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) 	movc		%a4,%buscr		# unlock the bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) 	bra.b		cas2l_noupdate_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) CAS2L_FILLER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) 	bra.b		CAS2L_START
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) ####
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) # THIS MUST BE THE STATE OF THE INTEGER REGISTER FILE UPON	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) # ENTERING _isp_cas2().						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) #								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) # D0 = destination[31:0] operand 1				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) # D1 = destination[31:0] operand 2				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) # D2 = cmp[31:0] operand 1					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) # D3 = cmp[31:0] operand 2					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) # D4 = 'xxxxxx11 -> no reg update; 'xxxxxx00 -> update required	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) # D5 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) # D6 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) # D7 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) # A0 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) # A1 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) # A2 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) # A3 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) # A4 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) # A5 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) # A6 = frame pointer						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) # A7 = stack pointer						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) cas2l_noupdate_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) # restore previous SFC/DFC value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) 	movc		%d6,%sfc		# restore old SFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) 	movc		%d6,%dfc		# restore old DFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) # restore previous interrupt mask level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) 	mov.w		%d7,%sr			# restore old SR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) 	sf		%d4			# indicate no update was done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) 	bra.l		_isp_cas2_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) cas2l_update_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) # restore previous SFC/DFC value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) 	movc		%d6,%sfc		# restore old SFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) 	movc		%d6,%dfc		# restore old DFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) # restore previous interrupt mask level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) 	mov.w		%d7,%sr			# restore old SR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) 	st		%d4			# indicate update was done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) 	bra.l		_isp_cas2_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) ####
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) 	align		0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) CAS2L2_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) 	movc		%a2,%buscr		# assert LOCK*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) 	movs.l		(%a1),%d1		# fetch Dest2[31:0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) 	movs.l		(%a0),%d0		# fetch Dest1[31:0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) 	bra.b		CAS2L2_CONT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) CAS2L2_ENTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) CAS2L2_CONT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) 	cmp.l		%d0,%d2			# Dest1 - Compare1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) 	bne.b		CAS2L2_NOUPDATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) 	cmp.l		%d1,%d3			# Dest2 - Compare2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) 	bne.b		CAS2L2_NOUPDATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) 	movs.l		%d5,(%a1)		# Update2[31:0] -> Dest2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) 	bra.b		CAS2L2_UPDATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) CAS2L2_UPDATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) 	swap		%d4			# get Update1[31:16]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) 	movs.w		%d4,(%a0)+		# Update1[31:16] -> DEST1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) 	movc		%a3,%buscr		# assert LOCKE*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) 	swap		%d4			# get Update1[15:0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) 	bra.b		CAS2L2_UPDATE2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) CAS2L2_UPDATE2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) 	movs.w		%d4,(%a0)		# Update1[15:0] -> DEST1+0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) 	movc		%a4,%buscr		# unlock the bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) 	bra.w		cas2l_update_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) CAS2L2_NOUPDATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) 	swap		%d0			# get Dest1[31:16]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) 	movs.w		%d0,(%a0)+		# Dest1[31:16] -> DEST1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) 	movc		%a3,%buscr		# assert LOCKE*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) 	swap		%d0			# get Dest1[15:0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) 	bra.b		CAS2L2_NOUPDATE2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) CAS2L2_NOUPDATE2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) 	movs.w		%d0,(%a0)		# Dest1[15:0] -> DEST1+0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) 	movc		%a4,%buscr		# unlock the bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) 	bra.w		cas2l_noupdate_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) CAS2L2_FILLER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) 	bra.b		CAS2L2_START
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) #################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) 	align		0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) CAS2L3_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) 	movc		%a2,%buscr		# assert LOCK*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) 	movs.l		(%a1),%d1		# fetch Dest2[31:0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) 	movs.l		(%a0),%d0		# fetch Dest1[31:0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) 	bra.b		CAS2L3_CONT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) CAS2L3_ENTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) CAS2L3_CONT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) 	cmp.l		%d0,%d2			# Dest1 - Compare1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) 	bne.b		CAS2L3_NOUPDATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) 	cmp.l		%d1,%d3			# Dest2 - Compare2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) 	bne.b		CAS2L3_NOUPDATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) 	movs.l		%d5,(%a1)		# Update2[31:0] -> DEST2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) 	bra.b		CAS2L3_UPDATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) CAS2L3_UPDATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) 	rol.l		&0x8,%d4		# get Update1[31:24]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) 	movs.b		%d4,(%a0)+		# Update1[31:24] -> DEST1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) 	swap		%d4			# get Update1[23:8]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) 	movs.w		%d4,(%a0)+		# Update1[23:8] -> DEST1+0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) 	bra.b		CAS2L3_UPDATE2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) CAS2L3_UPDATE2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) 	rol.l		&0x8,%d4		# get Update1[7:0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) 	movc		%a3,%buscr		# assert LOCKE*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) 	movs.b		%d4,(%a0)		# Update1[7:0] -> DEST1+0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) 	bra.b		CAS2L3_UPDATE3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) CAS2L3_UPDATE3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) 	movc		%a4,%buscr		# unlock the bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) 	bra.w		cas2l_update_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) CAS2L3_NOUPDATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) 	rol.l		&0x8,%d0		# get Dest1[31:24]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) 	movs.b		%d0,(%a0)+		# Dest1[31:24] -> DEST1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) 	swap		%d0			# get Dest1[23:8]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) 	movs.w		%d0,(%a0)+		# Dest1[23:8] -> DEST1+0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) 	bra.b		CAS2L3_NOUPDATE2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) CAS2L3_NOUPDATE2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) 	rol.l		&0x8,%d0		# get Dest1[7:0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) 	movc		%a3,%buscr		# assert LOCKE*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) 	movs.b		%d0,(%a0)		# Update1[7:0] -> DEST1+0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) 	bra.b		CAS2L3_NOUPDATE3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) CAS2L3_NOUPDATE3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) 	movc		%a4,%buscr		# unlock the bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) 	bra.w		cas2l_noupdate_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) 	bra.b		~+14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) CAS2L3_FILLER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) 	bra.w		CAS2L3_START
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) #############################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) #############################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) cas2w:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) 	mov.l		%a0,%a2			# copy ADDR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) 	mov.l		%a1,%a3			# copy ADDR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) 	mov.l		%a0,%a4			# copy ADDR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) 	mov.l		%a1,%a5			# copy ADDR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) 	addq.l		&0x1,%a4		# ADDR1+1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) 	addq.l		&0x1,%a5		# ADDR2+1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) 	mov.l		%a2,%d1			# ADDR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) # mask interrupt levels 0-6. save old mask value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) 	mov.w		%sr,%d7			# save current SR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) 	ori.w		&0x0700,%sr		# inhibit interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) # load the SFC and DFC with the appropriate mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) 	movc		%sfc,%d6		# save old SFC/DFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) 	movc		%d0,%sfc		# store new SFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) 	movc		%d0,%dfc		# store new DFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) # pre-load the operand ATC. no page faults should occur because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) # _real_lock_page() should have taken care of this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) 	plpaw		(%a2)			# load atc for ADDR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) 	plpaw		(%a4)			# load atc for ADDR1+1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) 	plpaw		(%a3)			# load atc for ADDR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) 	plpaw		(%a5)			# load atc for ADDR2+1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) # push the operand cache lines from the cache if they exist.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) 	cpushl		%dc,(%a2)		# push line for ADDR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) 	cpushl		%dc,(%a4)		# push line for ADDR1+1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) 	cpushl		%dc,(%a3)		# push line for ADDR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) 	cpushl		%dc,(%a5)		# push line for ADDR2+1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) 	mov.l		%d1,%a2			# ADDR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) 	addq.l		&0x3,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) 	mov.l		%d1,%a4			# ADDR1+3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) # if ADDR1 was ATC resident before the above "plpaw" and was executed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) # and it was the next entry scheduled for replacement and ADDR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) # shares the same set, then the "plpaw" for ADDR2 can push the ADDR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) # entries from the ATC. so, we do a second set of "plpa"s.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) 	plpar		(%a2)			# load atc for ADDR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) 	plpar		(%a4)			# load atc for ADDR1+3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) # load the BUSCR values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) 	mov.l		&0x80000000,%a2		# assert LOCK* buscr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) 	mov.l		&0xa0000000,%a3		# assert LOCKE* buscr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) 	mov.l		&0x00000000,%a4		# buscr unlock value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) # there are two possible mis-aligned cases for word cas. they
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) # are separated because the final write which asserts LOCKE* must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) # be aligned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) 	mov.l		%a0,%d0			# is ADDR1 misaligned?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) 	btst		&0x0,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) 	bne.w		CAS2W2_ENTER		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) 	bra.b		CAS2W_ENTER		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) # D0 = dst operand 1 <-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) # D1 = dst operand 2 <-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) # D2 = cmp operand 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) # D3 = cmp operand 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) # D4 = update oper 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) # D5 = update oper 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) # D6 = old SFC/DFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) # D7 = old SR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) # A0 = ADDR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) # A1 = ADDR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) # A2 = bus LOCK*  value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) # A3 = bus LOCKE* value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) # A4 = bus unlock value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) # A5 = xxxxxxxx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) 	align		0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) CAS2W_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) 	movc		%a2,%buscr		# assert LOCK*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) 	movs.w		(%a1),%d1		# fetch Dest2[15:0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) 	movs.w		(%a0),%d0		# fetch Dest1[15:0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) 	bra.b		CAS2W_CONT2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) CAS2W_ENTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) CAS2W_CONT2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) 	cmp.w		%d0,%d2			# Dest1 - Compare1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) 	bne.b		CAS2W_NOUPDATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) 	cmp.w		%d1,%d3			# Dest2 - Compare2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) 	bne.b		CAS2W_NOUPDATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) 	movs.w		%d5,(%a1)		# Update2[15:0] -> DEST2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) 	bra.b		CAS2W_UPDATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) CAS2W_UPDATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) 	movc		%a3,%buscr		# assert LOCKE*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) 	movs.w		%d4,(%a0)		# Update1[15:0] -> DEST1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) 	movc		%a4,%buscr		# unlock the bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) 	bra.b		cas2w_update_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) CAS2W_NOUPDATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) 	movc		%a3,%buscr		# assert LOCKE*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) 	movs.w		%d0,(%a0)		# Dest1[15:0] -> DEST1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) 	movc		%a4,%buscr		# unlock the bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) 	bra.b		cas2w_noupdate_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) CAS2W_FILLER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) 	bra.b		CAS2W_START
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) ####
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) # THIS MUST BE THE STATE OF THE INTEGER REGISTER FILE UPON	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) # ENTERING _isp_cas2().						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) #								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) # D0 = destination[15:0] operand 1				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) # D1 = destination[15:0] operand 2				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) # D2 = cmp[15:0] operand 1					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) # D3 = cmp[15:0] operand 2					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) # D4 = 'xxxxxx11 -> no reg update; 'xxxxxx00 -> update required	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) # D5 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) # D6 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) # D7 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) # A0 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) # A1 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) # A2 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) # A3 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) # A4 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) # A5 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) # A6 = frame pointer						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) # A7 = stack pointer						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) cas2w_noupdate_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) # restore previous SFC/DFC value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) 	movc		%d6,%sfc		# restore old SFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) 	movc		%d6,%dfc		# restore old DFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) # restore previous interrupt mask level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) 	mov.w		%d7,%sr			# restore old SR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) 	sf		%d4			# indicate no update was done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) 	bra.l		_isp_cas2_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) cas2w_update_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) # restore previous SFC/DFC value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) 	movc		%d6,%sfc		# restore old SFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) 	movc		%d6,%dfc		# restore old DFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) # restore previous interrupt mask level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) 	mov.w		%d7,%sr			# restore old SR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) 	st		%d4			# indicate update was done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) 	bra.l		_isp_cas2_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) ####
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) 	align		0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) CAS2W2_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) 	movc		%a2,%buscr		# assert LOCK*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) 	movs.w		(%a1),%d1		# fetch Dest2[15:0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) 	movs.w		(%a0),%d0		# fetch Dest1[15:0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) 	bra.b		CAS2W2_CONT2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) CAS2W2_ENTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) CAS2W2_CONT2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) 	cmp.w		%d0,%d2			# Dest1 - Compare1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) 	bne.b		CAS2W2_NOUPDATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) 	cmp.w		%d1,%d3			# Dest2 - Compare2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) 	bne.b		CAS2W2_NOUPDATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) 	movs.w		%d5,(%a1)		# Update2[15:0] -> DEST2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) 	bra.b		CAS2W2_UPDATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) CAS2W2_UPDATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) 	ror.l		&0x8,%d4		# get Update1[15:8]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) 	movs.b		%d4,(%a0)+		# Update1[15:8] -> DEST1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) 	movc		%a3,%buscr		# assert LOCKE*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) 	rol.l		&0x8,%d4		# get Update1[7:0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) 	bra.b		CAS2W2_UPDATE2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) CAS2W2_UPDATE2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) 	movs.b		%d4,(%a0)		# Update1[7:0] -> DEST1+0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) 	movc		%a4,%buscr		# unlock the bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) 	bra.w		cas2w_update_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) CAS2W2_NOUPDATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) 	ror.l		&0x8,%d0		# get Dest1[15:8]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) 	movs.b		%d0,(%a0)+		# Dest1[15:8] -> DEST1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) 	movc		%a3,%buscr		# assert LOCKE*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) 	rol.l		&0x8,%d0		# get Dest1[7:0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) 	bra.b		CAS2W2_NOUPDATE2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) CAS2W2_NOUPDATE2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) 	movs.b		%d0,(%a0)		# Dest1[7:0] -> DEST1+0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) 	movc		%a4,%buscr		# unlock the bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) 	bra.w		cas2w_noupdate_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) CAS2W2_FILLER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) 	bra.b		CAS2W2_START
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) #       ######      ##      ######
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) #       #	   #  #     #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) #	#	  ######    ######
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) #	#	  #    #         #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) #       ######    #    #    ######
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) #	_isp_cas(): "core" emulation code for the cas instruction	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) #	_isp_cas_finish() - only exit point for this emulation code;	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) #			    do clean-up					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) #	*see entry chart below*						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) #	*see exit chart below*						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) #	(1) Make several copies of the effective address.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) #	(2) Save current SR; Then mask off all maskable interrupts.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) #	(3) Save current DFC/SFC (ASSUMED TO BE EQUAL!!!); Then set	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) #	    SFC/DFC according to whether exception occurred in user or	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) #	    supervisor mode.						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) #	(4) Use "plpaw" instruction to pre-load ATC with effective	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) #	    address page(s). THIS SHOULD NOT FAULT!!! The relevant	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) #	    page(s) should have been made resident prior to entering	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) #	    this routine.						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) #	(5) Push the operand lines from the cache w/ "cpushl".		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) #	    In the 68040, this was done within the locked region. In	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) #	    the 68060, it is done outside of the locked region.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) #	(6) Pre-fetch the core emulation instructions by executing one	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) #	    branch within each physical line (16 bytes) of the code	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) #	    before actually executing the code.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) #	(7) Load the BUSCR with the bus lock value.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) #	(8) Fetch the source operand.					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) #	(9) Do the compare. If equal, go to step (12).			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) #	(10)Unequal. No update occurs. But, we do write the DST op back	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) #	    to itself (as w/ the '040) so we can gracefully unlock	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) #	    the bus (and assert LOCKE*) using BUSCR and the final move.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) #	(11)Exit.							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) #	(12)Write update operand to the DST location. Use BUSCR to	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) #	    assert LOCKE* for the final write operation.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) #	(13)Exit.							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) #	The algorithm is actually implemented slightly differently	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) # depending on the size of the operation and the misalignment of the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) # operand. A misaligned operand must be written in aligned chunks or	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) # else the BUSCR register control gets confused.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) #########################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) # THIS IS THE STATE OF THE INTEGER REGISTER FILE UPON	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) # ENTERING _isp_cas().					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) #							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) # D0 = xxxxxxxx						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) # D1 = xxxxxxxx						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) # D2 = update operand					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) # D3 = xxxxxxxx						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) # D4 = compare operand					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) # D5 = xxxxxxxx						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) # D6 = supervisor ('xxxxxxff) or user mode ('xxxxxx00)	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) # D7 = longword ('xxxxxxff) or word size ('xxxxxx00)	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) # A0 = ADDR						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) # A1 = xxxxxxxx						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) # A2 = xxxxxxxx						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) # A3 = xxxxxxxx						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) # A4 = xxxxxxxx						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) # A5 = xxxxxxxx						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) # A6 = frame pointer					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) # A7 = stack pointer					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) #########################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) 	global		_isp_cas
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) _isp_cas:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) 	tst.b		%d6			# user or supervisor mode?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) 	bne.b		cas_super		# supervisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) cas_user:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) 	movq.l		&0x1,%d0		# load user data fc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) 	bra.b		cas_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) cas_super:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) 	movq.l		&0x5,%d0		# load supervisor data fc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) cas_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) 	tst.b		%d7			# word or longword?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) 	bne.w		casl			# longword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) ####
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) casw:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) 	mov.l		%a0,%a1			# make copy for plpaw1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) 	mov.l		%a0,%a2			# make copy for plpaw2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) 	addq.l		&0x1,%a2		# plpaw2 points to end of word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) 	mov.l		%d2,%d3			# d3 = update[7:0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) 	lsr.w		&0x8,%d2		# d2 = update[15:8]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) # mask interrupt levels 0-6. save old mask value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) 	mov.w		%sr,%d7			# save current SR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) 	ori.w		&0x0700,%sr		# inhibit interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) # load the SFC and DFC with the appropriate mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) 	movc		%sfc,%d6		# save old SFC/DFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) 	movc		%d0,%sfc		# load new sfc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) 	movc		%d0,%dfc		# load new dfc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) # pre-load the operand ATC. no page faults should occur here because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) # _real_lock_page() should have taken care of this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) 	plpaw		(%a1)			# load atc for ADDR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) 	plpaw		(%a2)			# load atc for ADDR+1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) # push the operand lines from the cache if they exist.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) 	cpushl		%dc,(%a1)		# push dirty data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) 	cpushl		%dc,(%a2)		# push dirty data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) # load the BUSCR values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) 	mov.l		&0x80000000,%a1		# assert LOCK* buscr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) 	mov.l		&0xa0000000,%a2		# assert LOCKE* buscr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) 	mov.l		&0x00000000,%a3		# buscr unlock value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) # pre-load the instruction cache for the following algorithm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) # this will minimize the number of cycles that LOCK* will be asserted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) 	bra.b		CASW_ENTER		# start pre-loading icache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) # D0 = dst operand <-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) # D1 = update[15:8] operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) # D2 = update[7:0]  operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) # D3 = xxxxxxxx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) # D4 = compare[15:0] operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) # D5 = xxxxxxxx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) # D6 = old SFC/DFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) # D7 = old SR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) # A0 = ADDR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) # A1 = bus LOCK*  value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) # A2 = bus LOCKE* value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) # A3 = bus unlock value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) # A4 = xxxxxxxx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) # A5 = xxxxxxxx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) 	align		0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) CASW_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) 	movc		%a1,%buscr		# assert LOCK*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) 	movs.w		(%a0),%d0		# fetch Dest[15:0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) 	cmp.w		%d0,%d4			# Dest - Compare
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) 	bne.b		CASW_NOUPDATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) 	bra.b		CASW_UPDATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) CASW_ENTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) CASW_UPDATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) 	movs.b		%d2,(%a0)+		# Update[15:8] -> DEST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) 	movc		%a2,%buscr		# assert LOCKE*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) 	movs.b		%d3,(%a0)		# Update[7:0] -> DEST+0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) 	bra.b		CASW_UPDATE2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) CASW_UPDATE2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) 	movc		%a3,%buscr		# unlock the bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) 	bra.b		casw_update_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) CASW_NOUPDATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) 	ror.l		&0x8,%d0		# get Dest[15:8]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) 	movs.b		%d0,(%a0)+		# Dest[15:8] -> DEST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) 	movc		%a2,%buscr		# assert LOCKE*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) 	rol.l		&0x8,%d0		# get Dest[7:0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) 	bra.b		CASW_NOUPDATE2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) CASW_NOUPDATE2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) 	movs.b		%d0,(%a0)		# Dest[7:0] -> DEST+0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) 	movc		%a3,%buscr		# unlock the bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) 	bra.b		casw_noupdate_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) CASW_FILLER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) 	bra.b		CASW_START
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) # THIS MUST BE THE STATE OF THE INTEGER REGISTER FILE UPON	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) # CALLING _isp_cas_finish().					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) #								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) # D0 = destination[15:0] operand				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) # D1 = 'xxxxxx11 -> no reg update; 'xxxxxx00 -> update required	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) # D2 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) # D3 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) # D4 = compare[15:0] operand					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) # D5 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) # D6 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) # D7 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) # A0 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) # A1 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) # A2 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) # A3 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) # A4 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) # A5 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) # A6 = frame pointer						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) # A7 = stack pointer						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) casw_noupdate_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) # restore previous SFC/DFC value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) 	movc		%d6,%sfc		# restore old SFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) 	movc		%d6,%dfc		# restore old DFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) # restore previous interrupt mask level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) 	mov.w		%d7,%sr			# restore old SR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) 	sf		%d1			# indicate no update was done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) 	bra.l		_isp_cas_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) casw_update_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) # restore previous SFC/DFC value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) 	movc		%d6,%sfc		# restore old SFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) 	movc		%d6,%dfc		# restore old DFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) # restore previous interrupt mask level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) 	mov.w		%d7,%sr			# restore old SR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) 	st		%d1			# indicate update was done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) 	bra.l		_isp_cas_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) ################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) # there are two possible mis-aligned cases for longword cas. they
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) # are separated because the final write which asserts LOCKE* must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) # be an aligned write.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) casl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) 	mov.l		%a0,%a1			# make copy for plpaw1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) 	mov.l		%a0,%a2			# make copy for plpaw2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) 	addq.l		&0x3,%a2		# plpaw2 points to end of longword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) 	mov.l		%a0,%d1			# byte or word misaligned?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042) 	btst		&0x0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) 	bne.w		casl2			# byte misaligned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) 	mov.l		%d2,%d3			# d3 = update[15:0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046) 	swap		%d2			# d2 = update[31:16]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) # mask interrupts levels 0-6. save old mask value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) 	mov.w		%sr,%d7			# save current SR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) 	ori.w		&0x0700,%sr		# inhibit interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) # load the SFC and DFC with the appropriate mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) 	movc		%sfc,%d6		# save old SFC/DFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) 	movc		%d0,%sfc		# load new sfc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) 	movc		%d0,%dfc		# load new dfc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) # pre-load the operand ATC. no page faults should occur here because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) # _real_lock_page() should have taken care of this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) 	plpaw		(%a1)			# load atc for ADDR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) 	plpaw		(%a2)			# load atc for ADDR+3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) # push the operand lines from the cache if they exist.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) 	cpushl		%dc,(%a1)		# push dirty data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) 	cpushl		%dc,(%a2)		# push dirty data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) # load the BUSCR values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) 	mov.l		&0x80000000,%a1		# assert LOCK* buscr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) 	mov.l		&0xa0000000,%a2		# assert LOCKE* buscr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) 	mov.l		&0x00000000,%a3		# buscr unlock value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) 	bra.b		CASL_ENTER		# start pre-loading icache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) # D0 = dst operand <-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) # D1 = xxxxxxxx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) # D2 = update[31:16] operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) # D3 = update[15:0]  operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) # D4 = compare[31:0] operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) # D5 = xxxxxxxx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) # D6 = old SFC/DFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) # D7 = old SR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) # A0 = ADDR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) # A1 = bus LOCK*  value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) # A2 = bus LOCKE* value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) # A3 = bus unlock value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) # A4 = xxxxxxxx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087) # A5 = xxxxxxxx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) 	align		0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) CASL_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) 	movc		%a1,%buscr		# assert LOCK*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) 	movs.l		(%a0),%d0		# fetch Dest[31:0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093) 	cmp.l		%d0,%d4			# Dest - Compare
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) 	bne.b		CASL_NOUPDATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) 	bra.b		CASL_UPDATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) CASL_ENTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) CASL_UPDATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) 	movs.w		%d2,(%a0)+		# Update[31:16] -> DEST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) 	movc		%a2,%buscr		# assert LOCKE*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) 	movs.w		%d3,(%a0)		# Update[15:0] -> DEST+0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) 	bra.b		CASL_UPDATE2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) CASL_UPDATE2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) 	movc		%a3,%buscr		# unlock the bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) 	bra.b		casl_update_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) CASL_NOUPDATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) 	swap		%d0			# get Dest[31:16]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) 	movs.w		%d0,(%a0)+		# Dest[31:16] -> DEST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) 	swap		%d0			# get Dest[15:0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) 	movc		%a2,%buscr		# assert LOCKE*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) 	bra.b		CASL_NOUPDATE2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) CASL_NOUPDATE2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) 	movs.w		%d0,(%a0)		# Dest[15:0] -> DEST+0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) 	movc		%a3,%buscr		# unlock the bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) 	bra.b		casl_noupdate_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) CASL_FILLER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) 	bra.b		CASL_START
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) # THIS MUST BE THE STATE OF THE INTEGER REGISTER FILE UPON	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) # CALLING _isp_cas_finish().					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) #								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) # D0 = destination[31:0] operand				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) # D1 = 'xxxxxx11 -> no reg update; 'xxxxxx00 -> update required	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) # D2 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) # D3 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) # D4 = compare[31:0] operand					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) # D5 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) # D6 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) # D7 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) # A0 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) # A1 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) # A2 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) # A3 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) # A4 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) # A5 = xxxxxxxx							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) # A6 = frame pointer						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) # A7 = stack pointer						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) casl_noupdate_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165) # restore previous SFC/DFC value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) 	movc		%d6,%sfc		# restore old SFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) 	movc		%d6,%dfc		# restore old DFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) # restore previous interrupt mask level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) 	mov.w		%d7,%sr			# restore old SR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) 	sf		%d1			# indicate no update was done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) 	bra.l		_isp_cas_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) casl_update_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) # restore previous SFC/DFC value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) 	movc		%d6,%sfc		# restore old SFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179) 	movc		%d6,%dfc		# restore old DFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) # restore previous interrupts mask level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182) 	mov.w		%d7,%sr			# restore old SR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) 	st		%d1			# indicate update was done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) 	bra.l		_isp_cas_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) #######################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) casl2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) 	mov.l		%d2,%d5			# d5 = Update[7:0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) 	lsr.l		&0x8,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) 	mov.l		%d2,%d3			# d3 = Update[23:8]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192) 	swap		%d2			# d2 = Update[31:24]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) # mask interrupts levels 0-6. save old mask value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) 	mov.w		%sr,%d7			# save current SR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) 	ori.w		&0x0700,%sr		# inhibit interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) # load the SFC and DFC with the appropriate mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) 	movc		%sfc,%d6		# save old SFC/DFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) 	movc		%d0,%sfc		# load new sfc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) 	movc		%d0,%dfc		# load new dfc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203) # pre-load the operand ATC. no page faults should occur here because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) # _real_lock_page() should have taken care of this already.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) 	plpaw		(%a1)			# load atc for ADDR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) 	plpaw		(%a2)			# load atc for ADDR+3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) # puch the operand lines from the cache if they exist.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) 	cpushl		%dc,(%a1)		# push dirty data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) 	cpushl		%dc,(%a2)		# push dirty data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) # load the BUSCR values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) 	mov.l		&0x80000000,%a1		# assert LOCK* buscr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214) 	mov.l		&0xa0000000,%a2		# assert LOCKE* buscr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) 	mov.l		&0x00000000,%a3		# buscr unlock value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217) # pre-load the instruction cache for the following algorithm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218) # this will minimize the number of cycles that LOCK* will be asserted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219) 	bra.b		CASL2_ENTER		# start pre-loading icache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222) # D0 = dst operand <-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223) # D1 = xxxxxxxx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224) # D2 = update[31:24] operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225) # D3 = update[23:8]  operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) # D4 = compare[31:0] operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227) # D5 = update[7:0]  operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) # D6 = old SFC/DFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229) # D7 = old SR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230) # A0 = ADDR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) # A1 = bus LOCK*  value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232) # A2 = bus LOCKE* value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233) # A3 = bus unlock value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234) # A4 = xxxxxxxx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) # A5 = xxxxxxxx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) 	align		0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238) CASL2_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) 	movc		%a1,%buscr		# assert LOCK*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240) 	movs.l		(%a0),%d0		# fetch Dest[31:0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241) 	cmp.l		%d0,%d4			# Dest - Compare
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242) 	bne.b		CASL2_NOUPDATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243) 	bra.b		CASL2_UPDATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244) CASL2_ENTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) CASL2_UPDATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248) 	movs.b		%d2,(%a0)+		# Update[31:24] -> DEST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249) 	movs.w		%d3,(%a0)+		# Update[23:8] -> DEST+0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250) 	movc		%a2,%buscr		# assert LOCKE*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) 	bra.b		CASL2_UPDATE2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) CASL2_UPDATE2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) 	movs.b		%d5,(%a0)		# Update[7:0] -> DEST+0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) 	movc		%a3,%buscr		# unlock the bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) 	bra.w		casl_update_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) CASL2_NOUPDATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262) 	rol.l		&0x8,%d0		# get Dest[31:24]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263) 	movs.b		%d0,(%a0)+		# Dest[31:24] -> DEST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) 	swap		%d0			# get Dest[23:8]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265) 	movs.w		%d0,(%a0)+		# Dest[23:8] -> DEST+0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) 	bra.b		CASL2_NOUPDATE2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) CASL2_NOUPDATE2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) 	rol.l		&0x8,%d0		# get Dest[7:0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) 	movc		%a2,%buscr		# assert LOCKE*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272) 	movs.b		%d0,(%a0)		# Dest[7:0] -> DEST+0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) 	bra.b		CASL2_NOUPDATE3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277) CASL2_NOUPDATE3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278) 	movc		%a3,%buscr		# unlock the bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279) 	bra.w		casl_noupdate_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) 	bra.b		~+16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285) CASL2_FILLER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) 	nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) 	bra.b		CASL2_START
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295) ####
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) ####
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) # end label used by _isp_cas_inrange()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) 	global		_CASHI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299) _CASHI: