^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: