Better A3000/A4000 ReadGayle() update, save and restore possible Gary timeout register.
[AROS.git] / arch / m68k-amiga / exec / readgayle.S
blobb33600020feff896a455c1b689be4068430882a0
1 /*
2     Copyright © 1995-2010, The AROS Development Team. All rights reserved.
3     $Id$
5     Desc: ReadGayle() - get the Gayle ID
6     Lang: english
7 */
8 /*****************************************************************************
10     NAME
11 #include <proto/exec.h>
13         AROS_LH0(ULONG, ReadGayle,
15     LOCATION
16         struct ExecBase *, SysBase, 136, Exec)
18     FUNCTION
19     Gets the Gayle ID
21     INPUTS
22         None.
24     RESULT
26     NOTES
28     EXAMPLE
30     BUGS
32     SEE ALSO
34     INTERNALS
36 ******************************************************************************/
37         #include "aros/m68k/asm.h"
39         .text
40         .balign 4
41         .globl  AROS_SLIB_ENTRY(ReadGayle,Exec,136)
42 AROS_SLIB_ENTRY(ReadGayle,Exec,136):
44         /* A3000 Fat Gary/RAMSEY registers are supposed to be supervisor-only
45          * Common chip revisions don't care but later (rare) revisions might do it */
47         /* If A6 is 0, this is the initial ROM call, and
48          * we are already in supervisor mode.
49          */
50         move.l  %a6,%d0
51         beq.s   ss
52         move.l  %a5,%sp@-
53         lea             %pc@(sv),%a5
54         jsr             Supervisor(%a6)
55         move.l  %sp@+,%a5
56         rts
57 sv:
58         or.w    #0x0700,%sr
59 ss:
60         move.l  #0xde1000,%a0       /* Gayle ID register */
61         move.l  #0xdff000,%a1
62         /* NOTE: We must check for custom chip mirroring. */
63         /* Can we turn off interrupts? */
64         move.w  0x1c(%a1),%sp@-         /* INTENAR */
65         move.w  #0x7fff,0x9a(%a1)       /* INTENA */
66         tst.w   0x1c(%a0)
67         bne.s   4f                                      /* If non-zero, not INTENAR */
68         move.w  #0xc000,0x9a(%a1)
69         move.w  0x1c(%a0),%d0
70         move.w  #0x7fff,0x9a(%a1)       /* INTENA */
71         cmp.w   #0x4000,%d0
72         beq.s   3f                                      /* If 0x4000, was INTENAR */
74         /* Now, finally, we can check for a Gayle */
75         clr.l   %d0                 /* ID we will return */
76         moveq   #8-1,%d1            /* Gayle bit index */
78         move.b  %a0@,%sp@-                      /* It could be Gary timeout register, not Gayle ID. */
80         move.b  %d0,%a0@            /* Reset ID register */
82 0:      move.b  %a0@,%d0            /* Put reg into lower byte of %d0 */
83         lsl.w   #1,%d0              /* Shift lower 16 bits of %d0 left by 1 */
84         dbf             %d1,0b
85         lsr.w   #8,%d0              /* Move ID to lower 8 bits of %d0 */
87         move.b  %sp@+,%a0@                      /* Restore possible Gary timeout register */
89         cmp.b   #0xff,%d0
90         bne.s   1f
92         clr.b   %d0
95         /* Restore interrupts. */
96         move.w  %sp@+,%d1
97         or.w    #0x8000,%d1
98         move.w  %d1,0x9a(%a1)           /* INTENA */
100         move.l  %a6,%d1
101         beq.s   2f
102         rte
103 2:      rts