head     56.3;
access   paws bayes jws quist brad dew jwh;
symbols  ;
locks    ; strict;
comment  @# @;


56.3
date     93.01.27.13.18.42;  author jwh;  state Exp;
branches ;
next     56.2;

56.2
date     93.01.27.11.59.44;  author jwh;  state Exp;
branches ;
next     56.1;

56.1
date     91.11.05.09.56.01;  author jwh;  state Exp;
branches ;
next     55.1;

55.1
date     91.08.25.10.31.27;  author jwh;  state Exp;
branches ;
next     54.5;

54.5
date     91.08.21.10.38.43;  author jwh;  state Exp;
branches ;
next     54.4;

54.4
date     91.08.21.09.42.25;  author jwh;  state Exp;
branches ;
next     54.3;

54.3
date     91.08.08.08.46.22;  author jwh;  state Exp;
branches ;
next     54.2;

54.2
date     91.05.28.13.39.48;  author jwh;  state Exp;
branches ;
next     54.1;

54.1
date     91.03.18.15.32.49;  author jwh;  state Exp;
branches ;
next     53.1;

53.1
date     91.03.11.19.32.45;  author jwh;  state Exp;
branches ;
next     52.1;

52.1
date     91.02.19.09.18.03;  author jwh;  state Exp;
branches ;
next     51.2;

51.2
date     91.02.10.15.14.49;  author jwh;  state Exp;
branches ;
next     51.1;

51.1
date     91.01.30.16.17.17;  author jwh;  state Exp;
branches ;
next     50.1;

50.1
date     90.10.29.16.31.22;  author jwh;  state Exp;
branches ;
next     49.3;

49.3
date     90.10.29.14.07.32;  author jwh;  state Exp;
branches ;
next     49.2;

49.2
date     90.09.24.16.01.55;  author jwh;  state Exp;
branches ;
next     49.1;

49.1
date     90.08.14.14.15.07;  author jwh;  state Exp;
branches ;
next     48.1;

48.1
date     90.07.26.11.21.35;  author jwh;  state Exp;
branches ;
next     47.1;

47.1
date     90.05.14.11.06.30;  author dew;  state Exp;
branches ;
next     46.1;

46.1
date     90.05.07.08.53.27;  author jwh;  state Exp;
branches ;
next     45.1;

45.1
date     90.04.19.16.01.25;  author jwh;  state Exp;
branches ;
next     44.1;

44.1
date     90.04.01.22.18.37;  author jwh;  state Exp;
branches ;
next     43.1;

43.1
date     90.03.20.14.11.15;  author jwh;  state Exp;
branches ;
next     42.1;

42.1
date     90.01.23.17.55.31;  author jwh;  state Exp;
branches ;
next     41.2;

41.2
date     90.01.18.22.49.36;  author jwh;  state Exp;
branches ;
next     41.1;

41.1
date     89.12.22.11.37.40;  author jwh;  state Exp;
branches ;
next     40.7;

40.7
date     89.12.21.15.01.03;  author jwh;  state Exp;
branches ;
next     40.6;

40.6
date     89.12.15.15.53.21;  author jwh;  state Exp;
branches ;
next     40.5;

40.5
date     89.12.15.15.40.12;  author jwh;  state Exp;
branches ;
next     40.4;

40.4
date     89.12.15.14.44.45;  author jwh;  state Exp;
branches ;
next     40.3;

40.3
date     89.12.01.13.51.57;  author jwh;  state Exp;
branches ;
next     40.2;

40.2
date     89.12.01.10.32.23;  author jwh;  state Exp;
branches ;
next     40.1;

40.1
date     89.09.29.11.58.44;  author jwh;  state Exp;
branches ;
next     39.1;

39.1
date     89.09.26.16.43.31;  author dew;  state Exp;
branches ;
next     38.1;

38.1
date     89.08.29.11.35.31;  author jwh;  state Exp;
branches ;
next     37.1;

37.1
date     89.05.12.11.49.20;  author dew;  state Exp;
branches ;
next     36.1;

36.1
date     89.02.06.10.26.57;  author dew;  state Exp;
branches ;
next     35.1;

35.1
date     89.02.02.13.42.34;  author dew;  state Exp;
branches ;
next     34.1;

34.1
date     89.01.23.16.17.46;  author jwh;  state Exp;
branches ;
next     33.1;

33.1
date     89.01.16.11.49.10;  author dew;  state Exp;
branches ;
next     32.1;

32.1
date     89.01.10.11.58.32;  author bayes;  state Exp;
branches ;
next     31.1;

31.1
date     88.12.14.18.19.19;  author bayes;  state Exp;
branches ;
next     30.1;

30.1
date     88.12.09.13.56.25;  author dew;  state Exp;
branches ;
next     29.1;

29.1
date     88.10.31.15.40.58;  author bayes;  state Exp;
branches ;
next     28.1;

28.1
date     88.10.06.11.07.13;  author dew;  state Exp;
branches ;
next     27.2;

27.2
date     88.09.29.12.42.32;  author bayes;  state Exp;
branches ;
next     27.1;

27.1
date     88.09.29.11.49.58;  author bayes;  state Exp;
branches ;
next     26.1;

26.1
date     88.09.28.13.38.54;  author bayes;  state Exp;
branches ;
next     25.1;

25.1
date     88.03.02.09.44.38;  author bayes;  state Exp;
branches ;
next     24.1;

24.1
date     87.08.31.10.15.40;  author jws;  state Exp;
branches ;
next     23.1;

23.1
date     87.08.26.11.01.31;  author bayes;  state Exp;
branches ;
next     22.1;

22.1
date     87.08.17.11.40.54;  author bayes;  state Exp;
branches ;
next     21.1;

21.1
date     87.08.12.14.24.58;  author bayes;  state Exp;
branches ;
next     20.1;

20.1
date     87.07.30.11.36.38;  author bayes;  state Exp;
branches ;
next     19.1;

19.1
date     87.06.01.08.50.40;  author jws;  state Exp;
branches ;
next     18.1;

18.1
date     87.05.20.15.56.01;  author bayes;  state Exp;
branches ;
next     17.1;

17.1
date     87.04.30.10.59.56;  author jws;  state Exp;
branches ;
next     16.1;

16.1
date     87.04.26.16.10.10;  author jws;  state Exp;
branches ;
next     15.1;

15.1
date     87.04.13.09.50.51;  author jws;  state Exp;
branches ;
next     14.1;

14.1
date     87.04.01.16.00.35;  author jws;  state Exp;
branches ;
next     13.1;

13.1
date     87.02.28.18.53.29;  author jws;  state Exp;
branches ;
next     12.1;

12.1
date     87.02.02.13.47.05;  author jws;  state Exp;
branches ;
next     11.1;

11.1
date     87.01.19.10.13.14;  author jws;  state Exp;
branches ;
next     10.1;

10.1
date     86.12.24.11.28.24;  author jws;  state Exp;
branches ;
next     9.1;

9.1
date     86.12.12.15.12.04;  author bayes;  state Exp;
branches ;
next     8.1;

8.1
date     86.11.27.12.21.35;  author jws;  state Exp;
branches ;
next     7.1;

7.1
date     86.11.20.14.33.35;  author hal;  state Exp;
branches ;
next     6.1;

6.1
date     86.11.04.18.26.56;  author paws;  state Exp;
branches ;
next     5.1;

5.1
date     86.10.28.17.16.18;  author hal;  state Exp;
branches ;
next     4.1;

4.1
date     86.09.30.20.10.16;  author hal;  state Exp;
branches ;
next     3.1;

3.1
date     86.09.01.12.21.19;  author hal;  state Exp;
branches ;
next     2.2;

2.2
date     86.08.12.10.44.52;  author hal;  state Exp;
branches ;
next     2.1;

2.1
date     86.07.30.15.09.46;  author hal;  state Exp;
branches ;
next     1.1;

1.1
date     86.06.30.16.46.53;  author danm;  state tmp;
branches ;
next     ;


desc
@Base file for PWS 3.2 release.

@


56.3
log
@
pws2rcs automatic delta on Wed Jan 27 13:14:25 MST 1993
@
text
@*
*       INTERRUPT, TRAP, AND EXCEPTION HANDLER
*
*    (rdq) changes for Rev 3.0
*
*     CHANGES FOR PARITY SUPPORT  -- JS 9/12/83
*     Changes for 68040 support - JWH 12/1/89
*     Each line has 68040 as a comment.
*
	DEF     ASM_SETINTLEVEL,ASM_INTLEVEL
	DEF     ASM_INITVECTS,RESETX,ASM_CLOSEFILES
	DEF     EXCP_PC,EXCP_LINE
	DEF     GRAPHICSBASE,GRAPHICSFLAG,ALPHAFLAG,FLTPTHDW
	DEF     INITSTACK                                     JS 20 JUN 85
	DEF     ERR_INFO                                      RQ 18/Jan/84

	REFA    SYSGLOBALS,LOADER,STACKFUDGE,ASM_CACHE_ON
	REFA    ASM_FLUSH_ICACHE,ASM_ICACHE_ON                3/25/85
	REFA    ASM_ICACHE_OFF,ASM_CACHE_OFF,ASM_COPY_OFF
	REFR    FS_FCLOSE,INITUNITS_NOISR,INITLOAD_INITLOAD
	LMODE   FS_FCLOSE,INITUNITS_NOISR,INITLOAD_INITLOAD
	LMODE   ASM_CACHE_ON
	LMODE   ASM_FLUSH_ICACHE,ASM_ICACHE_ON                3/25/85
	LMODE   ASM_ICACHE_OFF,ASM_CACHE_OFF
	LMODE   SPUR_VEC,OUTA_HERE
	SMODE   ESCAPE

*THE FOLLOWING OFFSETS ARE RELATIVE TO SYSGLOBALS(A5)

ESCAPECODE      EQU SYSGLOBALS-2          (A5)
FILELISTPTR     EQU SYSGLOBALS-6          (A5)
RECOVERBLOCK    EQU SYSGLOBALS-10         (A5)
HEAPPOINTER     EQU SYSGLOBALS-14         (A5)
HEAPBASE        EQU SYSGLOBALS-18         (A5)
IORESULT        EQU SYSGLOBALS-22         (A5)
INTERRUPTTABLE  EQU SYSGLOBALS-62         (A5) ADDRESS OF INTERRUPTTABLE[1..7]
ENDISRHOOK      EQU SYSGLOBALS-66         (A5) ADDRESS OF END OF ISR ROUTINE
DEBUGGER        EQU SYSGLOBALS-276        (A5) DEBUGGER HOOK
CLEARIOHOOK     EQU SYSGLOBALS-284        (A5) CLEAR I/O HOOK
SYSDEFS         EQU LOADER-70             (A5) LINKED LIST OF PERMANT PROGRAMS
NIL             EQU 0

HIGHMEM         EQU $FFFFFB00   LEAVES ROOM FOR VECTORS, MONITOR STUFF, ETC.
TRAP0VECTOR     EQU $FFFFFF94   LOCATION OF EXCEPTION VECTOR FOR TRAP #0
*
LEVEL7V         EQU $FFFFFF9A   NMI
LEVEL7DV        EQU $FFFFFF22   LEVEL 7 DEVICE VECTOR                   (rdq)
KBDRESETV       EQU $FFFFFF34   KEY BOARD <SHIFT PAUSE VECTOR>
FHIVECTOR       EQU $FFFFFF2E   KEY BOARD LEVEL 7 TIMER INTERRUPT       (rdq)
*
F_LINEV         EQU $FFFFFFC4   TRAP FOR F-LINE INSTRUCTIONS
M68881V         EQU $FFFFFEE0   TRAP FOR 68881 EXCEPTIONS
UNSUPP          EQU $FFFFFEE6   68040 only
SPUR_VEC        EQU $FFFFFF1C   SPURIOUS INTERRUPT VECTOR
*
LOWMEM          EQU $FFFFFDCE   LOCATION IN BOOT ROM OF LOWEST RAM
RTN_TO_MONITOR  EQU $1A0        ENTRY POINT IN BOOT ROM
G_OFF_MEM       EQU $538000     GRAPHICS OFF
ALPHA_MEM       EQU $512000     ALPHA MEMORY
*
P_STATUS        EQU $5B0000     PARITY STATUS REG                  JS 9/12/83
*
*
* MAGIC NUMBERS, see alse FILES ASM, DEBUGGER and INITBUG
*
ERR_INFO        EQU HIGHMEM
FAULT_ADDR      EQU HIGHMEM     PARITY ERROR ADDRESS
*                                       68000
BE_SSW          EQU     HIGHMEM         SPECIAL STATUS WORD
BE_FAULT_ADDR   EQU     BE_SSW+2        FAULT ADDRESS
BE_INSTR        EQU     BE_FAULT_ADDR+4 INSTRUCTION BUFFER
*
*                                       68010
*BE_SSW         2 BYTES                 VECTOR TYPE 1000
*BE_FAULT_ADDR  4 BYTES
BE_PAD1_10      EQU     BE_FAULT_ADDR+4
BE_DATAO_10     EQU     BE_PAD1_10+2    DATA INPUT BUFFER
BE_PAD2_10      EQU     BE_DATAO_10+2
BE_DATAI_10     EQU     BE_PAD2_10+2    DATA OUTPUT BUFFER
BE_PAD3_10      EQU     BE_DATAI_10+2
BE_INSTR_10     EQU     BE_PAD3_10+2    INSTRUCTION BUFFER
BE_MISC_10      EQU     BE_INSTR_10+2   16 WORDS
BE_END_10       EQU     BE_MISC_10+32
*
*                                       68020
ERR_PC          EQU     HIGHMEM         VECTOR TYPE 0010
*ERR_PC         4 BYTES                 VECTOR TYPE 1001
ERR_WRD1        EQU     ERR_PC+4
ERR_WRD2        EQU     ERR_WRD1+2
ERR_EA          EQU     ERR_WRD2+2      EVALUATED ADDRESS
*BE_SSW         4 BYTES                 VECTOR TYPE 1010 (SHORT BUS ERROR)
BE_IPSC         EQU     BE_SSW+4        I PIPE C
BE_IPSB         EQU     BE_IPSC+2       I PIPE B
BE_PAD2_20      EQU     BE_IPSB+2
BE_FAULT_ADDR20 EQU     BE_PAD2_20+4
BE_DATA_20      EQU     BE_FAULT_ADDR20+4       DATA BUFFER
BE_MISCS_20     EQU     BE_DATA_20+4    4 BYTES
BE_END_S_20     EQU     BE_MISCS_20+4
*
*BE_SSW         4 BYTES                 VECTOR TYPE 1011 (LONG BUS ERROR)
*BE_IPSC        2 BYTES
*BE_IPSB        2 BYTES
*BE_PAD         4 BYTES
*BE_FAULT_ADDR  4 BYTES
*BE_DATAO       4 BYTES
BE_PAD3_20      EQU     BE_DATA_20+4            16 BYTES
BE_DATAI_20     EQU     BE_PAD3_20+16
BE_MISC20_20    EQU     BE_DATAI_20+4           44 BYTES
BE_END_L_20     EQU     BE_MISC20_20+44
BE_END          EQU     BE_END_L_20
*--------------------------------------------------------------------------
EXCP_STATUS     EQU BE_END
EXCP_PC         EQU EXCP_STATUS+2
EXCP_VOFFSET    EQU EXCP_PC+4           VECTOR WORD FOR 680xx           (rdq)
EXCP_LINE       EQU EXCP_VOFFSET+2                                      (rdq)
LASTLINE        EQU EXCP_LINE+4
ESCAPE          EQU LASTLINE+4
PCTEMP          EQU ESCAPE+6
SRTEMP          EQU PCTEMP+4
INITSTACK       EQU SRTEMP+2
INITPC          EQU INITSTACK+4
INITRECOVER     EQU INITPC+4
G_DOLLAR        EQU INITRECOVER+4
CTL_RESETV      EQU G_DOLLAR+4          KEY BOARD <CONTROL><SHIFT><PAUSE> VECTOR
DEBUGESCAPE     EQU CTL_RESETV+6
BESPTEMP        EQU DEBUGESCAPE+6       USED IN IGNOREBUS
ALPHAFLAG       EQU BESPTEMP+4
GRAPHICSFLAG    EQU ALPHAFLAG+1
GRAPHICSBASE    EQU GRAPHICSFLAG+1
INITSR          EQU GRAPHICSBASE+4
M68KTYPE        EQU INITSR+2    PROCESSOR TYPE 0=68000 else 680xx       (rdq)
MSYSFLAGS       EQU M68KTYPE+1  MORE SYSFLAGS BIT 0 = CACHE PRESENT/ABSENT
FLTPTHDW        EQU MSYSFLAGS+1
FILLER          EQU FLTPTHDW+1  UNUSED

JMP     EQU $4EF9                       LONG ABSOLUTE JMP OPCODE


	RORG 0

*
* NOTE -- ALL CACHES SHOULD BE OFF AT THIS TIME
*
ASM_INITVECTS   EQU *                   MAIN PROGRAM POWER UP LOCATION
	CLR.B   FLTPTHDW        SHOW NO FLOATING POINT HARDWARE

	MOVEQ   #$FFFFFFFF,D0           HIGHEST POSSIBLE ADDRESS
	MOVE.L  D0,FILELISTPTR(A5)
	MOVE.W  #$4E75,DEBUGESCAPE
	CLR.L   LASTLINE
	MOVE.L  #ENDISR,ENDISRHOOK(A5)  SET UP ORDINARY RETURN FROM ISR's

	jsr     init_timer      checks for and turns on timer   (rdq)

*                               TURN OFF GRAPHICS
	MOVEA.L #G_OFF_MEM,A0   GET MEM ADDRESS
	MOVE.L  A0,GRAPHICSBASE SAVE IT IN GLOBAL AREA
	CLR.B   GRAPHICSFLAG    MARK IT TURNED OFF

	LEA     IGNOREBUS,A1    SET BUS ERROR VECTOR
	MOVE.L  A1,-4
	MOVE.W  #JMP,-6
	PEA     GRPH1
	MOVE.L  SP,BESPTEMP
	MOVE    (A0),D0         TURN OFF GRAPHICS
	ADDQ.L  #4,SP
GRPH1   EQU     *
	MOVE.B  #1,ALPHAFLAG    MARK ALPHA TURNED ON
*
*    TURN ON CACHE IF WE HAVE ONE
*
CACHE_CTL EQU   $5F400E
	CLR.B   MSYSFLAGS       CLEAR FLAGS BYTE
	PEA     CACHE1
	MOVE.L  SP,BESPTEMP
	TST.W   CACHE_CTL       TEST
	ADDQ.L  #4,SP
	BSET    #0,MSYSFLAGS    CACHE EXISTS
	MOVE    #0,CACHE_CTL    CLEAR THE CONTROL WORD
	JSR     ASM_CACHE_ON
CACHE1  EQU     *
*
*    TURN ON PARITY BOARDS IF ANY                             JS 9/12/83
*                                                             JS 9/12/83
	PEA     PCHK1
	MOVE.L  SP,BESPTEMP
	MOVE.W  #1,P_STATUS                                   JS 9/12/83
	ADDQ.L  #4,SP
PCHK1   EQU     *                                             JS 9/12/83
*
	LEA     $FFFFFFC4,A0            ADDRESS PAST INTERRUPT VECTOR LEVEL 1
	LEA     INTERRUPT,A1
	MOVEQ   #6,D0                   HANDLE LEVELS 1 THRU 6
I_LOOP  MOVE.L  A1,-(A0)                MOVE JMP TO INTERRUPT VECTOR
	MOVE.W  #JMP,-(A0)
	SUBQ    #1,D0
	BNE     I_LOOP

	LEA     LEVEL7DV,A0     SETUP LEVEL 7 DEVICE VECTOR             (rdq)
	MOVE.W  #JMP,(A0)+                                              (rdq)
	MOVE.L  A1,(A0)                                                 (rdq)
* INIT VECTORS FOR HANDLING <SHIFT PAUSE> AND <CONTROL><SHIFT><PAUSE>
	MOVE.W  #JMP,LEVEL7V
	MOVE.L  $1B0,LEVEL7V+2
	MOVE.W  #JMP,KBDRESETV
	MOVE.L  #RESET_ISR,KBDRESETV+2
	MOVE.W  #JMP,CTL_RESETV
	MOVE.L  #TRYMONITOR,CTL_RESETV+2
*
	LEA     FHIVECTOR,A0    LEVEL 7 TIMER INTERRUPT VECTOR          (rdq)
	MOVE.W  #JMP,(A0)+                                              (rdq)
	MOVE.L  A1,(A0)                                                 (rdq)

	LEA     ESC,A0                  MOVE ESCAPE LINKAGE TO HIGH MEMORY
	MOVE.W  #JMP,ESCAPE
	MOVE.L  A0,ESCAPE+2

	MOVE.L  TRAP0VECTOR+2,D0        GET DEFAULT ENTRY POINT FOR TRAP #0
	AND.L   #$00FFFFFF,D0           TEST FOR MONITOR
	CMP.L   #$00880000,D0
	BGE.S   L0
	MOVE.W  #JMP,TRAP0VECTOR        SET UP EXCEPTION VECTOR FOR
	LEA     P_BREAK,A0              PASCAL LINE HEADERS
	MOVE.L  A0,TRAP0VECTOR+2

*==========

L0      MOVEM.W ESCAPE_PROTO,D1-D2      GET 6 BYTE MOVEQ #ESCCODE, JMP ESCAPE
	LEA     0,A0                    START FROM TOP OF RAM
	MOVE.W  #JMP,D0                 $4EF9   (LONG ABS JUMP)

	LEA     BUS_ERR,A1              SET UP BUS ERROR TRAP
	MOVE.L  A1,-(A0)                ADDRESS IN LAST 4 BYTES
	MOVE.W  D0,-(A0)                LONG JUMP IN FIRST 2 BYTES

	LEA     ADD_ERR,A1              SET UP ADDRESS ERROR TRAP
	MOVE.L  A1,-(A0)                ADDRESS IN LAST 4 BYTES
	MOVE.W  D0,-(A0)                LONG JUMP IN FIRST 2 BYTES

	MOVEQ   #-13,D3                 ILLEGAL INSTRUCTION, ESCAPE(-13)
	MOVEM.W D1-D3,-(A0)             MOVE 'moveq, short jump esc'

	MOVEQ   #-5,D3                  SIMILAR FOR DIVIDE BY ZERO
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-8,D3                  SIMILAR FOR CHK EXCEPTION
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-4,D3                  SIMILAR FOR TRAPV
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-14,D3                 SIMILAR FOR PRIVILEGE VIOLATION
	MOVEM.W D1-D3,-(A0)

	SUBQ.L  #6,A0                   SKIP TRACE

	MOVEQ   #-13,D3                 ILLEGAL INSTRUCTION (OPS A,F), ESCAPE(-13)
	MOVEM.W D1-D3,-(A0)             MOVE 'moveq, short jump esc'
	MOVEM.W D1-D3,-(A0)             MOVE 'moveq, short jump esc'

	LEA     $FFFFFF94,A0            CONTINUE WITH TRAP VECTORS

	LEA     LINKA6,A1               TRAP 1, LINK A6 EMULATOR
	MOVE.L  A1,-(A0)
	MOVE.W  D0,-(A0)

	MOVEQ   #-2,D3                  TRAP 2, STACK OVERFLOW
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-10,D3                 TRAP 3, I/O RESULT NOT ZERO
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-4,D3                  TRAP 4, INTEGER OVERFLOW
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-5,D3                  TRAP 5, INTEGER DIVIDE BY ZERO
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-9,D3                  TRAP 6, CASE STATEMENT ERROR
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-8,D3                  TRAP 7, VALUE RANGE ERROR
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-3,D3                  TRAP 8, NIL POINTER REFERENCE
	MOVEM.W D1-D3,-(A0)

	LEA     NLGOTO,A1               TRAP 9, NON LOCAL GOTO
	MOVE.L  A1,-(A0)
	MOVE.W  D0,-(A0)

	LEA     ESCN,A1                 TRAP 10, ESCAPE N
	MOVE.L  A1,-(A0)
	MOVE.W  D0,-(A0)
*                                       (rdq)
	SUBQ.L  #6,A0                   skip over TRAP 11 (done by ASM_POWERUP)
*
	MOVEQ   #-21,D3                 TRAP 12, UNASSIGNED
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-21,D3                 TRAP 13, UNASSIGNED
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-21,D3                 TRAP 14, UNASSIGNED
	MOVEM.W D1-D3,-(A0)

	JSR     SPURIOUS                JWH 1/18/90
	JSR     M881_ON                 ENABLE M68881 IF PRESENT
	JSR     ASM_ICACHE_ON           NOW TURN ICACHE ON        { 3/25/85 }
	RTS                             END OF VECTOR SET UP, POWER UP
*-------(rdq)------------------------------------------------------------
IGNOREBUS EQU   *
	TST.B   M68KTYPE
	BNE.S   IGNBUS1
	ADDA.L  #8,SP                 THROW AWAY STACK INFO FROM BUS ERROR
IGNBUS1 MOVE  (SP),SR                 FIX SR SO SP WILL BE CORRECT
	MOVEA.L BESPTEMP,SP
	RTS                           RETURN TO RECOVERY POINT
*-------------------------------------------------------------------------
	PAGE
*
*  ENABLE M68881 AND SETUP EXCEPTION VECTOR IF PRESENT
*      - JS 4/29/85
*
*  Note - this serves equally well for getting things set up
*  when you have a 68040, since the FPCONTROL register is
*  now on chip ... JWH 12/1/89
*
M881_ON EQU *
	MOVE.W  F_LINEV,-(SP)        SAVE OLD F-LINE VECTOR
	MOVE.L  F_LINEV+2,-(SP)
	MOVE.W  #JMP,F_LINEV         SETUP NEW VECTOR
	MOVE.L  #FLINE,F_LINEV+2
	FMOVE.L #$FC00,FPCONTROL     ENABLE THE 881 EXCEPTIONS
	MOVE.W  #JMP,M68881V         SETUP EXCEPTION VECTOR
	MOVE.L  #M881SERV,M68881V+2
*=============================================================
* Following code keeps the unsupported data type handler from
* being completely bare on the 68040. All exceptions going
* through exception 55 wind up giving "error -31 : undocumented
* error" unless the FP40 package is installed, in which case
* a better error message is displayed. JWH 2/11/91. If not
* for this you bounce into the boot rom with "UNEXPECTED USE
* OF FFFFFEE6 and the system hangs. JWH 2/11/91
	BTST    #3,SYSFLAG2          68040 ONLY 2/11/91 JWH
	BNE     M881_ON1             68040 ONLY 2/11/91 JWH
	MOVE.W  #JMP,UNSUPP          68040 ONLY 2/11/91 JWH
	MOVE.L  #M881SERV,UNSUPP+2   68040 ONLY 2/11/91 JWH
*============================================================
M881_ON1 EQU *
	MOVE.L  (SP)+,F_LINEV+2      RESTORE F-LINE VECTOR
	MOVE.W  (SP)+,F_LINEV
	RTS                          DONE WITH M68881 ENABLE

* Added 1/18/90 JWH :
*
SPURIOUS EQU *
	 MOVE.W   D0,spur_vec       assumes d0 has JMP
	 lea      outa_here,a0
	 move.l   a0,d0
	 move.l   d0,spur_vec+2
	 rts
outa_here  RTE
*
FLINE   EQU *                       NO 881 IF WE GET HERE
	MOVE.L #M881_ON1,2(SP)      ADJUST RETURN ADDR
	RTE                         AND RETURN
*
*
* M68881 Trap service routines
*     - stolen from BASIC code  JS 4/29/85
*
* Escapecodes for 68881 traps
*
errover         equ     -6                      Real overflow
errarc          equ     -30                     Arcsin, Arccos arg > 1
errlog          equ     -16                     Log of non-positive #
errill          equ     -31                     Illegal real number
errsqr          equ     -17                     SQR of negative #
errdvdz         equ     -5                      Divide by 0
errunder        equ     -7                      Real underflow
errintovr       equ     -4                      integer overflow
*
m881serv        equ     *                       68881 trap service routine
		move.w  d0,-(sp)                save regs we might use
		move.l  a0,-(sp)
		FSAVE   256             IDLE 68882 SO IT WILL DTACK
*                                       IF WE DON'T IT WON'T DTACK. SFB/RDQ/DD
		fmove.l fpstatus,d0
		btst    #12,d0
		beq.s   m881s1
		moveq   #errover,d0             68881 overflow
		bra     common881
m881s1          btst    #11,d0
		beq.s   m881s2
		move.l  #errunder,d0            68881 underflow
		bra     common881
m881s2          btst    #10,d0
		beq.s   m881s3
		fmove.l fpiaddr,a0              divide by 0, get instr addr
		move.l  (a0),d0                 get the offending instruction
		andi.b  #$7f,d0                 look at opcode
		cmpi.b  #$20,d0                 is it fdiv?
		bne.s   m881s2a
		moveq   #errdvdz,d0             escape with divide by 0 error
		bra     common881
m881s2a         moveq   #errlog,d0              68881 divide by 0
		bra     common881
m881s3          btst    #13,d0
		beq.s   m881s4
		fmove.l fpiaddr,a0              operand error, get instr addr
		move.l  (a0),d0                 get the offending instruction
		andi.b  #$7f,d0                 look at opcode
		cmpi.b  #$20,d0                 is it fdiv?
		bne.s   m881s3a
		moveq   #errdvdz,d0             escape with divide by 0 error
*                                               note: if could also be inf/inf
		bra.s   common881
m881s3a         cmpi.b  #$04,d0                 is it fsqrt?
		bne.s   m881s3b
		moveq   #errsqr,d0              escape with sqr of negative #
		bra.s   common881
m881s3b         cmpi.b  #$15,d0                 is it flog10?
		beq.s   m881s3c
		cmpi.b  #$14,d0                 is it flogn?
		bne.s   m881s3d
m881s3c         moveq   #errlog,d0              escape with log of negative #
		bra.s   common881
m881s3d         cmpi.b  #$1c,d0                 is it facos?
		beq.s   m881s3e
		cmpi.b  #$0c,d0                 is it fasin?
		bne.s   m881s3f
m881s3e         moveq   #errarc,d0              escape with asin/acos of x > 1
		bra.s   common881
*
*               The following is a special case for the Pascal compiler.
*               If fmove to an integer generates integer overflow, the 68881
*               will generate OPERR, but we want to report integer overflow.
*
m881s3f         equ     *
		tst.b   d0                      is it fmove?
		bne.s   m881s3g
		moveq   #errintovr,d0           escape with integer overflow
		bra.s   common881
m881s3g         equ     *

*       Note:  Error -31 (illegal real number) will be
*              returned for BSUN (branch or set on unordered) and for
*              invalid operands:
*                       add     +infinity with -infinity
*                       mul     0 * infinity
*                       sub     infinity
*                       div     infinity/infinity
*               These should not happen however.

m881s4          moveq   #errill,d0              68881 signaling not-a-number
*
common881       equ     *
		move.l  a5,-(sp)                save a5
		movea.l g_dollar,a5             get it setup right
		move.w  d0,sysglobals-2(a5)     set up escapecode
		movea.l (sp)+,a5
		movea.l (sp)+,a0                restore regs
		move    (sp)+,d0
		jmp     escn                    goto generic trap routine
		page

*=========================================================================
ASM_CLOSEFILES EQU *
	MOVEA.L 4(SP),A0        EVENTUAL SP
	MOVEA.L FILELISTPTR(A5),A1
	CMPA.L  A0,A1
	BCC.S   ALLDONE
	CMPA.L  SP,A1
	BCS.S   ALLDONE
	MOVE.L  4(A1),FILELISTPTR(A5)
	CLR.L   4(A1)           FLAG UNINITIALIZED
	MOVE.L  IORESULT(A5),-(SP)
	MOVE.W  ESCAPECODE(A5),-(SP)
	PEA     (A1)
	CLR.W   -(SP)           NORMAL CLOSE
	JSR     FS_FCLOSE
	MOVE.W  (SP)+,ESCAPECODE(A5)
	MOVE.L  (SP)+,IORESULT(A5)
	BRA.S   ASM_CLOSEFILES
ALLDONE MOVE.L  (SP)+,(SP)
	RTS

NLGOTO  MOVE.W  (SP)+,D0        SAVE STATUS REG
	MOVEA.L (SP)+,A0
	TST.B   M68KTYPE                                        (rdq)
	BEQ.S   NLGOTOA                                         (rdq)
	ADDQ.L  #2,SP           POP VECTOR WORD                 (rdq)
NLGOTOA MOVE    D0,SR           RESTORE USER MODE
	MOVE.W  (A0)+,D1        STATIC DELTA
	BGE.S   NLGOTO1
	MOVEA.L INITSTACK,A6    DEST IS MAIN PROG
NLGOTO1 BLE.S   NLGOTO3
NLGOTO2 MOVEA.L 8(A6),A6
	SUBQ.W  #1,D1
	BGT.S   NLGOTO2
NLGOTO3 MOVE.L  (A0),D1         DESTINATION DELTA
	PEA     0(A0,D1.L)      COMPUTE RETURN ADDRESS
*
*  Check for LEA {4fee} or MOVEA {2e4e}
*  Code is either LEA <delta.w>(a6),sp or MOVEA.L a6,sp  ADDA.L #<delta.l>,sp
*
	CMPI.W  #$4FEE,0(A0,D1.L)   BUG FIX 5/13/85 JWS
	BEQ.S   DELTA16
	MOVE.L  4(A0,D1.L),D2   SP DELTA FROM A6 { 32 BIT VALUE }
	LEA     0(A6,D2.L),A1   EVENTUAL SP
	BRA.S   NLGOTO4
DELTA16 MOVE.W  2(A0,D1.L),D2   SP DELTA FROM A6 { 16 BIT VALUE }
	LEA     0(A6,D2.W),A1   EVENTUAL SP
NLGOTO4 CMPA.L  RECOVERBLOCK(A5),A1 POP OFF TRY RECOVER BLOCKS
	BLS.S   NLGOTO5         ABOVE THE EVENTUAL SP
	MOVEA.L RECOVERBLOCK(A5),A2
	MOVE.L  8(A2),RECOVERBLOCK(A5)
	BRA.S   NLGOTO4
NLGOTO5 MOVE.L  A1,-(SP)
	JSR     ASM_CLOSEFILES  CLOSE FILES BEING POPPED OFF
	RTS

LINKA6  MOVE    (SP)+,D0        STATUS
	MOVEA.L (SP)+,A0        PC
	TST.B   M68KTYPE                                        (rdq)
	BEQ.S   LINKA6A                                         (rdq)
	ADDQ.L  #2,SP           POP VECTOR WORD                 (rdq)
LINKA6A MOVE    D0,SR           RETURN TO ORIGINAL MODE
	MOVE.L  A6,-(SP)        EMULATE LINK A6
	MOVEA.L SP,A6
	MOVEA.L SP,A3           COPY FOR SP CALC.
	MOVE.W  (A0)+,D1
	EXT.L   D1
	BLE.S   LINKW
	SWAP    D1
	MOVE.W  (A0)+,D1
	BCLR    #30,D1           **** FIX FOR 3.1b
	NEG.L   D1
LINKW   ADDA.L  D1,A3           PRE CALCULATE NEW SP

	BTST    #13,D0          WHICH MODE?
	BEQ.S   UMODE

SMODE   LEA     32766(A5),A2
	BRA.S   SCHECK
UMODE   MOVEA.L HEAPPOINTER(A5),A2

SCHECK  LEA     -STACKFUDGE(A3),A1

	CMPA.L  A2,A1   CHECK STACK OVERFLOW
	BLS.S   STACKOV
	MOVEA.L A3,SP   NOW SET NEW SP
	JMP     (A0)

STACKOV TRAP    #2              SIGNAL STACK OVERFLOW

	PAGE
******************************************************************************
*                     INTERRUPT POLLING ROUTINE: LEVELS 1-7 (rdq)            *
******************************************************************************

*
* ISRIB STRUCTURE
*
INTREGADDR      EQU     0       (LONG)          CHARPTR
INTREGMASK      EQU     4       (BYTE)          BYTE
INTREGVALUE     EQU     5       (BYTE)          BYTE
CHAINFLAG       EQU     6       (WORD)          BOOLEAN IN MSB; OTHER BITS RESERVED
PROC.ADDR       EQU     8       (LONG)          PROCEDURE ADDRESS
PROC.LINK       EQU     12      (LONG)          PROCEDURE STATIC LINK
LINK            EQU     16      (LONG)          LINK TO NEXT ISRIB

*
*  INTERRUPT POLLING ROUTINE: LEVELS 1-7                                (rdq)
*
INTERRUPT       EQU *

	MOVEM.L D0-D7/A0-A6,-(SP)       SAVE CONTEXT, 64 BYTES
	MOVEA.L G_DOLLAR,A5             SET UP THE PASCAL GLOBAL ENVIRONMENT
	MOVE.L  IORESULT(A5),-(SP)      IORESULT IS PART OF THE CONTEXT
	MOVE.W  ESCAPECODE(A5),-(SP)    THE ESCAPE CODE IS PART OF THE CONTEXT

	MOVE.L  RECOVERBLOCK(A5),-(SP)  SET UP A TRY/RECOVER BLOCK
	PEA     RECOVER
	MOVE.L  SP,RECOVERBLOCK(A5)

	MOVE    SR,D0                   FETCH THE CURRENT INTERRUPT LEVEL
	LSR     #8-2,D0                 POSITION IN THE LOWER BYTE, MULTIPLIED BY 4
	AND.W   #$1C,D0                 MASK OUT THE OTHER BITS
	LEA     INTERRUPTTABLE(A5),A0
	MOVEA.L -4(A0,D0),A0            POINT TO THE FIRST ISRIB FOR THIS LEVEL

PLOOP   MOVE.L  A0,D0                   SET THE CONDITION CODES
	BEQ.S   NOISR                   BRANCH IF THE POINTER IS NILL
	MOVEA.L A0,A1                   USE A1 FOR SCANNING THE ISRIB
	MOVEA.L (A1)+,A2                INTERRUPT REGISTER ADDRESS
	MOVE.B  (A2),D0                 INTERRUPT REGISTER CONTENTS
	AND.B   (A1)+,D0                INTERRUPT REGISTER MASK
	CMP.B   (A1)+,D0                THIS SOURCE REQUESTING AN INTERRUPT?
	BNE.S   NEXT                    BRANCH IF NOT

	CLR     (A1)+                   CLEAR THE CHAIN FLAG
	MOVE.L  A0,-(SP)                SAVE THE POINTER TO THIS ISRIB
	MOVE.L  A0,-(SP)                ALSO, THE ISR GETS IT AS A PARAMETER

	BSR.S   CALLPROC                CALL THE ISR

	MOVEA.L (SP)+,A0                RESTORE THE POINTER TO THIS ISRIB
	TST     CHAINFLAG(A0)           DID THIS ISR CHOOSE TO SERVICE THE INTERRUPT?
	BEQ.S   RESTORE                 BRANCH IF SO; OTHERWISE...

NEXT    MOVEA.L LINK(A0),A0             POINT TO THE NEXT ISRIB IN THE LINKED LIST
	BRA     PLOOP                   AND POLL IT's associated interrupt bit
	PAGE
NOISR   MOVE    SR,D0                   CHECK INTERRUPT LEVEL       JS 9/12/83
	LSR     #8,D0                                               JS 9/12/83
	ANDI    #7,D0                   MASK ALL BUT LEVEL BITS     JS 9/12/83
	CMPI    #7,D0                   IS IT AN NMI ?              JS 9/12/83
	BNE.S   NOISRB                  NO, TREAT AS BEFORE         JS 9/12/83
	JSR     P_CHECK                 PARITY ERROR?               JS 9/12/83
	BEQ.S   NOISRB                  NO, SOMETHING ELSE          JS 9/12/83
	ADDQ.L  #4,SP                   POP ISR RECOVER ADDR        JS 9/12/83
	MOVE.L  (SP)+,RECOVERBLOCK(A5)  RESTORE OLD RECOVERBLOCK    JS 9/12/83
	MOVE.W  (SP)+,ESCAPECODE(A5)    ESCAPECODE AND IORESULT     JS 9/12/83
	MOVE.L  (SP)+,IORESULT(A5)      FROM USER CONTEXT           JS 9/12/83
	MOVEM.L (SP)+,D0-D7/A0-A6       AND LOOK AS IF WE DID A     JS 9/12/83
	MOVE.W  #-28,ESCAPECODE(A5)     ESCAPE(-28) FROM THE        JS 9/12/83
	CLR.L   FAULT_ADDR              USER PROGRAM                JS 9/12/83
	BRA     ESCN                                                JS 9/12/83

NOISRB  MOVE.L  A0,-(SP)                NILL POINTER
	JSR     INITUNITS_NOISR


RESTORE ADDQ.L  #4,SP                   POP OFF THE RECOVER BLOCK ADDRESS
RECOV_1 MOVE.L  (SP)+,RECOVERBLOCK(A5)  RESTORE THE ORIGINAL RECOVER BLOCK
	MOVE.W  (SP)+,ESCAPECODE(A5)    RESTORE THE ORIGINAL ESCAPE CODE
	MOVE.L  (SP)+,IORESULT(A5)      RESTORE IORESULT
	MOVEA.L ENDISRHOOK(A5),A0       CALL ISR HOOK TO ALLOW MULTI-TASKING
	JMP     (A0)

ENDISR  MOVEM.L (SP)+,D0-D7/A0-A6       RESTORE THE ORIGINAL CONTEXT
	RTE                             END OF INTERRUPT SERVICE

CALLPROC EQU *                          PROCEDURE CALL
	MOVEA.L (A1)+,A0                PROC ADDRESS
	MOVE.L  (A1)+,D0                STATIC LINK
	BEQ.S   CALLIT                  SKIP IF THERE IS NO STATIC LINK
	  MOVEA.L (SP)+,A1              SHUFFLE RETURN ADDRESS
	  MOVE.L  D0,-(SP)              PUSH STATIC LINK ON THE STACK
	  MOVE.L  A1,-(SP)
CALLIT  JMP     (A0)                    CALL THE PROCEDURE


*
* RECOVER BLOCK ROUTINES TO CATCH ESCAPES FROM ISR'S
*
RECOV_2 MOVEQ   #70,D0                  SETUP TO ENTER DEBUGGER         (rdq)
	MOVE.W  0(SP,D0),SRTEMP         SAVE THE STATUS REGISTER        (rdq)
	MOVE.W  #$2100,0(SP,D0)         DUMMY STATUS                    (rdq)
	MOVE.L  PCTEMP,D1               SAVE THE TARGET ADDRESS         (rdq)
	MOVE.L  2(SP,D0),PCTEMP         SWITCH PCTEMP                   (rdq)
	MOVE.L  D1,2(SP,D0)                                             (rdq)
	BRA.S   RECOV_1

RECOVER CMPI.W  #-22,ESCAPECODE(A5)     TEST FOR DEBUGGER CALL
	BEQ     RECOV_2
	CMPI.W  #-28,ESCAPECODE(A5)     CHECK FOR PARITY ERROR    JS 9/12/83
	BEQ.S   RECOVRX                 SAME TREATMENT AS STOP    JS 9/12/83
	CMPI.W  #-20,ESCAPECODE(A5)     TEST FOR STOP KEY
	BNE     RECOV_1

*       STOP KEY PRESSED                SIMULATE AN ESCAPE(-20)
RECOVRX MOVE.L  (SP)+,RECOVERBLOCK(A5)  RESTORE THE ORIGINAL RECOVER BLOCK
	ADDQ.L  #2,SP                   GET RID OF SAVED ESCAPECODE
	MOVE.L  (SP)+,IORESULT(A5)      RESTORE IORESULT
	LEA     STOP,A0
RECOVERA MOVE.L A0,62(SP)     REDIRECT INTERRUPTED PROGRAM TO STOP    (rdq)

* FIX FOR 3.1 STOPKEY DURING 68881 FLOAT OP BUG--SFB 8/14/85
* THE PROBLEM IS THAT THE 68881 CAN BE EXECUTING A float INSTRUCTION WHILE
* AN INTERRUPT OCCURS. IN THAT CASE A "MID-INSTRUCTION" EXCEPTION FRAME
* WILL BE DUMPED TO ALLOW 68881 RESTART/CONTINUANCE. ONLY IN THE CASE OF
* THE STOPKEY IS THERE A PROBLEM, AS THEN WE CHANGE THE PC IN THAT FRAME
* BEFORE DOING RTE. THIS RESTARTS THE 68881, AND IF THE FETCH OF THE float
* INSTRUCTION IS NOT COMPLETE, THE FIRST FETCH AFTER RTE IS EATEN BY THE
* 68881. FIX IS TO MODIFY THE MID-INSTRUCTION FRAME (FORMAT 9) TO A NORMAL
* FORMAT 0 FRAME, WHICH IS 12 BYTES SHORTER. TO DO THIS WE MOVE THE FRAME
* (INCLUDING REGISTER COPIES FOR THE MOVEM.L) UPWARD 12 BYTES IN RAM, AND
* SET THE FORMAT TO 0 (4-BIT FIELD AT BYTE 6 OF RTE FRAME). FINALLY
* WE DO FSAVE TO STOP THE 68881 IF IT THINKS IT'S STILL PROCESSING THE
* OPCODE, AND IGNORE THE DATA DUMPED BY FSAVE.
* NOTE- ONLY WORKS FOR 68881 (NO OTHER COPROCESSOR), AND ASSUMES 144 BYTES
* AVAILABLE ON THE STACK AT ENTRY.

	MOVE.B  66(SP),D0               NEED TO DETECT EXCEPT FRAME FMT 9
	ANDI.B  #$F0,D0
	CMPI.B  #$90,D0
	BNE.S   FRAME_OK

FRAME9  EQU     *                       UNUSED LABEL--FRAME TYPE KNOWN TO BE 9
	MOVEQ   #16,D0                  GOING TO MOVE 17 LONGWORDS UP ON STACK
	LEA     68(SP),A1               POINTS TO COMMON PART OF BOTH FRAMES
	LEA     80(SP),A2               OLD STACK FRAME+REGISTERS IS 80 BYTES

MOVEFRAME EQU   *                       FASTER THAN CALLING MOVELEFT
	MOVE.L  -(A1),-(A2)
	DBRA    D0,MOVEFRAME

	ADDA.W  #12,SP                  ADUST STACK FOR SMALLER FRAME SIZE
	ANDI.W  #$0FFF,66(SP)           AND SET FORMAT CODE 0 IN UPPER NIBBLE
*                                       OF FRAME FORMAT WORD

	FSAVE   256                     FINALLY, TURN OFF 68881 BY DUMPING
*                                       ITS CONTROL INFO (WHICH IS THEN
*                                       IGNORED) ONTO BOOTROM NOW SFB

	CLR.L   -(SP)                   NULL FRAME FOR 68882 SFB
	FRESTORE (SP)+                  RESTART COPROCESSOR (68882) SFB
	FMOVE.L #$FC00,FPCONTROL        ENABLE THE 881 EXCEPTIONS SFB

FRAME_OK EQU    *                       END OF 3.1 STOP KEY/68881 FIX SFB

	MOVEA.L ENDISRHOOK(A5),A0       CALL ISR HOOK TO ALLOW MULTI-TASKING
	JMP     (A0)

STOP    TRAP    #10

ADD_ERR MOVEA.L G_DOLLAR,A5             FIX A5
	MOVE.W  #-11,ESCAPECODE(A5)     SET ESCAPE CODE
	BRA.S   BE_INFO
BUS_ERR MOVEA.L G_DOLLAR,A5             FIX A5
	MOVE.W  #-12,ESCAPECODE(A5)     SET ESCAPE CODE
BE_INFO TST.B   M68KTYPE                                                (rdq)
	BEQ     BE_INFOA                                                (rdq)
*-(rdq)-new code for 680xx -----------------------------
	MOVE.W  (SP)+,EXCP_STATUS       SAVE RELEVANT DIAGNOSTIC INFO 680xx
	MOVE.L  (SP)+,EXCP_PC
E680XX  MOVE.W  (SP)+,EXCP_VOFFSET      other 680xx EXCEPTIONS enter here
	BTST    #7,EXCP_VOFFSET         ?0XX note: bit 6 is assumed 0
	BNE     BE02
	BTST    #6,EXCP_VOFFSET         0111 ? 68040
	BEQ     NOT_07                  68040
	MOVEM.L A0/D0,BE_END-8          68040 - got a $7 frame
*========================================================================
* All the code between the '=========' lines is unique to the problem
* of performing write-backs, if needed : $7 (68040) only. JWH 12/15/89.
*
	  MOVEM.L D1-D3,32(SP)    STEAL_IT uses D1-D3
WRITE_EM  JSR    STEAL_IT         steal the bus error vector
WB2       MOVE.W 8(SP),D0         get WB2 status byte from stack
	  BTST   #7,D0            see if we have a write to perform
	  BEQ    WB3              if not, check out WB3
*
* code added for bug discovered by Steve Elbinger. Before doing
* the write implied by WB2S, make sure the transfer type was
* not MOVE16 , i.e. TT (bits 4 and 3) are not 0, 1
	  BTST   #4,D0
	  BNE    DOO_IT           bit 4 = 1 so do it
	  BTST   #3,D0            bit 4 = 0 so check bit 3
	  BNE    WB3              it was TT = 01 so don't do it
* end of code to fix that bug
*
DOO_IT    PEA    WB3              address to 'recover' to
	  MOVEA.L 28(SP),A0       address to write to, from frame
	  BTST   #6,D0
	  BEQ    TRY_AGAIN2
	  MOVE.W 34(SP),D0        bit 6 = 1, word sized write
	  MOVE.W D0,(A0)          write it
	  NOP                     forces clean $7 frame if we B.E.
	  RTS                     puts us at WB3
TRY_AGAIN2 BTST #5,D0
	   BEQ  LONG_W2
	   MOVE.W 34(SP),D0       bit 6 = 0 bit 5 = 1, byte size
	   MOVE.B D0,(A0)
	   NOP
	   RTS                    puts us at WB3
LONG_W2    MOVE.L 32(SP),D0       bit 6 = 0 bit 5 = 0, long size
	   MOVE.L D0,(A0)
	   NOP
	   ADDQ  #4,SP            RTS would put us at WB3 , no point ...
WB3        MOVE.W 6(SP),D0        get WB3 status byte from stack
	   BTST  #7,D0            write pending ?
	   BEQ   CARRY_ON         carry on if not
	   PEA   CARRY_ON         place to 'recover' to
	   MOVEA.L 20(SP),A0      address to write to from stack
	   BTST   #6,D0
	   BEQ    TRY_AGAIN3
	   MOVE.W  26(SP),D0      bit 6 = 1, word sized write
	   MOVE.W  D0,(A0)
	   NOP
	   RTS                    lands us at CARRY_ON
TRY_AGAIN3 BTST #5,D0
	   BEQ  LONG_W3
	   MOVE.W  26(SP),D0      bit 6 = 0 bit 5 = 1, byte sized write
	   MOVE.B  D0,(A0)
	   NOP
	   RTS                    lands us at carry_on
LONG_W3    MOVE.L 24(SP),D0       bit 6 = 0, bit 5 = 0, long size
	   MOVE.L D0,(A0)
	   NOP
	   ADDQ    #4,SP    RTS puts us at CARRY_ON, no point ...
CARRY_ON   JSR     RES_IT   restore the bus error vector
	   MOVEM.L 32(SP),D1-D3    STEAL_IT used D1-D3
*========================================================================
* Rest of the $7 processing is just like we didn't have to worry about
* the possibility of writing anything back ...
*
	LEA     ERR_INFO,A0             68040
	MOVEQ   #12,D0                  68040 - 13 words to pitch
BE07    MOVE.L  (SP)+,(A0)+             68040
	DBRA    D0,BE07                 68040
	MOVEM.L BE_END-8,A0/D0          68040
	BRA     ESCNA                   68040
NOT_07  BTST    #5,EXCP_VOFFSET         00?X
	BEQ     ESCNA                   000X either 0000 or 0001
* Note - 001X could be a 0011 starting with the 68040
* Both $2 and $3 frames have 6 words, however, so
* For this purpose we can treat a $3 as a $2 ...
	MOVE.L  (SP)+,ERR_PC            001X assumed to be 0010
	BRA     ESCNA
*
BE02    MOVEM.L A0/D0,BE_END-8  SAVE SCRATCH REGS
	LEA     ERR_INFO,A0     FRONT OF SAVE AREA
	MOVEQ   #2,D0           SET FOR 1001
	BTST    #4,EXCP_VOFFSET         10X?
	BEQ.S   BE04
	BTST    #5,EXCP_VOFFSET         10?1
	BEQ.S   BE06    IF 0 THEN HAVE  1001
	MOVEQ   #18,D0          1011 (LONG 68020 EXECPTION)
BE03    MOVE.L  (SP)+,(A0)+
	DBRA    D0,BE03
	MOVEM.L BE_END-8,A0/D0  RESTORE SCRATCH REGS
	MOVE.L  (SP)+,BE_END_L_20-8     SAVE LAST 2 LONG WORDS
	MOVE.L  (SP)+,BE_END_L_20-4
	BRA.S   ESCNA
*
BE04    MOVEQ   #5,D0           SET FOR 1010
	BTST    #5,EXCP_VOFFSET         10?0
	BNE     BE06
	MOVE.W  (SP)+,(A0)+     HAVE 1000 MUST BE 68010
	MOVEQ   #11,D0
BE06    MOVE.L  (SP)+,(A0)+     MOVE FROM STACK TO SAVE AREA
	DBRA    D0,BE06
	MOVEM.L BE_END-8,A0/D0  RESTORE SCRATCH REGS
	BRA.S   ESCNA

*-------------------------------------------------------
BE_INFOA MOVE.W (SP)+,BE_SSW            SAVE RELEVANT DIAGNOSTIC INFO 68000
	MOVE.L  (SP)+,BE_FAULT_ADDR
	MOVE.W  (SP)+,BE_INSTR
	BRA.S   ESCN                    THE REST IS LIKE OTHER EXCEPTIONS

ESC     MOVE.L  A5,-(SP)                SAVE A5
	MOVEA.L 4(SP),A5                GET CODE POINTER
	MOVE.W  (A5),6(SP)              SAVE CODE
	MOVEA.L G_DOLLAR,A5
	MOVE.W  6(SP),ESCAPECODE(A5)    SET ERROR CODE
	MOVEA.L (SP)+,A5                RESTORE A5
	ADDQ.L  #4,SP                   POP SCRATCH SPACE

ESCN    MOVE.W  (SP)+,EXCP_STATUS       SAVE EXCEPTION DIAGNOSTIC INFO
	MOVE.L  (SP)+,EXCP_PC
	TST.B   M68KTYPE                                                (rdq)
	BNE     E680XX                                                  (rdq)
	CLR.W   EXCP_VOFFSET                                            (rdq)
ESCNA   MOVE.L  A0,-(SP)                SAVE A0                         (rdq)
	MOVE.L  #-1,EXCP_LINE           TRY TO GET LINE #
	MOVEA.L LASTLINE,A0
	CMPI.W  #$4E40,(A0)+            TRAP 0 ?
	BNE.S   NO_LINE
	CLR.W   EXCP_LINE
	MOVE.W  (A0),EXCP_LINE+2        FOUND LINE #
NO_LINE MOVEA.L (SP)+,A0                RESTORE A0
	JSR     DEBUGESCAPE             DEBUGGER HOOK
	TRAP    #11
	ADDQ.L  #2,SP                                                   (rdq)
	MOVEA.L G_DOLLAR,A5             FIX A5

* TRY TO DETECT CASES OF INTERRUPTED SUPERVISOR CALLS DURING USER PROGRAM
	MOVEA.L RECOVERBLOCK(A5),A0
	CMPA.L  SP,A0
	BGE.S   TEST_2
	BCLR    #5,EXCP_STATUS          MOVE BACK TO USER MODE BECAUSE USER
	BRA.S   NORMAL_RECOVER            STACK IS BELOW SUPERVISOR STACK
TEST_2  CMPA.L  INITRECOVER,A0
	BNE.S   NORMAL_RECOVER
	MOVE    INITSR,EXCP_STATUS      INITSR WAS SAVED WHEN INITRECOVER WAS

NORMAL_RECOVER  EQU *
	MOVE    EXCP_STATUS,SR          RETURN TO USER MODE
	MOVE.L  RECOVERBLOCK(A5),-(SP)  GO CLOSE ALL FILES ABOVE NEW (SP)
	BSR     ASM_CLOSEFILES
	MOVEA.L RECOVERBLOCK(A5),SP     CUT BACK USER's stack
	RTS

*=====================================================================
* Next 3 added for 68040 support Jwh 12/15/89, in particular the
* problem of performing write-backs.
* The fake bus error handler : just pitch the whole exception frame
TOSS_IT        EQU *
	       ADDA  #60,SP
	       RTS
* Steals the bus error vector, puts in the fake :
STEAL_IT       EQU *
	       MOVEM.W  buserrvec,D1-D3
	       MOVE.W   #JMP,buserrvec
	       MOVE.L   #TOSS_IT,buserrvec+2
* added 9/24/90 : flush i-cache after you take over
	       trap  #11
	       CPUSHA  IC/DC     just to be sure
	       move    (SP)+,SR
	       RTS
* Restores previous bus error vector :
RES_IT         EQU *
	       MOVEM.W  D1-D3,buserrvec
	       trap #11
	       CPUSHA   IC/DC      just to be sure
	       move     (SP)+,SR
	       RTS
*=====================================================================

P_BREAK SUBQ.L  #2,2(SP)        BACKUP TO OPCODE
	MOVE.L  2(SP),LASTLINE  SAVE THE PC
	ADDQ.L  #4,2(SP)        BUMP RETURN ADDRESS TO SKIP LINE NUMBER
	RTE                     RETURN FROM TRAP #0

ESCAPE_PROTO    JSR     ESCAPE
	PAGE
*
* HANDLING LEVEL 7 KEYBOARD RESET INTERUPTS
*
MONITOR     EQU  $FF880024
KBDSTATUS   EQU  $00428003
KBDDATA     EQU  $00428001
KBDCOMMAND  EQU  $00428003
*
RESET_ISR   MOVEM.L D0-D7/A0-A6,-(SP)   SAVE REGISTERS
	    MOVE.B #$B2,KBDCOMMAND      TURN OFF INTERRUPT
	    BSR.S  GETCTRL
	    BSR.S  GETCTRL
	    BTST   #1,D1
	    BNE.S  RESETX
	    MOVEM.L     (SP)+,D0-D7/A0-A6       RESTORE REGISTERS
	    JMP    CTL_RESETV       WATCH IF OUT OF RANGE

TRYMONITOR  PEA    MONITOR
	    JSR    RTN_TO_MONITOR       WILL RETURN IF NO MONITOR
	    ADDQ   #4,SP                POP MONITOR ADDRESS     {rdq}
	    MOVEM.L D0-D7/A0-A6,-(SP)   SAVE REGISTERS
*
RESETX      EQU *
	    PEA         7                       DEBUGGER(7,0,0)
	    CLR.L       -(SP)
	    CLR.L       -(SP)
	    MOVEA.L     G_DOLLAR,A5
	    LEA         DEBUGGER(A5),A1
	    BSR         CALLPROC
	    MOVEM.L     (SP)+,D0-D7/A0-A6       RESTORE REGISTERS
	    JSR         DEBUGESCAPE             GIVE DEBUGGER ANOTHER SHOT

	    RESET                               NO DEBUGGER, GIVE UP, CLEAR I/O
	    MOVEQ       #16,D0                  WAIT 1..2 SECONDS
LP1         DBRA        D1,LP1
	    DBRA        D0,LP1
	    JSR         ASM_COPY_OFF            JWH 5/28/91
	    JSR         ASM_ICACHE_OFF           CLEAR BOTH CACHES 3/27/85
	    JSR         ASM_CACHE_OFF
	    CLR         -574                    THEN REBOOT FROM SCRATCH
	    JMP         448                     CALL BOOT ROM TO BOOT A SYSTEM
*
GETCTRL     BSR.S  STALL
	    MOVE.B #5,KBDCOMMAND
GA          BSR.S  STALL
	    BTST   #0,D0
	    BEQ    GA
	    MOVE.B KBDDATA,D1
	    AND    #$F0,D0
	    CMP    #$40,D0
	    BNE    GA
	    RTS
STALL       MOVE.B KBDSTATUS,D0
	    BTST   #1,D0
	    BNE    STALL
	    RTS
*                               SUPERCALL CODE MOVED TO ASM_POWERUP     (rdq)
*
ASM_INTLEVEL    EQU *                   FUNCTION TO RETURN INTERRUPT LEVEL
	TRAP    #11                     SHIFT TO SUPERVISOR MODE        (rdq)
	MOVE.W  (SP)+,D0                POP OFF STATUS REGISTER         (rdq)
	MOVE    D0,SR                   RETURN TO PREVIOUS MODE         (rdq)
	AND.L   #$00000700,D0           EXTRACT LEVEL
	LSR     #8,D0                   MOVE IT OVER
	MOVE.L  D0,4(SP)                RETURN INTEGER RESULT
	RTS

ASM_SETINTLEVEL   EQU *                 PROCEDURE TO SET INTERRUPT LEVEL
	MOVEA.L (SP)+,A0                RETURN ADDRESS
	MOVE.L  (SP)+,D0                INTEGER PARAMETER
	AND     #7,D0                   TAKE MOD 8 FOR SAFETY
	LSL     #8,D0                   MOVE IT OVER
	TRAP    #11                     MOVE INTO SUPERVISOR MODE
	MOVE    (SP)+,D1                GET CURRENT STATUS REGISTER
	AND     #$F8FF,D1               CLEAR CURRENT LEVEL
	OR      D1,D0                   COMBINE WITH NEW LEVEL
	MOVE    D0,SR                   RESTORE STATUS
	JMP     (A0)

	page
************************  PARITY ERROR CHECKER  **************************
*                                                                  JS 9/12/83
*     RETURNS WITH CC=EQ IF NOT PARITY ERROR,                      JS 9/12/83
*                                                                  JS 9/12/83
P_CHECK MOVEM.L D0-D1/A0,-(SP)    SAVE REGS WE WILL USE            JS 9/12/83
	MOVEA.L #-4,A0            SETUP FOR VECTOR SWAPPING        JS 9/13/83
	MOVE.L  (A0),-(SP)        SAVE OLD BERR VECTOR             JS 9/12/83
	MOVE.L  #IGNOREBUS,(A0)   SETUP DUMMY BUS ERROR VECTOR     JS 1/23/84
	MOVE.W  -(A0),-(SP)                                        JS 9/13/83
	MOVE.W  #JMP,(A0)                                          JS 9/13/83
	JSR     ASM_FLUSH_ICACHE                                   JS 3/25/85
	MOVEQ   #1,D0          ASSUME WE HAVE A PARITY ERROR       JS 9/12/83
	PEA     PBERR
	MOVE.L  SP,BESPTEMP
	MOVE.W  P_STATUS,D1    TRY TO READ STATUS WORD             JS 9/12/83
	ADDQ.L  #4,SP          IF READ OK WE HAVE PARITY ERROR     JS 9/12/83
P_CHECK1 TST    D0             DID WE HAVE A PARITY ERROR?         JS 9/12/83
	BEQ.S   P_RTS          IF NOT THEN RESTORE AND RETURN      JS 9/12/83
	MOVE.W  #0,P_STATUS    ELSE WE MUST CLEAR THE INTERRUPT    JS 9/12/83
	MOVE.W  #1,P_STATUS    AND RE-ENABLE IT                    JS 9/12/83
P_RTS   MOVE.W  (SP)+,(A0)+    RESTORE OLD BERR VECTOR             JS 9/12/83
	MOVE.L  (SP)+,(A0)                                         JS 9/13/83
	JSR     ASM_FLUSH_ICACHE                                   JS 3/25/85
	TST     D0             SET THE CC                          JS 9/12/83
	MOVEM.L (SP)+,D0-D1/A0 RESTORE REGS                        JS 9/12/83
	RTS                    AND RETURN                          JS 9/12/83
*                                                                  JS 9/12/83
PBERR   MOVEQ   #0,D0          CLEAR D0 -- NO PARITY ERR           JS 9/12/83
	JMP     P_CHECK1       AND RETURN FROM BUS ERR ROUTINE     JS 1/23/84
	PAGE
*************************** TIMER JUNK ***************************************

	def     init_timer      initialize timer: call at powerup/scratch a
	def     check_timer     call after ~1ms to check w/ bpl
	def     delay_timer     wait for x microseconds
	def     asm_ticker      read timer in itcs

	smode   sysflag2

timer_present   equ     1               1 if there is a timer, 0 if not


sysflag2        equ     $fffffeda
buserrvec       equ     $fffffffa       bus error vector


*************************************************************************
* look_for_timer
*   Determine if you have a timer chip on the processor board.
*   Try to read from the status register of the chip and see if you get
*   a bus error.
*************************************************************************

look_for_timer equ *
	move.l  buserrvec+2,-(sp)       save old bus error vector
	move.w  buserrvec,-(sp)
	move.w  #$4ef9,buserrvec
	move.l  #ignorebus,buserrvec+2  point buserr vector to service routine
	pea     buserr_serv
	move.l  sp,besptemp
	tst.b   $5f8003                 test for the timer
	addq.l  #4,sp
	bclr    #timer_present,sysflag2 there is a timer
	bra.s   skip1

buserr_serv equ *
	bset    #timer_present,sysflag2 there is no timer

skip1   move.w  (sp)+,buserrvec         restore original bus error vector
	move.l  (sp)+,buserrvec+2
	rts

*************************************************************************
* init_timer                            initialize the timer
*   outputs enabled
*   no interrupts
*   continuous operating mode
*   16 bit for counter 1 and 2, 8 bit for counter 3
*   external clock source
*   divide by 8 (temporary)
*
*   CR1         x000000r
*   CR2         x000000a
*   CR3         10000101
*     x - don't care
*     r - counter reset
*     a - address bit (selects CR1 or CR3)
*************************************************************************

init_timer equ *
	bsr     look_for_timer          look for hardware timer
	btst    #timer_present,sysflag2 if hardware timer present
	bne.s   itskp
	lea     $5f8000,a0              a0 = address of timer
	move.b  #$00,3(a0)              address CR3
	move.b  #$84,1(a0)              set up CR3    ($84 for no divide by 8)
	move.b  #$01,3(a0)              set up CR2 (address CR1)
	move.b  #$01,1(a0)              set up CR1, stop timer
	move.b  #$ff,9(a0)              set timer 2 to $ffff
	move.b  #$ff,11(a0)
	move.b  #$ff,13(a0)             set timer 3 to $ffff
	move.b  #$ff,15(a0)
	move.b  #$00,1(a0)              start timer
itskp   rts

*************************************************************************
* asm_ticker   function ticker:integer
*       sp+4 is the long word to contain the current timer value
*
*************************************************************************
asm_ticker equ *
	clr.l   4(sp)                   default value
	btst    #timer_present,sysflag2 if hardware timer present
	bne.s   rtskp2
	lea     $5f8000,a0              address of timer counter 2
	movep.l 9(a0),d0                read counter 2 and 3
	movep.l 9(a0),d1                read them again
	eor.l   d0,d1                   see if the upper word has changed
	swap    d1
	tst.w   d1
	beq.s   rtskp1
	   swap    d1
	   eor.l   d1,d0                use second reading if MSW has changed
rtskp1  move.l  d0,4(sp)
rtskp2  rts
*************************************************************************
* check_timer                           check the timer
*                                 Assumes timer is present!!
*
*   sp+4 contains a pointer to the timer control data structure:
*           timer_control_var: long word
*           first_time: boolean  (first byte after timer_control_var)
*     if first_time then timer_control_var contains the timeout in milliseconds
*     if not first_time then timer_control_var contains timeout clock image
*   use bpl or bmi to check for timeout (bpl will branch if not timed out yet)
*
*************************************************************************

check_timer equ *

	movem.l d0-d1/a0,-(sp)          save registers
*                                       read timer
	lea     $5f8000,a0              address of timer counter 2
	movep.l 9(a0),d0                read counter 2 and 3
	movep.l 9(a0),d1                read them again
	eor.l   d0,d1                   see if the upper word has changed
	swap    d1
	tst.w   d1
	beq.s   ctskp1
	   swap    d1
	   eor.l   d1,d0                use second reading if MSW has changed

ctskp1  equ     *                       timer value in d0
	movea.l 16(sp),a0               a0 = ^timeout value
	move.l  12(sp),16(sp)           move up return address
	tst.b   4(a0)                   first_time?
	bne     setup_timer             branch if first_time
	   cmp.l   (a0),d0              check for timeout (test with bpl)
	   movem.l (sp)+,d0-d1/a0       restore registers
	   addq.l  #4,sp                fix up stack
	   rts

setup_timer equ *
	move.l  (a0),d1                 d1 = delay in milliseconds
	lsl.l   #6,d1                   multiply by 250
	sub.l   (a0),d1
	lsl.l   #1,d1
	sub.l   (a0),d1
	lsl.l   #1,d1                   d1 = delay in tics (1 tic = 4 us)
	sub.l   d1,d0                   d0 = timeout value
	move.l  d0,(a0)+                store timeout value at a0^
	clr.b   (a0)                    first_time = false
	movem.l (sp)+,d0-d1/a0          restore registers
	addq.l  #4,sp                   fix up stack
	rts

*************************************************************************
* delay_timer                           wait for specified amount of time
*   sp+4 contains the amount of time to wait in microseconds (long integer)
*************************************************************************

delay_timer  equ  *
	movem.l d0-d1/a0,-(sp)
	btst    #timer_present,sysflag2 check for hardware timer

* Use the timer to measure delay.
* There is 218 cycles of overhead in addition to the timer amount.
* It takes 351 cycles to go through the routine once.

	bne.s   dlskp2
	lea     $5f8000,a0              address of timer
	movep.l 9(a0),d0                read counter 2 and 3
	movep.l 9(a0),d1                read them again
	eor.l   d0,d1                   see if the upper word has changed
	swap    d1
	tst.w   d1
	beq.s   dlskp1
	swap    d1
	eor.l   d1,d0                   use second reading if MSW has changed
dlskp1  move.l  16(sp),d1               d1 = delay in microseconds
	lsr.l   #2,d1                   d1 = delay in tics (1 tic = 4 us)
	subq.l  #3,d1                   subtract overhead outside timing loop
	sub.l   d1,d0                   d0 = timeout value

dlloop1 movep.l 9(a0),d1                read counter 2 and 3
	cmp.l   d0,d1                   compare timer value to timeout value
	bpl.s   dlloop1
	movem.l (sp)+,d0-d1/a0
	move.l  (sp)+,(sp)
	rts

* Use timing loop if no timer is present.
* Number of cycles = 230+31n

dlskp2  move.l  16(sp),d1               d1 = delay in microseconds
	lsr.l   #2,d1                   d1 = number of loops (1 loop = 4 us)
	subq.l  #7,d1                   subtract overhead outside loop (230/31)
dlloop2 subq.l  #1,d1                   timing loop
	nop
	nop
	bpl.s   dlloop2
	movem.l (sp)+,d0-d1/a0
	move.l  (sp)+,(sp)              pop parameter
	rts


	page
*       TRAPS:

*       ADDRESS         TRAP    ESCAPECODE      USUAL MEANING

*       $FFFFFF3A       15      (NONE)          DEBUGGER
*       $FFFFFF40       14      -21             UNASSIGNED
*       $FFFFFF46       13      -21             UNASSIGNED
*       $FFFFFF4C       12      -21             UNASSIGNED
*       $FFFFFF52       11      (NONE)          SUPERVISOR MODE
*       $FFFFFF58       10      "N"             ESCAPE N
*       $FFFFFF5E       9       (NONE)          NON LOCAL GOTO
*       $FFFFFF64       8        -3             DEREFERENCE NIL POINTER
*       $FFFFFF6A       7        -8             VALUE RANGE ERROR
*       $FFFFFF70       6        -9             CASE STATEMENT ERROR
*       $FFFFFF76       5        -5             DIVIDE BY ZERO
*       $FFFFFF7C       4        -4             INTEGER OVERFLOW
*       $FFFFFF82       3       -10             IORESULT <> 0
*       $FFFFFF88       2        -2             STACK OVERFLOW
*       $FFFFFF8E       1       (-2 IF ANY)     LINK A6 EMULATOR WITH STACK CHECK
*       $FFFFFF94       0       (NONE)          PASCAL LINE BREAKPOINT


*       SYSTEM EXCEPTIONS:

*       ADDRESS                 ESCAPECODE      USUAL MEANING

*       $FFFFFFC4               -13             1111 OPCODE
*       $FFFFFFCA               -13             1010 OPCODE
*       $FFFFFFD0               (NONE)          TRACE
*       $FFFFFFD6               -14             PRIVILEGE VIOLATION
*       $FFFFFFDC                -4             INTEGER OVERFLOW (TRAPV)
*       $FFFFFFE2                -8             CHK INSTRUCTION
*       $FFFFFFE8                -5             DIVIDE BY ZERO (HARDWARE)
*       $FFFFFFEE               -13             ILLEGAL INSTRUCTION
*       $FFFFFFF4               -11             ADDRESS ERROR
*       $FFFFFFFA               -12             BUS ERROR

	NOSYMS
	END .
@


56.2
log
@
pws2rcs automatic delta on Wed Jan 27 11:57:27 MST 1993
@
text
@d1 1276
@


56.1
log
@Automatic bump of revision number for PWS version 3.25
@
text
@a0 1276
*
*       INTERRUPT, TRAP, AND EXCEPTION HANDLER
*
*    (rdq) changes for Rev 3.0
*
*     CHANGES FOR PARITY SUPPORT  -- JS 9/12/83
*     Changes for 68040 support - JWH 12/1/89
*     Each line has 68040 as a comment.
*
	DEF     ASM_SETINTLEVEL,ASM_INTLEVEL
	DEF     ASM_INITVECTS,RESETX,ASM_CLOSEFILES
	DEF     EXCP_PC,EXCP_LINE
	DEF     GRAPHICSBASE,GRAPHICSFLAG,ALPHAFLAG,FLTPTHDW
	DEF     INITSTACK                                     JS 20 JUN 85
	DEF     ERR_INFO                                      RQ 18/Jan/84

	REFA    SYSGLOBALS,LOADER,STACKFUDGE,ASM_CACHE_ON
	REFA    ASM_FLUSH_ICACHE,ASM_ICACHE_ON                3/25/85
	REFA    ASM_ICACHE_OFF,ASM_CACHE_OFF,ASM_COPY_OFF
	REFR    FS_FCLOSE,INITUNITS_NOISR,INITLOAD_INITLOAD
	LMODE   FS_FCLOSE,INITUNITS_NOISR,INITLOAD_INITLOAD
	LMODE   ASM_CACHE_ON
	LMODE   ASM_FLUSH_ICACHE,ASM_ICACHE_ON                3/25/85
	LMODE   ASM_ICACHE_OFF,ASM_CACHE_OFF
	LMODE   SPUR_VEC,OUTA_HERE
	SMODE   ESCAPE

*THE FOLLOWING OFFSETS ARE RELATIVE TO SYSGLOBALS(A5)

ESCAPECODE      EQU SYSGLOBALS-2          (A5)
FILELISTPTR     EQU SYSGLOBALS-6          (A5)
RECOVERBLOCK    EQU SYSGLOBALS-10         (A5)
HEAPPOINTER     EQU SYSGLOBALS-14         (A5)
HEAPBASE        EQU SYSGLOBALS-18         (A5)
IORESULT        EQU SYSGLOBALS-22         (A5)
INTERRUPTTABLE  EQU SYSGLOBALS-62         (A5) ADDRESS OF INTERRUPTTABLE[1..7]
ENDISRHOOK      EQU SYSGLOBALS-66         (A5) ADDRESS OF END OF ISR ROUTINE
DEBUGGER        EQU SYSGLOBALS-276        (A5) DEBUGGER HOOK
CLEARIOHOOK     EQU SYSGLOBALS-284        (A5) CLEAR I/O HOOK
SYSDEFS         EQU LOADER-70             (A5) LINKED LIST OF PERMANT PROGRAMS
NIL             EQU 0

HIGHMEM         EQU $FFFFFB00   LEAVES ROOM FOR VECTORS, MONITOR STUFF, ETC.
TRAP0VECTOR     EQU $FFFFFF94   LOCATION OF EXCEPTION VECTOR FOR TRAP #0
*
LEVEL7V         EQU $FFFFFF9A   NMI
LEVEL7DV        EQU $FFFFFF22   LEVEL 7 DEVICE VECTOR                   (rdq)
KBDRESETV       EQU $FFFFFF34   KEY BOARD <SHIFT PAUSE VECTOR>
FHIVECTOR       EQU $FFFFFF2E   KEY BOARD LEVEL 7 TIMER INTERRUPT       (rdq)
*
F_LINEV         EQU $FFFFFFC4   TRAP FOR F-LINE INSTRUCTIONS
M68881V         EQU $FFFFFEE0   TRAP FOR 68881 EXCEPTIONS
UNSUPP          EQU $FFFFFEE6   68040 only
SPUR_VEC        EQU $FFFFFF1C   SPURIOUS INTERRUPT VECTOR
*
LOWMEM          EQU $FFFFFDCE   LOCATION IN BOOT ROM OF LOWEST RAM
RTN_TO_MONITOR  EQU $1A0        ENTRY POINT IN BOOT ROM
G_OFF_MEM       EQU $538000     GRAPHICS OFF
ALPHA_MEM       EQU $512000     ALPHA MEMORY
*
P_STATUS        EQU $5B0000     PARITY STATUS REG                  JS 9/12/83
*
*
* MAGIC NUMBERS, see alse FILES ASM, DEBUGGER and INITBUG
*
ERR_INFO        EQU HIGHMEM
FAULT_ADDR      EQU HIGHMEM     PARITY ERROR ADDRESS
*                                       68000
BE_SSW          EQU     HIGHMEM         SPECIAL STATUS WORD
BE_FAULT_ADDR   EQU     BE_SSW+2        FAULT ADDRESS
BE_INSTR        EQU     BE_FAULT_ADDR+4 INSTRUCTION BUFFER
*
*                                       68010
*BE_SSW         2 BYTES                 VECTOR TYPE 1000
*BE_FAULT_ADDR  4 BYTES
BE_PAD1_10      EQU     BE_FAULT_ADDR+4
BE_DATAO_10     EQU     BE_PAD1_10+2    DATA INPUT BUFFER
BE_PAD2_10      EQU     BE_DATAO_10+2
BE_DATAI_10     EQU     BE_PAD2_10+2    DATA OUTPUT BUFFER
BE_PAD3_10      EQU     BE_DATAI_10+2
BE_INSTR_10     EQU     BE_PAD3_10+2    INSTRUCTION BUFFER
BE_MISC_10      EQU     BE_INSTR_10+2   16 WORDS
BE_END_10       EQU     BE_MISC_10+32
*
*                                       68020
ERR_PC          EQU     HIGHMEM         VECTOR TYPE 0010
*ERR_PC         4 BYTES                 VECTOR TYPE 1001
ERR_WRD1        EQU     ERR_PC+4
ERR_WRD2        EQU     ERR_WRD1+2
ERR_EA          EQU     ERR_WRD2+2      EVALUATED ADDRESS
*BE_SSW         4 BYTES                 VECTOR TYPE 1010 (SHORT BUS ERROR)
BE_IPSC         EQU     BE_SSW+4        I PIPE C
BE_IPSB         EQU     BE_IPSC+2       I PIPE B
BE_PAD2_20      EQU     BE_IPSB+2
BE_FAULT_ADDR20 EQU     BE_PAD2_20+4
BE_DATA_20      EQU     BE_FAULT_ADDR20+4       DATA BUFFER
BE_MISCS_20     EQU     BE_DATA_20+4    4 BYTES
BE_END_S_20     EQU     BE_MISCS_20+4
*
*BE_SSW         4 BYTES                 VECTOR TYPE 1011 (LONG BUS ERROR)
*BE_IPSC        2 BYTES
*BE_IPSB        2 BYTES
*BE_PAD         4 BYTES
*BE_FAULT_ADDR  4 BYTES
*BE_DATAO       4 BYTES
BE_PAD3_20      EQU     BE_DATA_20+4            16 BYTES
BE_DATAI_20     EQU     BE_PAD3_20+16
BE_MISC20_20    EQU     BE_DATAI_20+4           44 BYTES
BE_END_L_20     EQU     BE_MISC20_20+44
BE_END          EQU     BE_END_L_20
*--------------------------------------------------------------------------
EXCP_STATUS     EQU BE_END
EXCP_PC         EQU EXCP_STATUS+2
EXCP_VOFFSET    EQU EXCP_PC+4           VECTOR WORD FOR 680xx           (rdq)
EXCP_LINE       EQU EXCP_VOFFSET+2                                      (rdq)
LASTLINE        EQU EXCP_LINE+4
ESCAPE          EQU LASTLINE+4
PCTEMP          EQU ESCAPE+6
SRTEMP          EQU PCTEMP+4
INITSTACK       EQU SRTEMP+2
INITPC          EQU INITSTACK+4
INITRECOVER     EQU INITPC+4
G_DOLLAR        EQU INITRECOVER+4
CTL_RESETV      EQU G_DOLLAR+4          KEY BOARD <CONTROL><SHIFT><PAUSE> VECTOR
DEBUGESCAPE     EQU CTL_RESETV+6
BESPTEMP        EQU DEBUGESCAPE+6       USED IN IGNOREBUS
ALPHAFLAG       EQU BESPTEMP+4
GRAPHICSFLAG    EQU ALPHAFLAG+1
GRAPHICSBASE    EQU GRAPHICSFLAG+1
INITSR          EQU GRAPHICSBASE+4
M68KTYPE        EQU INITSR+2    PROCESSOR TYPE 0=68000 else 680xx       (rdq)
MSYSFLAGS       EQU M68KTYPE+1  MORE SYSFLAGS BIT 0 = CACHE PRESENT/ABSENT
FLTPTHDW        EQU MSYSFLAGS+1
FILLER          EQU FLTPTHDW+1  UNUSED

JMP     EQU $4EF9                       LONG ABSOLUTE JMP OPCODE


	RORG 0

*
* NOTE -- ALL CACHES SHOULD BE OFF AT THIS TIME
*
ASM_INITVECTS   EQU *                   MAIN PROGRAM POWER UP LOCATION
	CLR.B   FLTPTHDW        SHOW NO FLOATING POINT HARDWARE

	MOVEQ   #$FFFFFFFF,D0           HIGHEST POSSIBLE ADDRESS
	MOVE.L  D0,FILELISTPTR(A5)
	MOVE.W  #$4E75,DEBUGESCAPE
	CLR.L   LASTLINE
	MOVE.L  #ENDISR,ENDISRHOOK(A5)  SET UP ORDINARY RETURN FROM ISR's

	jsr     init_timer      checks for and turns on timer   (rdq)

*                               TURN OFF GRAPHICS
	MOVEA.L #G_OFF_MEM,A0   GET MEM ADDRESS
	MOVE.L  A0,GRAPHICSBASE SAVE IT IN GLOBAL AREA
	CLR.B   GRAPHICSFLAG    MARK IT TURNED OFF

	LEA     IGNOREBUS,A1    SET BUS ERROR VECTOR
	MOVE.L  A1,-4
	MOVE.W  #JMP,-6
	PEA     GRPH1
	MOVE.L  SP,BESPTEMP
	MOVE    (A0),D0         TURN OFF GRAPHICS
	ADDQ.L  #4,SP
GRPH1   EQU     *
	MOVE.B  #1,ALPHAFLAG    MARK ALPHA TURNED ON
*
*    TURN ON CACHE IF WE HAVE ONE
*
CACHE_CTL EQU   $5F400E
	CLR.B   MSYSFLAGS       CLEAR FLAGS BYTE
	PEA     CACHE1
	MOVE.L  SP,BESPTEMP
	TST.W   CACHE_CTL       TEST
	ADDQ.L  #4,SP
	BSET    #0,MSYSFLAGS    CACHE EXISTS
	MOVE    #0,CACHE_CTL    CLEAR THE CONTROL WORD
	JSR     ASM_CACHE_ON
CACHE1  EQU     *
*
*    TURN ON PARITY BOARDS IF ANY                             JS 9/12/83
*                                                             JS 9/12/83
	PEA     PCHK1
	MOVE.L  SP,BESPTEMP
	MOVE.W  #1,P_STATUS                                   JS 9/12/83
	ADDQ.L  #4,SP
PCHK1   EQU     *                                             JS 9/12/83
*
	LEA     $FFFFFFC4,A0            ADDRESS PAST INTERRUPT VECTOR LEVEL 1
	LEA     INTERRUPT,A1
	MOVEQ   #6,D0                   HANDLE LEVELS 1 THRU 6
I_LOOP  MOVE.L  A1,-(A0)                MOVE JMP TO INTERRUPT VECTOR
	MOVE.W  #JMP,-(A0)
	SUBQ    #1,D0
	BNE     I_LOOP

	LEA     LEVEL7DV,A0     SETUP LEVEL 7 DEVICE VECTOR             (rdq)
	MOVE.W  #JMP,(A0)+                                              (rdq)
	MOVE.L  A1,(A0)                                                 (rdq)
* INIT VECTORS FOR HANDLING <SHIFT PAUSE> AND <CONTROL><SHIFT><PAUSE>
	MOVE.W  #JMP,LEVEL7V
	MOVE.L  $1B0,LEVEL7V+2
	MOVE.W  #JMP,KBDRESETV
	MOVE.L  #RESET_ISR,KBDRESETV+2
	MOVE.W  #JMP,CTL_RESETV
	MOVE.L  #TRYMONITOR,CTL_RESETV+2
*
	LEA     FHIVECTOR,A0    LEVEL 7 TIMER INTERRUPT VECTOR          (rdq)
	MOVE.W  #JMP,(A0)+                                              (rdq)
	MOVE.L  A1,(A0)                                                 (rdq)

	LEA     ESC,A0                  MOVE ESCAPE LINKAGE TO HIGH MEMORY
	MOVE.W  #JMP,ESCAPE
	MOVE.L  A0,ESCAPE+2

	MOVE.L  TRAP0VECTOR+2,D0        GET DEFAULT ENTRY POINT FOR TRAP #0
	AND.L   #$00FFFFFF,D0           TEST FOR MONITOR
	CMP.L   #$00880000,D0
	BGE.S   L0
	MOVE.W  #JMP,TRAP0VECTOR        SET UP EXCEPTION VECTOR FOR
	LEA     P_BREAK,A0              PASCAL LINE HEADERS
	MOVE.L  A0,TRAP0VECTOR+2

*==========

L0      MOVEM.W ESCAPE_PROTO,D1-D2      GET 6 BYTE MOVEQ #ESCCODE, JMP ESCAPE
	LEA     0,A0                    START FROM TOP OF RAM
	MOVE.W  #JMP,D0                 $4EF9   (LONG ABS JUMP)

	LEA     BUS_ERR,A1              SET UP BUS ERROR TRAP
	MOVE.L  A1,-(A0)                ADDRESS IN LAST 4 BYTES
	MOVE.W  D0,-(A0)                LONG JUMP IN FIRST 2 BYTES

	LEA     ADD_ERR,A1              SET UP ADDRESS ERROR TRAP
	MOVE.L  A1,-(A0)                ADDRESS IN LAST 4 BYTES
	MOVE.W  D0,-(A0)                LONG JUMP IN FIRST 2 BYTES

	MOVEQ   #-13,D3                 ILLEGAL INSTRUCTION, ESCAPE(-13)
	MOVEM.W D1-D3,-(A0)             MOVE 'moveq, short jump esc'

	MOVEQ   #-5,D3                  SIMILAR FOR DIVIDE BY ZERO
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-8,D3                  SIMILAR FOR CHK EXCEPTION
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-4,D3                  SIMILAR FOR TRAPV
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-14,D3                 SIMILAR FOR PRIVILEGE VIOLATION
	MOVEM.W D1-D3,-(A0)

	SUBQ.L  #6,A0                   SKIP TRACE

	MOVEQ   #-13,D3                 ILLEGAL INSTRUCTION (OPS A,F), ESCAPE(-13)
	MOVEM.W D1-D3,-(A0)             MOVE 'moveq, short jump esc'
	MOVEM.W D1-D3,-(A0)             MOVE 'moveq, short jump esc'

	LEA     $FFFFFF94,A0            CONTINUE WITH TRAP VECTORS

	LEA     LINKA6,A1               TRAP 1, LINK A6 EMULATOR
	MOVE.L  A1,-(A0)
	MOVE.W  D0,-(A0)

	MOVEQ   #-2,D3                  TRAP 2, STACK OVERFLOW
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-10,D3                 TRAP 3, I/O RESULT NOT ZERO
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-4,D3                  TRAP 4, INTEGER OVERFLOW
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-5,D3                  TRAP 5, INTEGER DIVIDE BY ZERO
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-9,D3                  TRAP 6, CASE STATEMENT ERROR
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-8,D3                  TRAP 7, VALUE RANGE ERROR
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-3,D3                  TRAP 8, NIL POINTER REFERENCE
	MOVEM.W D1-D3,-(A0)

	LEA     NLGOTO,A1               TRAP 9, NON LOCAL GOTO
	MOVE.L  A1,-(A0)
	MOVE.W  D0,-(A0)

	LEA     ESCN,A1                 TRAP 10, ESCAPE N
	MOVE.L  A1,-(A0)
	MOVE.W  D0,-(A0)
*                                       (rdq)
	SUBQ.L  #6,A0                   skip over TRAP 11 (done by ASM_POWERUP)
*
	MOVEQ   #-21,D3                 TRAP 12, UNASSIGNED
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-21,D3                 TRAP 13, UNASSIGNED
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-21,D3                 TRAP 14, UNASSIGNED
	MOVEM.W D1-D3,-(A0)

	JSR     SPURIOUS                JWH 1/18/90
	JSR     M881_ON                 ENABLE M68881 IF PRESENT
	JSR     ASM_ICACHE_ON           NOW TURN ICACHE ON        { 3/25/85 }
	RTS                             END OF VECTOR SET UP, POWER UP
*-------(rdq)------------------------------------------------------------
IGNOREBUS EQU   *
	TST.B   M68KTYPE
	BNE.S   IGNBUS1
	ADDA.L  #8,SP                 THROW AWAY STACK INFO FROM BUS ERROR
IGNBUS1 MOVE  (SP),SR                 FIX SR SO SP WILL BE CORRECT
	MOVEA.L BESPTEMP,SP
	RTS                           RETURN TO RECOVERY POINT
*-------------------------------------------------------------------------
	PAGE
*
*  ENABLE M68881 AND SETUP EXCEPTION VECTOR IF PRESENT
*      - JS 4/29/85
*
*  Note - this serves equally well for getting things set up
*  when you have a 68040, since the FPCONTROL register is
*  now on chip ... JWH 12/1/89
*
M881_ON EQU *
	MOVE.W  F_LINEV,-(SP)        SAVE OLD F-LINE VECTOR
	MOVE.L  F_LINEV+2,-(SP)
	MOVE.W  #JMP,F_LINEV         SETUP NEW VECTOR
	MOVE.L  #FLINE,F_LINEV+2
	FMOVE.L #$FC00,FPCONTROL     ENABLE THE 881 EXCEPTIONS
	MOVE.W  #JMP,M68881V         SETUP EXCEPTION VECTOR
	MOVE.L  #M881SERV,M68881V+2
*=============================================================
* Following code keeps the unsupported data type handler from
* being completely bare on the 68040. All exceptions going
* through exception 55 wind up giving "error -31 : undocumented
* error" unless the FP40 package is installed, in which case
* a better error message is displayed. JWH 2/11/91. If not
* for this you bounce into the boot rom with "UNEXPECTED USE
* OF FFFFFEE6 and the system hangs. JWH 2/11/91
	BTST    #3,SYSFLAG2          68040 ONLY 2/11/91 JWH
	BNE     M881_ON1             68040 ONLY 2/11/91 JWH
	MOVE.W  #JMP,UNSUPP          68040 ONLY 2/11/91 JWH
	MOVE.L  #M881SERV,UNSUPP+2   68040 ONLY 2/11/91 JWH
*============================================================
M881_ON1 EQU *
	MOVE.L  (SP)+,F_LINEV+2      RESTORE F-LINE VECTOR
	MOVE.W  (SP)+,F_LINEV
	RTS                          DONE WITH M68881 ENABLE

* Added 1/18/90 JWH :
*
SPURIOUS EQU *
	 MOVE.W   D0,spur_vec       assumes d0 has JMP
	 lea      outa_here,a0
	 move.l   a0,d0
	 move.l   d0,spur_vec+2
	 rts
outa_here  RTE
*
FLINE   EQU *                       NO 881 IF WE GET HERE
	MOVE.L #M881_ON1,2(SP)      ADJUST RETURN ADDR
	RTE                         AND RETURN
*
*
* M68881 Trap service routines
*     - stolen from BASIC code  JS 4/29/85
*
* Escapecodes for 68881 traps
*
errover         equ     -6                      Real overflow
errarc          equ     -30                     Arcsin, Arccos arg > 1
errlog          equ     -16                     Log of non-positive #
errill          equ     -31                     Illegal real number
errsqr          equ     -17                     SQR of negative #
errdvdz         equ     -5                      Divide by 0
errunder        equ     -7                      Real underflow
errintovr       equ     -4                      integer overflow
*
m881serv        equ     *                       68881 trap service routine
		move.w  d0,-(sp)                save regs we might use
		move.l  a0,-(sp)
		FSAVE   256             IDLE 68882 SO IT WILL DTACK
*                                       IF WE DON'T IT WON'T DTACK. SFB/RDQ/DD
		fmove.l fpstatus,d0
		btst    #12,d0
		beq.s   m881s1
		moveq   #errover,d0             68881 overflow
		bra     common881
m881s1          btst    #11,d0
		beq.s   m881s2
		move.l  #errunder,d0            68881 underflow
		bra     common881
m881s2          btst    #10,d0
		beq.s   m881s3
		fmove.l fpiaddr,a0              divide by 0, get instr addr
		move.l  (a0),d0                 get the offending instruction
		andi.b  #$7f,d0                 look at opcode
		cmpi.b  #$20,d0                 is it fdiv?
		bne.s   m881s2a
		moveq   #errdvdz,d0             escape with divide by 0 error
		bra     common881
m881s2a         moveq   #errlog,d0              68881 divide by 0
		bra     common881
m881s3          btst    #13,d0
		beq.s   m881s4
		fmove.l fpiaddr,a0              operand error, get instr addr
		move.l  (a0),d0                 get the offending instruction
		andi.b  #$7f,d0                 look at opcode
		cmpi.b  #$20,d0                 is it fdiv?
		bne.s   m881s3a
		moveq   #errdvdz,d0             escape with divide by 0 error
*                                               note: if could also be inf/inf
		bra.s   common881
m881s3a         cmpi.b  #$04,d0                 is it fsqrt?
		bne.s   m881s3b
		moveq   #errsqr,d0              escape with sqr of negative #
		bra.s   common881
m881s3b         cmpi.b  #$15,d0                 is it flog10?
		beq.s   m881s3c
		cmpi.b  #$14,d0                 is it flogn?
		bne.s   m881s3d
m881s3c         moveq   #errlog,d0              escape with log of negative #
		bra.s   common881
m881s3d         cmpi.b  #$1c,d0                 is it facos?
		beq.s   m881s3e
		cmpi.b  #$0c,d0                 is it fasin?
		bne.s   m881s3f
m881s3e         moveq   #errarc,d0              escape with asin/acos of x > 1
		bra.s   common881
*
*               The following is a special case for the Pascal compiler.
*               If fmove to an integer generates integer overflow, the 68881
*               will generate OPERR, but we want to report integer overflow.
*
m881s3f         equ     *
		tst.b   d0                      is it fmove?
		bne.s   m881s3g
		moveq   #errintovr,d0           escape with integer overflow
		bra.s   common881
m881s3g         equ     *

*       Note:  Error -31 (illegal real number) will be
*              returned for BSUN (branch or set on unordered) and for
*              invalid operands:
*                       add     +infinity with -infinity
*                       mul     0 * infinity
*                       sub     infinity
*                       div     infinity/infinity
*               These should not happen however.

m881s4          moveq   #errill,d0              68881 signaling not-a-number
*
common881       equ     *
		move.l  a5,-(sp)                save a5
		movea.l g_dollar,a5             get it setup right
		move.w  d0,sysglobals-2(a5)     set up escapecode
		movea.l (sp)+,a5
		movea.l (sp)+,a0                restore regs
		move    (sp)+,d0
		jmp     escn                    goto generic trap routine
		page

*=========================================================================
ASM_CLOSEFILES EQU *
	MOVEA.L 4(SP),A0        EVENTUAL SP
	MOVEA.L FILELISTPTR(A5),A1
	CMPA.L  A0,A1
	BCC.S   ALLDONE
	CMPA.L  SP,A1
	BCS.S   ALLDONE
	MOVE.L  4(A1),FILELISTPTR(A5)
	CLR.L   4(A1)           FLAG UNINITIALIZED
	MOVE.L  IORESULT(A5),-(SP)
	MOVE.W  ESCAPECODE(A5),-(SP)
	PEA     (A1)
	CLR.W   -(SP)           NORMAL CLOSE
	JSR     FS_FCLOSE
	MOVE.W  (SP)+,ESCAPECODE(A5)
	MOVE.L  (SP)+,IORESULT(A5)
	BRA.S   ASM_CLOSEFILES
ALLDONE MOVE.L  (SP)+,(SP)
	RTS

NLGOTO  MOVE.W  (SP)+,D0        SAVE STATUS REG
	MOVEA.L (SP)+,A0
	TST.B   M68KTYPE                                        (rdq)
	BEQ.S   NLGOTOA                                         (rdq)
	ADDQ.L  #2,SP           POP VECTOR WORD                 (rdq)
NLGOTOA MOVE    D0,SR           RESTORE USER MODE
	MOVE.W  (A0)+,D1        STATIC DELTA
	BGE.S   NLGOTO1
	MOVEA.L INITSTACK,A6    DEST IS MAIN PROG
NLGOTO1 BLE.S   NLGOTO3
NLGOTO2 MOVEA.L 8(A6),A6
	SUBQ.W  #1,D1
	BGT.S   NLGOTO2
NLGOTO3 MOVE.L  (A0),D1         DESTINATION DELTA
	PEA     0(A0,D1.L)      COMPUTE RETURN ADDRESS
*
*  Check for LEA {4fee} or MOVEA {2e4e}
*  Code is either LEA <delta.w>(a6),sp or MOVEA.L a6,sp  ADDA.L #<delta.l>,sp
*
	CMPI.W  #$4FEE,0(A0,D1.L)   BUG FIX 5/13/85 JWS
	BEQ.S   DELTA16
	MOVE.L  4(A0,D1.L),D2   SP DELTA FROM A6 { 32 BIT VALUE }
	LEA     0(A6,D2.L),A1   EVENTUAL SP
	BRA.S   NLGOTO4
DELTA16 MOVE.W  2(A0,D1.L),D2   SP DELTA FROM A6 { 16 BIT VALUE }
	LEA     0(A6,D2.W),A1   EVENTUAL SP
NLGOTO4 CMPA.L  RECOVERBLOCK(A5),A1 POP OFF TRY RECOVER BLOCKS
	BLS.S   NLGOTO5         ABOVE THE EVENTUAL SP
	MOVEA.L RECOVERBLOCK(A5),A2
	MOVE.L  8(A2),RECOVERBLOCK(A5)
	BRA.S   NLGOTO4
NLGOTO5 MOVE.L  A1,-(SP)
	JSR     ASM_CLOSEFILES  CLOSE FILES BEING POPPED OFF
	RTS

LINKA6  MOVE    (SP)+,D0        STATUS
	MOVEA.L (SP)+,A0        PC
	TST.B   M68KTYPE                                        (rdq)
	BEQ.S   LINKA6A                                         (rdq)
	ADDQ.L  #2,SP           POP VECTOR WORD                 (rdq)
LINKA6A MOVE    D0,SR           RETURN TO ORIGINAL MODE
	MOVE.L  A6,-(SP)        EMULATE LINK A6
	MOVEA.L SP,A6
	MOVEA.L SP,A3           COPY FOR SP CALC.
	MOVE.W  (A0)+,D1
	EXT.L   D1
	BLE.S   LINKW
	SWAP    D1
	MOVE.W  (A0)+,D1
	BCLR    #30,D1           **** FIX FOR 3.1b
	NEG.L   D1
LINKW   ADDA.L  D1,A3           PRE CALCULATE NEW SP

	BTST    #13,D0          WHICH MODE?
	BEQ.S   UMODE

SMODE   LEA     32766(A5),A2
	BRA.S   SCHECK
UMODE   MOVEA.L HEAPPOINTER(A5),A2

SCHECK  LEA     -STACKFUDGE(A3),A1

	CMPA.L  A2,A1   CHECK STACK OVERFLOW
	BLS.S   STACKOV
	MOVEA.L A3,SP   NOW SET NEW SP
	JMP     (A0)

STACKOV TRAP    #2              SIGNAL STACK OVERFLOW

	PAGE
******************************************************************************
*                     INTERRUPT POLLING ROUTINE: LEVELS 1-7 (rdq)            *
******************************************************************************

*
* ISRIB STRUCTURE
*
INTREGADDR      EQU     0       (LONG)          CHARPTR
INTREGMASK      EQU     4       (BYTE)          BYTE
INTREGVALUE     EQU     5       (BYTE)          BYTE
CHAINFLAG       EQU     6       (WORD)          BOOLEAN IN MSB; OTHER BITS RESERVED
PROC.ADDR       EQU     8       (LONG)          PROCEDURE ADDRESS
PROC.LINK       EQU     12      (LONG)          PROCEDURE STATIC LINK
LINK            EQU     16      (LONG)          LINK TO NEXT ISRIB

*
*  INTERRUPT POLLING ROUTINE: LEVELS 1-7                                (rdq)
*
INTERRUPT       EQU *

	MOVEM.L D0-D7/A0-A6,-(SP)       SAVE CONTEXT, 64 BYTES
	MOVEA.L G_DOLLAR,A5             SET UP THE PASCAL GLOBAL ENVIRONMENT
	MOVE.L  IORESULT(A5),-(SP)      IORESULT IS PART OF THE CONTEXT
	MOVE.W  ESCAPECODE(A5),-(SP)    THE ESCAPE CODE IS PART OF THE CONTEXT

	MOVE.L  RECOVERBLOCK(A5),-(SP)  SET UP A TRY/RECOVER BLOCK
	PEA     RECOVER
	MOVE.L  SP,RECOVERBLOCK(A5)

	MOVE    SR,D0                   FETCH THE CURRENT INTERRUPT LEVEL
	LSR     #8-2,D0                 POSITION IN THE LOWER BYTE, MULTIPLIED BY 4
	AND.W   #$1C,D0                 MASK OUT THE OTHER BITS
	LEA     INTERRUPTTABLE(A5),A0
	MOVEA.L -4(A0,D0),A0            POINT TO THE FIRST ISRIB FOR THIS LEVEL

PLOOP   MOVE.L  A0,D0                   SET THE CONDITION CODES
	BEQ.S   NOISR                   BRANCH IF THE POINTER IS NILL
	MOVEA.L A0,A1                   USE A1 FOR SCANNING THE ISRIB
	MOVEA.L (A1)+,A2                INTERRUPT REGISTER ADDRESS
	MOVE.B  (A2),D0                 INTERRUPT REGISTER CONTENTS
	AND.B   (A1)+,D0                INTERRUPT REGISTER MASK
	CMP.B   (A1)+,D0                THIS SOURCE REQUESTING AN INTERRUPT?
	BNE.S   NEXT                    BRANCH IF NOT

	CLR     (A1)+                   CLEAR THE CHAIN FLAG
	MOVE.L  A0,-(SP)                SAVE THE POINTER TO THIS ISRIB
	MOVE.L  A0,-(SP)                ALSO, THE ISR GETS IT AS A PARAMETER

	BSR.S   CALLPROC                CALL THE ISR

	MOVEA.L (SP)+,A0                RESTORE THE POINTER TO THIS ISRIB
	TST     CHAINFLAG(A0)           DID THIS ISR CHOOSE TO SERVICE THE INTERRUPT?
	BEQ.S   RESTORE                 BRANCH IF SO; OTHERWISE...

NEXT    MOVEA.L LINK(A0),A0             POINT TO THE NEXT ISRIB IN THE LINKED LIST
	BRA     PLOOP                   AND POLL IT's associated interrupt bit
	PAGE
NOISR   MOVE    SR,D0                   CHECK INTERRUPT LEVEL       JS 9/12/83
	LSR     #8,D0                                               JS 9/12/83
	ANDI    #7,D0                   MASK ALL BUT LEVEL BITS     JS 9/12/83
	CMPI    #7,D0                   IS IT AN NMI ?              JS 9/12/83
	BNE.S   NOISRB                  NO, TREAT AS BEFORE         JS 9/12/83
	JSR     P_CHECK                 PARITY ERROR?               JS 9/12/83
	BEQ.S   NOISRB                  NO, SOMETHING ELSE          JS 9/12/83
	ADDQ.L  #4,SP                   POP ISR RECOVER ADDR        JS 9/12/83
	MOVE.L  (SP)+,RECOVERBLOCK(A5)  RESTORE OLD RECOVERBLOCK    JS 9/12/83
	MOVE.W  (SP)+,ESCAPECODE(A5)    ESCAPECODE AND IORESULT     JS 9/12/83
	MOVE.L  (SP)+,IORESULT(A5)      FROM USER CONTEXT           JS 9/12/83
	MOVEM.L (SP)+,D0-D7/A0-A6       AND LOOK AS IF WE DID A     JS 9/12/83
	MOVE.W  #-28,ESCAPECODE(A5)     ESCAPE(-28) FROM THE        JS 9/12/83
	CLR.L   FAULT_ADDR              USER PROGRAM                JS 9/12/83
	BRA     ESCN                                                JS 9/12/83

NOISRB  MOVE.L  A0,-(SP)                NILL POINTER
	JSR     INITUNITS_NOISR


RESTORE ADDQ.L  #4,SP                   POP OFF THE RECOVER BLOCK ADDRESS
RECOV_1 MOVE.L  (SP)+,RECOVERBLOCK(A5)  RESTORE THE ORIGINAL RECOVER BLOCK
	MOVE.W  (SP)+,ESCAPECODE(A5)    RESTORE THE ORIGINAL ESCAPE CODE
	MOVE.L  (SP)+,IORESULT(A5)      RESTORE IORESULT
	MOVEA.L ENDISRHOOK(A5),A0       CALL ISR HOOK TO ALLOW MULTI-TASKING
	JMP     (A0)

ENDISR  MOVEM.L (SP)+,D0-D7/A0-A6       RESTORE THE ORIGINAL CONTEXT
	RTE                             END OF INTERRUPT SERVICE

CALLPROC EQU *                          PROCEDURE CALL
	MOVEA.L (A1)+,A0                PROC ADDRESS
	MOVE.L  (A1)+,D0                STATIC LINK
	BEQ.S   CALLIT                  SKIP IF THERE IS NO STATIC LINK
	  MOVEA.L (SP)+,A1              SHUFFLE RETURN ADDRESS
	  MOVE.L  D0,-(SP)              PUSH STATIC LINK ON THE STACK
	  MOVE.L  A1,-(SP)
CALLIT  JMP     (A0)                    CALL THE PROCEDURE


*
* RECOVER BLOCK ROUTINES TO CATCH ESCAPES FROM ISR'S
*
RECOV_2 MOVEQ   #70,D0                  SETUP TO ENTER DEBUGGER         (rdq)
	MOVE.W  0(SP,D0),SRTEMP         SAVE THE STATUS REGISTER        (rdq)
	MOVE.W  #$2100,0(SP,D0)         DUMMY STATUS                    (rdq)
	MOVE.L  PCTEMP,D1               SAVE THE TARGET ADDRESS         (rdq)
	MOVE.L  2(SP,D0),PCTEMP         SWITCH PCTEMP                   (rdq)
	MOVE.L  D1,2(SP,D0)                                             (rdq)
	BRA.S   RECOV_1

RECOVER CMPI.W  #-22,ESCAPECODE(A5)     TEST FOR DEBUGGER CALL
	BEQ     RECOV_2
	CMPI.W  #-28,ESCAPECODE(A5)     CHECK FOR PARITY ERROR    JS 9/12/83
	BEQ.S   RECOVRX                 SAME TREATMENT AS STOP    JS 9/12/83
	CMPI.W  #-20,ESCAPECODE(A5)     TEST FOR STOP KEY
	BNE     RECOV_1

*       STOP KEY PRESSED                SIMULATE AN ESCAPE(-20)
RECOVRX MOVE.L  (SP)+,RECOVERBLOCK(A5)  RESTORE THE ORIGINAL RECOVER BLOCK
	ADDQ.L  #2,SP                   GET RID OF SAVED ESCAPECODE
	MOVE.L  (SP)+,IORESULT(A5)      RESTORE IORESULT
	LEA     STOP,A0
RECOVERA MOVE.L A0,62(SP)     REDIRECT INTERRUPTED PROGRAM TO STOP    (rdq)

* FIX FOR 3.1 STOPKEY DURING 68881 FLOAT OP BUG--SFB 8/14/85
* THE PROBLEM IS THAT THE 68881 CAN BE EXECUTING A float INSTRUCTION WHILE
* AN INTERRUPT OCCURS. IN THAT CASE A "MID-INSTRUCTION" EXCEPTION FRAME
* WILL BE DUMPED TO ALLOW 68881 RESTART/CONTINUANCE. ONLY IN THE CASE OF
* THE STOPKEY IS THERE A PROBLEM, AS THEN WE CHANGE THE PC IN THAT FRAME
* BEFORE DOING RTE. THIS RESTARTS THE 68881, AND IF THE FETCH OF THE float
* INSTRUCTION IS NOT COMPLETE, THE FIRST FETCH AFTER RTE IS EATEN BY THE
* 68881. FIX IS TO MODIFY THE MID-INSTRUCTION FRAME (FORMAT 9) TO A NORMAL
* FORMAT 0 FRAME, WHICH IS 12 BYTES SHORTER. TO DO THIS WE MOVE THE FRAME
* (INCLUDING REGISTER COPIES FOR THE MOVEM.L) UPWARD 12 BYTES IN RAM, AND
* SET THE FORMAT TO 0 (4-BIT FIELD AT BYTE 6 OF RTE FRAME). FINALLY
* WE DO FSAVE TO STOP THE 68881 IF IT THINKS IT'S STILL PROCESSING THE
* OPCODE, AND IGNORE THE DATA DUMPED BY FSAVE.
* NOTE- ONLY WORKS FOR 68881 (NO OTHER COPROCESSOR), AND ASSUMES 144 BYTES
* AVAILABLE ON THE STACK AT ENTRY.

	MOVE.B  66(SP),D0               NEED TO DETECT EXCEPT FRAME FMT 9
	ANDI.B  #$F0,D0
	CMPI.B  #$90,D0
	BNE.S   FRAME_OK

FRAME9  EQU     *                       UNUSED LABEL--FRAME TYPE KNOWN TO BE 9
	MOVEQ   #16,D0                  GOING TO MOVE 17 LONGWORDS UP ON STACK
	LEA     68(SP),A1               POINTS TO COMMON PART OF BOTH FRAMES
	LEA     80(SP),A2               OLD STACK FRAME+REGISTERS IS 80 BYTES

MOVEFRAME EQU   *                       FASTER THAN CALLING MOVELEFT
	MOVE.L  -(A1),-(A2)
	DBRA    D0,MOVEFRAME

	ADDA.W  #12,SP                  ADUST STACK FOR SMALLER FRAME SIZE
	ANDI.W  #$0FFF,66(SP)           AND SET FORMAT CODE 0 IN UPPER NIBBLE
*                                       OF FRAME FORMAT WORD

	FSAVE   256                     FINALLY, TURN OFF 68881 BY DUMPING
*                                       ITS CONTROL INFO (WHICH IS THEN
*                                       IGNORED) ONTO BOOTROM NOW SFB

	CLR.L   -(SP)                   NULL FRAME FOR 68882 SFB
	FRESTORE (SP)+                  RESTART COPROCESSOR (68882) SFB
	FMOVE.L #$FC00,FPCONTROL        ENABLE THE 881 EXCEPTIONS SFB

FRAME_OK EQU    *                       END OF 3.1 STOP KEY/68881 FIX SFB

	MOVEA.L ENDISRHOOK(A5),A0       CALL ISR HOOK TO ALLOW MULTI-TASKING
	JMP     (A0)

STOP    TRAP    #10

ADD_ERR MOVEA.L G_DOLLAR,A5             FIX A5
	MOVE.W  #-11,ESCAPECODE(A5)     SET ESCAPE CODE
	BRA.S   BE_INFO
BUS_ERR MOVEA.L G_DOLLAR,A5             FIX A5
	MOVE.W  #-12,ESCAPECODE(A5)     SET ESCAPE CODE
BE_INFO TST.B   M68KTYPE                                                (rdq)
	BEQ     BE_INFOA                                                (rdq)
*-(rdq)-new code for 680xx -----------------------------
	MOVE.W  (SP)+,EXCP_STATUS       SAVE RELEVANT DIAGNOSTIC INFO 680xx
	MOVE.L  (SP)+,EXCP_PC
E680XX  MOVE.W  (SP)+,EXCP_VOFFSET      other 680xx EXCEPTIONS enter here
	BTST    #7,EXCP_VOFFSET         ?0XX note: bit 6 is assumed 0
	BNE     BE02
	BTST    #6,EXCP_VOFFSET         0111 ? 68040
	BEQ     NOT_07                  68040
	MOVEM.L A0/D0,BE_END-8          68040 - got a $7 frame
*========================================================================
* All the code between the '=========' lines is unique to the problem
* of performing write-backs, if needed : $7 (68040) only. JWH 12/15/89.
*
	  MOVEM.L D1-D3,32(SP)    STEAL_IT uses D1-D3
WRITE_EM  JSR    STEAL_IT         steal the bus error vector
WB2       MOVE.W 8(SP),D0         get WB2 status byte from stack
	  BTST   #7,D0            see if we have a write to perform
	  BEQ    WB3              if not, check out WB3
*
* code added for bug discovered by Steve Elbinger. Before doing
* the write implied by WB2S, make sure the transfer type was
* not MOVE16 , i.e. TT (bits 4 and 3) are not 0, 1
	  BTST   #4,D0
	  BNE    DOO_IT           bit 4 = 1 so do it
	  BTST   #3,D0            bit 4 = 0 so check bit 3
	  BNE    WB3              it was TT = 01 so don't do it
* end of code to fix that bug
*
DOO_IT    PEA    WB3              address to 'recover' to
	  MOVEA.L 28(SP),A0       address to write to, from frame
	  BTST   #6,D0
	  BEQ    TRY_AGAIN2
	  MOVE.W 34(SP),D0        bit 6 = 1, word sized write
	  MOVE.W D0,(A0)          write it
	  NOP                     forces clean $7 frame if we B.E.
	  RTS                     puts us at WB3
TRY_AGAIN2 BTST #5,D0
	   BEQ  LONG_W2
	   MOVE.W 34(SP),D0       bit 6 = 0 bit 5 = 1, byte size
	   MOVE.B D0,(A0)
	   NOP
	   RTS                    puts us at WB3
LONG_W2    MOVE.L 32(SP),D0       bit 6 = 0 bit 5 = 0, long size
	   MOVE.L D0,(A0)
	   NOP
	   ADDQ  #4,SP            RTS would put us at WB3 , no point ...
WB3        MOVE.W 6(SP),D0        get WB3 status byte from stack
	   BTST  #7,D0            write pending ?
	   BEQ   CARRY_ON         carry on if not
	   PEA   CARRY_ON         place to 'recover' to
	   MOVEA.L 20(SP),A0      address to write to from stack
	   BTST   #6,D0
	   BEQ    TRY_AGAIN3
	   MOVE.W  26(SP),D0      bit 6 = 1, word sized write
	   MOVE.W  D0,(A0)
	   NOP
	   RTS                    lands us at CARRY_ON
TRY_AGAIN3 BTST #5,D0
	   BEQ  LONG_W3
	   MOVE.W  26(SP),D0      bit 6 = 0 bit 5 = 1, byte sized write
	   MOVE.B  D0,(A0)
	   NOP
	   RTS                    lands us at carry_on
LONG_W3    MOVE.L 24(SP),D0       bit 6 = 0, bit 5 = 0, long size
	   MOVE.L D0,(A0)
	   NOP
	   ADDQ    #4,SP    RTS puts us at CARRY_ON, no point ...
CARRY_ON   JSR     RES_IT   restore the bus error vector
	   MOVEM.L 32(SP),D1-D3    STEAL_IT used D1-D3
*========================================================================
* Rest of the $7 processing is just like we didn't have to worry about
* the possibility of writing anything back ...
*
	LEA     ERR_INFO,A0             68040
	MOVEQ   #12,D0                  68040 - 13 words to pitch
BE07    MOVE.L  (SP)+,(A0)+             68040
	DBRA    D0,BE07                 68040
	MOVEM.L BE_END-8,A0/D0          68040
	BRA     ESCNA                   68040
NOT_07  BTST    #5,EXCP_VOFFSET         00?X
	BEQ     ESCNA                   000X either 0000 or 0001
* Note - 001X could be a 0011 starting with the 68040
* Both $2 and $3 frames have 6 words, however, so
* For this purpose we can treat a $3 as a $2 ...
	MOVE.L  (SP)+,ERR_PC            001X assumed to be 0010
	BRA     ESCNA
*
BE02    MOVEM.L A0/D0,BE_END-8  SAVE SCRATCH REGS
	LEA     ERR_INFO,A0     FRONT OF SAVE AREA
	MOVEQ   #2,D0           SET FOR 1001
	BTST    #4,EXCP_VOFFSET         10X?
	BEQ.S   BE04
	BTST    #5,EXCP_VOFFSET         10?1
	BEQ.S   BE06    IF 0 THEN HAVE  1001
	MOVEQ   #18,D0          1011 (LONG 68020 EXECPTION)
BE03    MOVE.L  (SP)+,(A0)+
	DBRA    D0,BE03
	MOVEM.L BE_END-8,A0/D0  RESTORE SCRATCH REGS
	MOVE.L  (SP)+,BE_END_L_20-8     SAVE LAST 2 LONG WORDS
	MOVE.L  (SP)+,BE_END_L_20-4
	BRA.S   ESCNA
*
BE04    MOVEQ   #5,D0           SET FOR 1010
	BTST    #5,EXCP_VOFFSET         10?0
	BNE     BE06
	MOVE.W  (SP)+,(A0)+     HAVE 1000 MUST BE 68010
	MOVEQ   #11,D0
BE06    MOVE.L  (SP)+,(A0)+     MOVE FROM STACK TO SAVE AREA
	DBRA    D0,BE06
	MOVEM.L BE_END-8,A0/D0  RESTORE SCRATCH REGS
	BRA.S   ESCNA

*-------------------------------------------------------
BE_INFOA MOVE.W (SP)+,BE_SSW            SAVE RELEVANT DIAGNOSTIC INFO 68000
	MOVE.L  (SP)+,BE_FAULT_ADDR
	MOVE.W  (SP)+,BE_INSTR
	BRA.S   ESCN                    THE REST IS LIKE OTHER EXCEPTIONS

ESC     MOVE.L  A5,-(SP)                SAVE A5
	MOVEA.L 4(SP),A5                GET CODE POINTER
	MOVE.W  (A5),6(SP)              SAVE CODE
	MOVEA.L G_DOLLAR,A5
	MOVE.W  6(SP),ESCAPECODE(A5)    SET ERROR CODE
	MOVEA.L (SP)+,A5                RESTORE A5
	ADDQ.L  #4,SP                   POP SCRATCH SPACE

ESCN    MOVE.W  (SP)+,EXCP_STATUS       SAVE EXCEPTION DIAGNOSTIC INFO
	MOVE.L  (SP)+,EXCP_PC
	TST.B   M68KTYPE                                                (rdq)
	BNE     E680XX                                                  (rdq)
	CLR.W   EXCP_VOFFSET                                            (rdq)
ESCNA   MOVE.L  A0,-(SP)                SAVE A0                         (rdq)
	MOVE.L  #-1,EXCP_LINE           TRY TO GET LINE #
	MOVEA.L LASTLINE,A0
	CMPI.W  #$4E40,(A0)+            TRAP 0 ?
	BNE.S   NO_LINE
	CLR.W   EXCP_LINE
	MOVE.W  (A0),EXCP_LINE+2        FOUND LINE #
NO_LINE MOVEA.L (SP)+,A0                RESTORE A0
	JSR     DEBUGESCAPE             DEBUGGER HOOK
	TRAP    #11
	ADDQ.L  #2,SP                                                   (rdq)
	MOVEA.L G_DOLLAR,A5             FIX A5

* TRY TO DETECT CASES OF INTERRUPTED SUPERVISOR CALLS DURING USER PROGRAM
	MOVEA.L RECOVERBLOCK(A5),A0
	CMPA.L  SP,A0
	BGE.S   TEST_2
	BCLR    #5,EXCP_STATUS          MOVE BACK TO USER MODE BECAUSE USER
	BRA.S   NORMAL_RECOVER            STACK IS BELOW SUPERVISOR STACK
TEST_2  CMPA.L  INITRECOVER,A0
	BNE.S   NORMAL_RECOVER
	MOVE    INITSR,EXCP_STATUS      INITSR WAS SAVED WHEN INITRECOVER WAS

NORMAL_RECOVER  EQU *
	MOVE    EXCP_STATUS,SR          RETURN TO USER MODE
	MOVE.L  RECOVERBLOCK(A5),-(SP)  GO CLOSE ALL FILES ABOVE NEW (SP)
	BSR     ASM_CLOSEFILES
	MOVEA.L RECOVERBLOCK(A5),SP     CUT BACK USER's stack
	RTS

*=====================================================================
* Next 3 added for 68040 support Jwh 12/15/89, in particular the
* problem of performing write-backs.
* The fake bus error handler : just pitch the whole exception frame
TOSS_IT        EQU *
	       ADDA  #60,SP
	       RTS
* Steals the bus error vector, puts in the fake :
STEAL_IT       EQU *
	       MOVEM.W  buserrvec,D1-D3
	       MOVE.W   #JMP,buserrvec
	       MOVE.L   #TOSS_IT,buserrvec+2
* added 9/24/90 : flush i-cache after you take over
	       trap  #11
	       CPUSHA  IC/DC     just to be sure
	       move    (SP)+,SR
	       RTS
* Restores previous bus error vector :
RES_IT         EQU *
	       MOVEM.W  D1-D3,buserrvec
	       trap #11
	       CPUSHA   IC/DC      just to be sure
	       move     (SP)+,SR
	       RTS
*=====================================================================

P_BREAK SUBQ.L  #2,2(SP)        BACKUP TO OPCODE
	MOVE.L  2(SP),LASTLINE  SAVE THE PC
	ADDQ.L  #4,2(SP)        BUMP RETURN ADDRESS TO SKIP LINE NUMBER
	RTE                     RETURN FROM TRAP #0

ESCAPE_PROTO    JSR     ESCAPE
	PAGE
*
* HANDLING LEVEL 7 KEYBOARD RESET INTERUPTS
*
MONITOR     EQU  $FF880024
KBDSTATUS   EQU  $00428003
KBDDATA     EQU  $00428001
KBDCOMMAND  EQU  $00428003
*
RESET_ISR   MOVEM.L D0-D7/A0-A6,-(SP)   SAVE REGISTERS
	    MOVE.B #$B2,KBDCOMMAND      TURN OFF INTERRUPT
	    BSR.S  GETCTRL
	    BSR.S  GETCTRL
	    BTST   #1,D1
	    BNE.S  RESETX
	    MOVEM.L     (SP)+,D0-D7/A0-A6       RESTORE REGISTERS
	    JMP    CTL_RESETV       WATCH IF OUT OF RANGE

TRYMONITOR  PEA    MONITOR
	    JSR    RTN_TO_MONITOR       WILL RETURN IF NO MONITOR
	    ADDQ   #4,SP                POP MONITOR ADDRESS     {rdq}
	    MOVEM.L D0-D7/A0-A6,-(SP)   SAVE REGISTERS
*
RESETX      EQU *
	    PEA         7                       DEBUGGER(7,0,0)
	    CLR.L       -(SP)
	    CLR.L       -(SP)
	    MOVEA.L     G_DOLLAR,A5
	    LEA         DEBUGGER(A5),A1
	    BSR         CALLPROC
	    MOVEM.L     (SP)+,D0-D7/A0-A6       RESTORE REGISTERS
	    JSR         DEBUGESCAPE             GIVE DEBUGGER ANOTHER SHOT

	    RESET                               NO DEBUGGER, GIVE UP, CLEAR I/O
	    MOVEQ       #16,D0                  WAIT 1..2 SECONDS
LP1         DBRA        D1,LP1
	    DBRA        D0,LP1
	    JSR         ASM_COPY_OFF            JWH 5/28/91
	    JSR         ASM_ICACHE_OFF           CLEAR BOTH CACHES 3/27/85
	    JSR         ASM_CACHE_OFF
	    CLR         -574                    THEN REBOOT FROM SCRATCH
	    JMP         448                     CALL BOOT ROM TO BOOT A SYSTEM
*
GETCTRL     BSR.S  STALL
	    MOVE.B #5,KBDCOMMAND
GA          BSR.S  STALL
	    BTST   #0,D0
	    BEQ    GA
	    MOVE.B KBDDATA,D1
	    AND    #$F0,D0
	    CMP    #$40,D0
	    BNE    GA
	    RTS
STALL       MOVE.B KBDSTATUS,D0
	    BTST   #1,D0
	    BNE    STALL
	    RTS
*                               SUPERCALL CODE MOVED TO ASM_POWERUP     (rdq)
*
ASM_INTLEVEL    EQU *                   FUNCTION TO RETURN INTERRUPT LEVEL
	TRAP    #11                     SHIFT TO SUPERVISOR MODE        (rdq)
	MOVE.W  (SP)+,D0                POP OFF STATUS REGISTER         (rdq)
	MOVE    D0,SR                   RETURN TO PREVIOUS MODE         (rdq)
	AND.L   #$00000700,D0           EXTRACT LEVEL
	LSR     #8,D0                   MOVE IT OVER
	MOVE.L  D0,4(SP)                RETURN INTEGER RESULT
	RTS

ASM_SETINTLEVEL   EQU *                 PROCEDURE TO SET INTERRUPT LEVEL
	MOVEA.L (SP)+,A0                RETURN ADDRESS
	MOVE.L  (SP)+,D0                INTEGER PARAMETER
	AND     #7,D0                   TAKE MOD 8 FOR SAFETY
	LSL     #8,D0                   MOVE IT OVER
	TRAP    #11                     MOVE INTO SUPERVISOR MODE
	MOVE    (SP)+,D1                GET CURRENT STATUS REGISTER
	AND     #$F8FF,D1               CLEAR CURRENT LEVEL
	OR      D1,D0                   COMBINE WITH NEW LEVEL
	MOVE    D0,SR                   RESTORE STATUS
	JMP     (A0)

	page
************************  PARITY ERROR CHECKER  **************************
*                                                                  JS 9/12/83
*     RETURNS WITH CC=EQ IF NOT PARITY ERROR,                      JS 9/12/83
*                                                                  JS 9/12/83
P_CHECK MOVEM.L D0-D1/A0,-(SP)    SAVE REGS WE WILL USE            JS 9/12/83
	MOVEA.L #-4,A0            SETUP FOR VECTOR SWAPPING        JS 9/13/83
	MOVE.L  (A0),-(SP)        SAVE OLD BERR VECTOR             JS 9/12/83
	MOVE.L  #IGNOREBUS,(A0)   SETUP DUMMY BUS ERROR VECTOR     JS 1/23/84
	MOVE.W  -(A0),-(SP)                                        JS 9/13/83
	MOVE.W  #JMP,(A0)                                          JS 9/13/83
	JSR     ASM_FLUSH_ICACHE                                   JS 3/25/85
	MOVEQ   #1,D0          ASSUME WE HAVE A PARITY ERROR       JS 9/12/83
	PEA     PBERR
	MOVE.L  SP,BESPTEMP
	MOVE.W  P_STATUS,D1    TRY TO READ STATUS WORD             JS 9/12/83
	ADDQ.L  #4,SP          IF READ OK WE HAVE PARITY ERROR     JS 9/12/83
P_CHECK1 TST    D0             DID WE HAVE A PARITY ERROR?         JS 9/12/83
	BEQ.S   P_RTS          IF NOT THEN RESTORE AND RETURN      JS 9/12/83
	MOVE.W  #0,P_STATUS    ELSE WE MUST CLEAR THE INTERRUPT    JS 9/12/83
	MOVE.W  #1,P_STATUS    AND RE-ENABLE IT                    JS 9/12/83
P_RTS   MOVE.W  (SP)+,(A0)+    RESTORE OLD BERR VECTOR             JS 9/12/83
	MOVE.L  (SP)+,(A0)                                         JS 9/13/83
	JSR     ASM_FLUSH_ICACHE                                   JS 3/25/85
	TST     D0             SET THE CC                          JS 9/12/83
	MOVEM.L (SP)+,D0-D1/A0 RESTORE REGS                        JS 9/12/83
	RTS                    AND RETURN                          JS 9/12/83
*                                                                  JS 9/12/83
PBERR   MOVEQ   #0,D0          CLEAR D0 -- NO PARITY ERR           JS 9/12/83
	JMP     P_CHECK1       AND RETURN FROM BUS ERR ROUTINE     JS 1/23/84
	PAGE
*************************** TIMER JUNK ***************************************

	def     init_timer      initialize timer: call at powerup/scratch a
	def     check_timer     call after ~1ms to check w/ bpl
	def     delay_timer     wait for x microseconds
	def     asm_ticker      read timer in itcs

	smode   sysflag2

timer_present   equ     1               1 if there is a timer, 0 if not


sysflag2        equ     $fffffeda
buserrvec       equ     $fffffffa       bus error vector


*************************************************************************
* look_for_timer
*   Determine if you have a timer chip on the processor board.
*   Try to read from the status register of the chip and see if you get
*   a bus error.
*************************************************************************

look_for_timer equ *
	move.l  buserrvec+2,-(sp)       save old bus error vector
	move.w  buserrvec,-(sp)
	move.w  #$4ef9,buserrvec
	move.l  #ignorebus,buserrvec+2  point buserr vector to service routine
	pea     buserr_serv
	move.l  sp,besptemp
	tst.b   $5f8003                 test for the timer
	addq.l  #4,sp
	bclr    #timer_present,sysflag2 there is a timer
	bra.s   skip1

buserr_serv equ *
	bset    #timer_present,sysflag2 there is no timer

skip1   move.w  (sp)+,buserrvec         restore original bus error vector
	move.l  (sp)+,buserrvec+2
	rts

*************************************************************************
* init_timer                            initialize the timer
*   outputs enabled
*   no interrupts
*   continuous operating mode
*   16 bit for counter 1 and 2, 8 bit for counter 3
*   external clock source
*   divide by 8 (temporary)
*
*   CR1         x000000r
*   CR2         x000000a
*   CR3         10000101
*     x - don't care
*     r - counter reset
*     a - address bit (selects CR1 or CR3)
*************************************************************************

init_timer equ *
	bsr     look_for_timer          look for hardware timer
	btst    #timer_present,sysflag2 if hardware timer present
	bne.s   itskp
	lea     $5f8000,a0              a0 = address of timer
	move.b  #$00,3(a0)              address CR3
	move.b  #$84,1(a0)              set up CR3    ($84 for no divide by 8)
	move.b  #$01,3(a0)              set up CR2 (address CR1)
	move.b  #$01,1(a0)              set up CR1, stop timer
	move.b  #$ff,9(a0)              set timer 2 to $ffff
	move.b  #$ff,11(a0)
	move.b  #$ff,13(a0)             set timer 3 to $ffff
	move.b  #$ff,15(a0)
	move.b  #$00,1(a0)              start timer
itskp   rts

*************************************************************************
* asm_ticker   function ticker:integer
*       sp+4 is the long word to contain the current timer value
*
*************************************************************************
asm_ticker equ *
	clr.l   4(sp)                   default value
	btst    #timer_present,sysflag2 if hardware timer present
	bne.s   rtskp2
	lea     $5f8000,a0              address of timer counter 2
	movep.l 9(a0),d0                read counter 2 and 3
	movep.l 9(a0),d1                read them again
	eor.l   d0,d1                   see if the upper word has changed
	swap    d1
	tst.w   d1
	beq.s   rtskp1
	   swap    d1
	   eor.l   d1,d0                use second reading if MSW has changed
rtskp1  move.l  d0,4(sp)
rtskp2  rts
*************************************************************************
* check_timer                           check the timer
*                                 Assumes timer is present!!
*
*   sp+4 contains a pointer to the timer control data structure:
*           timer_control_var: long word
*           first_time: boolean  (first byte after timer_control_var)
*     if first_time then timer_control_var contains the timeout in milliseconds
*     if not first_time then timer_control_var contains timeout clock image
*   use bpl or bmi to check for timeout (bpl will branch if not timed out yet)
*
*************************************************************************

check_timer equ *

	movem.l d0-d1/a0,-(sp)          save registers
*                                       read timer
	lea     $5f8000,a0              address of timer counter 2
	movep.l 9(a0),d0                read counter 2 and 3
	movep.l 9(a0),d1                read them again
	eor.l   d0,d1                   see if the upper word has changed
	swap    d1
	tst.w   d1
	beq.s   ctskp1
	   swap    d1
	   eor.l   d1,d0                use second reading if MSW has changed

ctskp1  equ     *                       timer value in d0
	movea.l 16(sp),a0               a0 = ^timeout value
	move.l  12(sp),16(sp)           move up return address
	tst.b   4(a0)                   first_time?
	bne     setup_timer             branch if first_time
	   cmp.l   (a0),d0              check for timeout (test with bpl)
	   movem.l (sp)+,d0-d1/a0       restore registers
	   addq.l  #4,sp                fix up stack
	   rts

setup_timer equ *
	move.l  (a0),d1                 d1 = delay in milliseconds
	lsl.l   #6,d1                   multiply by 250
	sub.l   (a0),d1
	lsl.l   #1,d1
	sub.l   (a0),d1
	lsl.l   #1,d1                   d1 = delay in tics (1 tic = 4 us)
	sub.l   d1,d0                   d0 = timeout value
	move.l  d0,(a0)+                store timeout value at a0^
	clr.b   (a0)                    first_time = false
	movem.l (sp)+,d0-d1/a0          restore registers
	addq.l  #4,sp                   fix up stack
	rts

*************************************************************************
* delay_timer                           wait for specified amount of time
*   sp+4 contains the amount of time to wait in microseconds (long integer)
*************************************************************************

delay_timer  equ  *
	movem.l d0-d1/a0,-(sp)
	btst    #timer_present,sysflag2 check for hardware timer

* Use the timer to measure delay.
* There is 218 cycles of overhead in addition to the timer amount.
* It takes 351 cycles to go through the routine once.

	bne.s   dlskp2
	lea     $5f8000,a0              address of timer
	movep.l 9(a0),d0                read counter 2 and 3
	movep.l 9(a0),d1                read them again
	eor.l   d0,d1                   see if the upper word has changed
	swap    d1
	tst.w   d1
	beq.s   dlskp1
	swap    d1
	eor.l   d1,d0                   use second reading if MSW has changed
dlskp1  move.l  16(sp),d1               d1 = delay in microseconds
	lsr.l   #2,d1                   d1 = delay in tics (1 tic = 4 us)
	subq.l  #3,d1                   subtract overhead outside timing loop
	sub.l   d1,d0                   d0 = timeout value

dlloop1 movep.l 9(a0),d1                read counter 2 and 3
	cmp.l   d0,d1                   compare timer value to timeout value
	bpl.s   dlloop1
	movem.l (sp)+,d0-d1/a0
	move.l  (sp)+,(sp)
	rts

* Use timing loop if no timer is present.
* Number of cycles = 230+31n

dlskp2  move.l  16(sp),d1               d1 = delay in microseconds
	lsr.l   #2,d1                   d1 = number of loops (1 loop = 4 us)
	subq.l  #7,d1                   subtract overhead outside loop (230/31)
dlloop2 subq.l  #1,d1                   timing loop
	nop
	nop
	bpl.s   dlloop2
	movem.l (sp)+,d0-d1/a0
	move.l  (sp)+,(sp)              pop parameter
	rts


	page
*       TRAPS:

*       ADDRESS         TRAP    ESCAPECODE      USUAL MEANING

*       $FFFFFF3A       15      (NONE)          DEBUGGER
*       $FFFFFF40       14      -21             UNASSIGNED
*       $FFFFFF46       13      -21             UNASSIGNED
*       $FFFFFF4C       12      -21             UNASSIGNED
*       $FFFFFF52       11      (NONE)          SUPERVISOR MODE
*       $FFFFFF58       10      "N"             ESCAPE N
*       $FFFFFF5E       9       (NONE)          NON LOCAL GOTO
*       $FFFFFF64       8        -3             DEREFERENCE NIL POINTER
*       $FFFFFF6A       7        -8             VALUE RANGE ERROR
*       $FFFFFF70       6        -9             CASE STATEMENT ERROR
*       $FFFFFF76       5        -5             DIVIDE BY ZERO
*       $FFFFFF7C       4        -4             INTEGER OVERFLOW
*       $FFFFFF82       3       -10             IORESULT <> 0
*       $FFFFFF88       2        -2             STACK OVERFLOW
*       $FFFFFF8E       1       (-2 IF ANY)     LINK A6 EMULATOR WITH STACK CHECK
*       $FFFFFF94       0       (NONE)          PASCAL LINE BREAKPOINT


*       SYSTEM EXCEPTIONS:

*       ADDRESS                 ESCAPECODE      USUAL MEANING

*       $FFFFFFC4               -13             1111 OPCODE
*       $FFFFFFCA               -13             1010 OPCODE
*       $FFFFFFD0               (NONE)          TRACE
*       $FFFFFFD6               -14             PRIVILEGE VIOLATION
*       $FFFFFFDC                -4             INTEGER OVERFLOW (TRAPV)
*       $FFFFFFE2                -8             CHK INSTRUCTION
*       $FFFFFFE8                -5             DIVIDE BY ZERO (HARDWARE)
*       $FFFFFFEE               -13             ILLEGAL INSTRUCTION
*       $FFFFFFF4               -11             ADDRESS ERROR
*       $FFFFFFFA               -12             BUS ERROR

	NOSYMS
	END .
@


55.1
log
@Automatic bump of revision number for PWS version 3.25A
@
text
@@


54.5
log
@
pws2rcs automatic delta on Wed Aug 21 10:27:27 MDT 1991
@
text
@@


54.4
log
@
pws2rcs automatic delta on Wed Aug 21 09:35:48 MDT 1991
@
text
@d1 1276
@


54.3
log
@added refa statement so asm_copy_off could be found.
@
text
@a0 1276
*
*       INTERRUPT, TRAP, AND EXCEPTION HANDLER
*
*    (rdq) changes for Rev 3.0
*
*     CHANGES FOR PARITY SUPPORT  -- JS 9/12/83
*     Changes for 68040 support - JWH 12/1/89
*     Each line has 68040 as a comment.
*
	DEF     ASM_SETINTLEVEL,ASM_INTLEVEL
	DEF     ASM_INITVECTS,RESETX,ASM_CLOSEFILES
	DEF     EXCP_PC,EXCP_LINE
	DEF     GRAPHICSBASE,GRAPHICSFLAG,ALPHAFLAG,FLTPTHDW
	DEF     INITSTACK                                     JS 20 JUN 85
	DEF     ERR_INFO                                      RQ 18/Jan/84

	REFA    SYSGLOBALS,LOADER,STACKFUDGE,ASM_CACHE_ON
	REFA    ASM_FLUSH_ICACHE,ASM_ICACHE_ON                3/25/85
	REFA    ASM_ICACHE_OFF,ASM_CACHE_OFF,ASM_COPY_OFF
	REFR    FS_FCLOSE,INITUNITS_NOISR,INITLOAD_INITLOAD
	LMODE   FS_FCLOSE,INITUNITS_NOISR,INITLOAD_INITLOAD
	LMODE   ASM_CACHE_ON
	LMODE   ASM_FLUSH_ICACHE,ASM_ICACHE_ON                3/25/85
	LMODE   ASM_ICACHE_OFF,ASM_CACHE_OFF
	LMODE   SPUR_VEC,OUTA_HERE
	SMODE   ESCAPE

*THE FOLLOWING OFFSETS ARE RELATIVE TO SYSGLOBALS(A5)

ESCAPECODE      EQU SYSGLOBALS-2          (A5)
FILELISTPTR     EQU SYSGLOBALS-6          (A5)
RECOVERBLOCK    EQU SYSGLOBALS-10         (A5)
HEAPPOINTER     EQU SYSGLOBALS-14         (A5)
HEAPBASE        EQU SYSGLOBALS-18         (A5)
IORESULT        EQU SYSGLOBALS-22         (A5)
INTERRUPTTABLE  EQU SYSGLOBALS-62         (A5) ADDRESS OF INTERRUPTTABLE[1..7]
ENDISRHOOK      EQU SYSGLOBALS-66         (A5) ADDRESS OF END OF ISR ROUTINE
DEBUGGER        EQU SYSGLOBALS-276        (A5) DEBUGGER HOOK
CLEARIOHOOK     EQU SYSGLOBALS-284        (A5) CLEAR I/O HOOK
SYSDEFS         EQU LOADER-70             (A5) LINKED LIST OF PERMANT PROGRAMS
NIL             EQU 0

HIGHMEM         EQU $FFFFFB00   LEAVES ROOM FOR VECTORS, MONITOR STUFF, ETC.
TRAP0VECTOR     EQU $FFFFFF94   LOCATION OF EXCEPTION VECTOR FOR TRAP #0
*
LEVEL7V         EQU $FFFFFF9A   NMI
LEVEL7DV        EQU $FFFFFF22   LEVEL 7 DEVICE VECTOR                   (rdq)
KBDRESETV       EQU $FFFFFF34   KEY BOARD <SHIFT PAUSE VECTOR>
FHIVECTOR       EQU $FFFFFF2E   KEY BOARD LEVEL 7 TIMER INTERRUPT       (rdq)
*
F_LINEV         EQU $FFFFFFC4   TRAP FOR F-LINE INSTRUCTIONS
M68881V         EQU $FFFFFEE0   TRAP FOR 68881 EXCEPTIONS
UNSUPP          EQU $FFFFFEE6   68040 only
SPUR_VEC        EQU $FFFFFF1C   SPURIOUS INTERRUPT VECTOR
*
LOWMEM          EQU $FFFFFDCE   LOCATION IN BOOT ROM OF LOWEST RAM
RTN_TO_MONITOR  EQU $1A0        ENTRY POINT IN BOOT ROM
G_OFF_MEM       EQU $538000     GRAPHICS OFF
ALPHA_MEM       EQU $512000     ALPHA MEMORY
*
P_STATUS        EQU $5B0000     PARITY STATUS REG                  JS 9/12/83
*
*
* MAGIC NUMBERS, see alse FILES ASM, DEBUGGER and INITBUG
*
ERR_INFO        EQU HIGHMEM
FAULT_ADDR      EQU HIGHMEM     PARITY ERROR ADDRESS
*                                       68000
BE_SSW          EQU     HIGHMEM         SPECIAL STATUS WORD
BE_FAULT_ADDR   EQU     BE_SSW+2        FAULT ADDRESS
BE_INSTR        EQU     BE_FAULT_ADDR+4 INSTRUCTION BUFFER
*
*                                       68010
*BE_SSW         2 BYTES                 VECTOR TYPE 1000
*BE_FAULT_ADDR  4 BYTES
BE_PAD1_10      EQU     BE_FAULT_ADDR+4
BE_DATAO_10     EQU     BE_PAD1_10+2    DATA INPUT BUFFER
BE_PAD2_10      EQU     BE_DATAO_10+2
BE_DATAI_10     EQU     BE_PAD2_10+2    DATA OUTPUT BUFFER
BE_PAD3_10      EQU     BE_DATAI_10+2
BE_INSTR_10     EQU     BE_PAD3_10+2    INSTRUCTION BUFFER
BE_MISC_10      EQU     BE_INSTR_10+2   16 WORDS
BE_END_10       EQU     BE_MISC_10+32
*
*                                       68020
ERR_PC          EQU     HIGHMEM         VECTOR TYPE 0010
*ERR_PC         4 BYTES                 VECTOR TYPE 1001
ERR_WRD1        EQU     ERR_PC+4
ERR_WRD2        EQU     ERR_WRD1+2
ERR_EA          EQU     ERR_WRD2+2      EVALUATED ADDRESS
*BE_SSW         4 BYTES                 VECTOR TYPE 1010 (SHORT BUS ERROR)
BE_IPSC         EQU     BE_SSW+4        I PIPE C
BE_IPSB         EQU     BE_IPSC+2       I PIPE B
BE_PAD2_20      EQU     BE_IPSB+2
BE_FAULT_ADDR20 EQU     BE_PAD2_20+4
BE_DATA_20      EQU     BE_FAULT_ADDR20+4       DATA BUFFER
BE_MISCS_20     EQU     BE_DATA_20+4    4 BYTES
BE_END_S_20     EQU     BE_MISCS_20+4
*
*BE_SSW         4 BYTES                 VECTOR TYPE 1011 (LONG BUS ERROR)
*BE_IPSC        2 BYTES
*BE_IPSB        2 BYTES
*BE_PAD         4 BYTES
*BE_FAULT_ADDR  4 BYTES
*BE_DATAO       4 BYTES
BE_PAD3_20      EQU     BE_DATA_20+4            16 BYTES
BE_DATAI_20     EQU     BE_PAD3_20+16
BE_MISC20_20    EQU     BE_DATAI_20+4           44 BYTES
BE_END_L_20     EQU     BE_MISC20_20+44
BE_END          EQU     BE_END_L_20
*--------------------------------------------------------------------------
EXCP_STATUS     EQU BE_END
EXCP_PC         EQU EXCP_STATUS+2
EXCP_VOFFSET    EQU EXCP_PC+4           VECTOR WORD FOR 680xx           (rdq)
EXCP_LINE       EQU EXCP_VOFFSET+2                                      (rdq)
LASTLINE        EQU EXCP_LINE+4
ESCAPE          EQU LASTLINE+4
PCTEMP          EQU ESCAPE+6
SRTEMP          EQU PCTEMP+4
INITSTACK       EQU SRTEMP+2
INITPC          EQU INITSTACK+4
INITRECOVER     EQU INITPC+4
G_DOLLAR        EQU INITRECOVER+4
CTL_RESETV      EQU G_DOLLAR+4          KEY BOARD <CONTROL><SHIFT><PAUSE> VECTOR
DEBUGESCAPE     EQU CTL_RESETV+6
BESPTEMP        EQU DEBUGESCAPE+6       USED IN IGNOREBUS
ALPHAFLAG       EQU BESPTEMP+4
GRAPHICSFLAG    EQU ALPHAFLAG+1
GRAPHICSBASE    EQU GRAPHICSFLAG+1
INITSR          EQU GRAPHICSBASE+4
M68KTYPE        EQU INITSR+2    PROCESSOR TYPE 0=68000 else 680xx       (rdq)
MSYSFLAGS       EQU M68KTYPE+1  MORE SYSFLAGS BIT 0 = CACHE PRESENT/ABSENT
FLTPTHDW        EQU MSYSFLAGS+1
FILLER          EQU FLTPTHDW+1  UNUSED

JMP     EQU $4EF9                       LONG ABSOLUTE JMP OPCODE


	RORG 0

*
* NOTE -- ALL CACHES SHOULD BE OFF AT THIS TIME
*
ASM_INITVECTS   EQU *                   MAIN PROGRAM POWER UP LOCATION
	CLR.B   FLTPTHDW        SHOW NO FLOATING POINT HARDWARE

	MOVEQ   #$FFFFFFFF,D0           HIGHEST POSSIBLE ADDRESS
	MOVE.L  D0,FILELISTPTR(A5)
	MOVE.W  #$4E75,DEBUGESCAPE
	CLR.L   LASTLINE
	MOVE.L  #ENDISR,ENDISRHOOK(A5)  SET UP ORDINARY RETURN FROM ISR's

	jsr     init_timer      checks for and turns on timer   (rdq)

*                               TURN OFF GRAPHICS
	MOVEA.L #G_OFF_MEM,A0   GET MEM ADDRESS
	MOVE.L  A0,GRAPHICSBASE SAVE IT IN GLOBAL AREA
	CLR.B   GRAPHICSFLAG    MARK IT TURNED OFF

	LEA     IGNOREBUS,A1    SET BUS ERROR VECTOR
	MOVE.L  A1,-4
	MOVE.W  #JMP,-6
	PEA     GRPH1
	MOVE.L  SP,BESPTEMP
	MOVE    (A0),D0         TURN OFF GRAPHICS
	ADDQ.L  #4,SP
GRPH1   EQU     *
	MOVE.B  #1,ALPHAFLAG    MARK ALPHA TURNED ON
*
*    TURN ON CACHE IF WE HAVE ONE
*
CACHE_CTL EQU   $5F400E
	CLR.B   MSYSFLAGS       CLEAR FLAGS BYTE
	PEA     CACHE1
	MOVE.L  SP,BESPTEMP
	TST.W   CACHE_CTL       TEST
	ADDQ.L  #4,SP
	BSET    #0,MSYSFLAGS    CACHE EXISTS
	MOVE    #0,CACHE_CTL    CLEAR THE CONTROL WORD
	JSR     ASM_CACHE_ON
CACHE1  EQU     *
*
*    TURN ON PARITY BOARDS IF ANY                             JS 9/12/83
*                                                             JS 9/12/83
	PEA     PCHK1
	MOVE.L  SP,BESPTEMP
	MOVE.W  #1,P_STATUS                                   JS 9/12/83
	ADDQ.L  #4,SP
PCHK1   EQU     *                                             JS 9/12/83
*
	LEA     $FFFFFFC4,A0            ADDRESS PAST INTERRUPT VECTOR LEVEL 1
	LEA     INTERRUPT,A1
	MOVEQ   #6,D0                   HANDLE LEVELS 1 THRU 6
I_LOOP  MOVE.L  A1,-(A0)                MOVE JMP TO INTERRUPT VECTOR
	MOVE.W  #JMP,-(A0)
	SUBQ    #1,D0
	BNE     I_LOOP

	LEA     LEVEL7DV,A0     SETUP LEVEL 7 DEVICE VECTOR             (rdq)
	MOVE.W  #JMP,(A0)+                                              (rdq)
	MOVE.L  A1,(A0)                                                 (rdq)
* INIT VECTORS FOR HANDLING <SHIFT PAUSE> AND <CONTROL><SHIFT><PAUSE>
	MOVE.W  #JMP,LEVEL7V
	MOVE.L  $1B0,LEVEL7V+2
	MOVE.W  #JMP,KBDRESETV
	MOVE.L  #RESET_ISR,KBDRESETV+2
	MOVE.W  #JMP,CTL_RESETV
	MOVE.L  #TRYMONITOR,CTL_RESETV+2
*
	LEA     FHIVECTOR,A0    LEVEL 7 TIMER INTERRUPT VECTOR          (rdq)
	MOVE.W  #JMP,(A0)+                                              (rdq)
	MOVE.L  A1,(A0)                                                 (rdq)

	LEA     ESC,A0                  MOVE ESCAPE LINKAGE TO HIGH MEMORY
	MOVE.W  #JMP,ESCAPE
	MOVE.L  A0,ESCAPE+2

	MOVE.L  TRAP0VECTOR+2,D0        GET DEFAULT ENTRY POINT FOR TRAP #0
	AND.L   #$00FFFFFF,D0           TEST FOR MONITOR
	CMP.L   #$00880000,D0
	BGE.S   L0
	MOVE.W  #JMP,TRAP0VECTOR        SET UP EXCEPTION VECTOR FOR
	LEA     P_BREAK,A0              PASCAL LINE HEADERS
	MOVE.L  A0,TRAP0VECTOR+2

*==========

L0      MOVEM.W ESCAPE_PROTO,D1-D2      GET 6 BYTE MOVEQ #ESCCODE, JMP ESCAPE
	LEA     0,A0                    START FROM TOP OF RAM
	MOVE.W  #JMP,D0                 $4EF9   (LONG ABS JUMP)

	LEA     BUS_ERR,A1              SET UP BUS ERROR TRAP
	MOVE.L  A1,-(A0)                ADDRESS IN LAST 4 BYTES
	MOVE.W  D0,-(A0)                LONG JUMP IN FIRST 2 BYTES

	LEA     ADD_ERR,A1              SET UP ADDRESS ERROR TRAP
	MOVE.L  A1,-(A0)                ADDRESS IN LAST 4 BYTES
	MOVE.W  D0,-(A0)                LONG JUMP IN FIRST 2 BYTES

	MOVEQ   #-13,D3                 ILLEGAL INSTRUCTION, ESCAPE(-13)
	MOVEM.W D1-D3,-(A0)             MOVE 'moveq, short jump esc'

	MOVEQ   #-5,D3                  SIMILAR FOR DIVIDE BY ZERO
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-8,D3                  SIMILAR FOR CHK EXCEPTION
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-4,D3                  SIMILAR FOR TRAPV
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-14,D3                 SIMILAR FOR PRIVILEGE VIOLATION
	MOVEM.W D1-D3,-(A0)

	SUBQ.L  #6,A0                   SKIP TRACE

	MOVEQ   #-13,D3                 ILLEGAL INSTRUCTION (OPS A,F), ESCAPE(-13)
	MOVEM.W D1-D3,-(A0)             MOVE 'moveq, short jump esc'
	MOVEM.W D1-D3,-(A0)             MOVE 'moveq, short jump esc'

	LEA     $FFFFFF94,A0            CONTINUE WITH TRAP VECTORS

	LEA     LINKA6,A1               TRAP 1, LINK A6 EMULATOR
	MOVE.L  A1,-(A0)
	MOVE.W  D0,-(A0)

	MOVEQ   #-2,D3                  TRAP 2, STACK OVERFLOW
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-10,D3                 TRAP 3, I/O RESULT NOT ZERO
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-4,D3                  TRAP 4, INTEGER OVERFLOW
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-5,D3                  TRAP 5, INTEGER DIVIDE BY ZERO
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-9,D3                  TRAP 6, CASE STATEMENT ERROR
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-8,D3                  TRAP 7, VALUE RANGE ERROR
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-3,D3                  TRAP 8, NIL POINTER REFERENCE
	MOVEM.W D1-D3,-(A0)

	LEA     NLGOTO,A1               TRAP 9, NON LOCAL GOTO
	MOVE.L  A1,-(A0)
	MOVE.W  D0,-(A0)

	LEA     ESCN,A1                 TRAP 10, ESCAPE N
	MOVE.L  A1,-(A0)
	MOVE.W  D0,-(A0)
*                                       (rdq)
	SUBQ.L  #6,A0                   skip over TRAP 11 (done by ASM_POWERUP)
*
	MOVEQ   #-21,D3                 TRAP 12, UNASSIGNED
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-21,D3                 TRAP 13, UNASSIGNED
	MOVEM.W D1-D3,-(A0)

	MOVEQ   #-21,D3                 TRAP 14, UNASSIGNED
	MOVEM.W D1-D3,-(A0)

	JSR     SPURIOUS                JWH 1/18/90
	JSR     M881_ON                 ENABLE M68881 IF PRESENT
	JSR     ASM_ICACHE_ON           NOW TURN ICACHE ON        { 3/25/85 }
	RTS                             END OF VECTOR SET UP, POWER UP
*-------(rdq)------------------------------------------------------------
IGNOREBUS EQU   *
	TST.B   M68KTYPE
	BNE.S   IGNBUS1
	ADDA.L  #8,SP                 THROW AWAY STACK INFO FROM BUS ERROR
IGNBUS1 MOVE  (SP),SR                 FIX SR SO SP WILL BE CORRECT
	MOVEA.L BESPTEMP,SP
	RTS                           RETURN TO RECOVERY POINT
*-------------------------------------------------------------------------
	PAGE
*
*  ENABLE M68881 AND SETUP EXCEPTION VECTOR IF PRESENT
*      - JS 4/29/85
*
*  Note - this serves equally well for getting things set up
*  when you have a 68040, since the FPCONTROL register is
*  now on chip ... JWH 12/1/89
*
M881_ON EQU *
	MOVE.W  F_LINEV,-(SP)        SAVE OLD F-LINE VECTOR
	MOVE.L  F_LINEV+2,-(SP)
	MOVE.W  #JMP,F_LINEV         SETUP NEW VECTOR
	MOVE.L  #FLINE,F_LINEV+2
	FMOVE.L #$FC00,FPCONTROL     ENABLE THE 881 EXCEPTIONS
	MOVE.W  #JMP,M68881V         SETUP EXCEPTION VECTOR
	MOVE.L  #M881SERV,M68881V+2
*=============================================================
* Following code keeps the unsupported data type handler from
* being completely bare on the 68040. All exceptions going
* through exception 55 wind up giving "error -31 : undocumented
* error" unless the FP40 package is installed, in which case
* a better error message is displayed. JWH 2/11/91. If not
* for this you bounce into the boot rom with "UNEXPECTED USE
* OF FFFFFEE6 and the system hangs. JWH 2/11/91
	BTST    #3,SYSFLAG2          68040 ONLY 2/11/91 JWH
	BNE     M881_ON1             68040 ONLY 2/11/91 JWH
	MOVE.W  #JMP,UNSUPP          68040 ONLY 2/11/91 JWH
	MOVE.L  #M881SERV,UNSUPP+2   68040 ONLY 2/11/91 JWH
*============================================================
M881_ON1 EQU *
	MOVE.L  (SP)+,F_LINEV+2      RESTORE F-LINE VECTOR
	MOVE.W  (SP)+,F_LINEV
	RTS                          DONE WITH M68881 ENABLE

* Added 1/18/90 JWH :
*
SPURIOUS EQU *
	 MOVE.W   D0,spur_vec       assumes d0 has JMP
	 lea      outa_here,a0
	 move.l   a0,d0
	 move.l   d0,spur_vec+2
	 rts
outa_here  RTE
*
FLINE   EQU *                       NO 881 IF WE GET HERE
	MOVE.L #M881_ON1,2(SP)      ADJUST RETURN ADDR
	RTE                         AND RETURN
*
*
* M68881 Trap service routines
*     - stolen from BASIC code  JS 4/29/85
*
* Escapecodes for 68881 traps
*
errover         equ     -6                      Real overflow
errarc          equ     -30                     Arcsin, Arccos arg > 1
errlog          equ     -16                     Log of non-positive #
errill          equ     -31                     Illegal real number
errsqr          equ     -17                     SQR of negative #
errdvdz         equ     -5                      Divide by 0
errunder        equ     -7                      Real underflow
errintovr       equ     -4                      integer overflow
*
m881serv        equ     *                       68881 trap service routine
		move.w  d0,-(sp)                save regs we might use
		move.l  a0,-(sp)
		FSAVE   256             IDLE 68882 SO IT WILL DTACK
*                                       IF WE DON'T IT WON'T DTACK. SFB/RDQ/DD
		fmove.l fpstatus,d0
		btst    #12,d0
		beq.s   m881s1
		moveq   #errover,d0             68881 overflow
		bra     common881
m881s1          btst    #11,d0
		beq.s   m881s2
		move.l  #errunder,d0            68881 underflow
		bra     common881
m881s2          btst    #10,d0
		beq.s   m881s3
		fmove.l fpiaddr,a0              divide by 0, get instr addr
		move.l  (a0),d0                 get the offending instruction
		andi.b  #$7f,d0                 look at opcode
		cmpi.b  #$20,d0                 is it fdiv?
		bne.s   m881s2a
		moveq   #errdvdz,d0             escape with divide by 0 error
		bra     common881
m881s2a         moveq   #errlog,d0              68881 divide by 0
		bra     common881
m881s3          btst    #13,d0
		beq.s   m881s4
		fmove.l fpiaddr,a0              operand error, get instr addr
		move.l  (a0),d0                 get the offending instruction
		andi.b  #$7f,d0                 look at opcode
		cmpi.b  #$20,d0                 is it fdiv?
		bne.s   m881s3a
		moveq   #errdvdz,d0             escape with divide by 0 error
*                                               note: if could also be inf/inf
		bra.s   common881
m881s3a         cmpi.b  #$04,d0                 is it fsqrt?
		bne.s   m881s3b
		moveq   #errsqr,d0              escape with sqr of negative #
		bra.s   common881
m881s3b         cmpi.b  #$15,d0                 is it flog10?
		beq.s   m881s3c
		cmpi.b  #$14,d0                 is it flogn?
		bne.s   m881s3d
m881s3c         moveq   #errlog,d0              escape with log of negative #
		bra.s   common881
m881s3d         cmpi.b  #$1c,d0                 is it facos?
		beq.s   m881s3e
		cmpi.b  #$0c,d0                 is it fasin?
		bne.s   m881s3f
m881s3e         moveq   #errarc,d0              escape with asin/acos of x > 1
		bra.s   common881
*
*               The following is a special case for the Pascal compiler.
*               If fmove to an integer generates integer overflow, the 68881
*               will generate OPERR, but we want to report integer overflow.
*
m881s3f         equ     *
		tst.b   d0                      is it fmove?
		bne.s   m881s3g
		moveq   #errintovr,d0           escape with integer overflow
		bra.s   common881
m881s3g         equ     *

*       Note:  Error -31 (illegal real number) will be
*              returned for BSUN (branch or set on unordered) and for
*              invalid operands:
*                       add     +infinity with -infinity
*                       mul     0 * infinity
*                       sub     infinity
*                       div     infinity/infinity
*               These should not happen however.

m881s4          moveq   #errill,d0              68881 signaling not-a-number
*
common881       equ     *
		move.l  a5,-(sp)                save a5
		movea.l g_dollar,a5             get it setup right
		move.w  d0,sysglobals-2(a5)     set up escapecode
		movea.l (sp)+,a5
		movea.l (sp)+,a0                restore regs
		move    (sp)+,d0
		jmp     escn                    goto generic trap routine
		page

*=========================================================================
ASM_CLOSEFILES EQU *
	MOVEA.L 4(SP),A0        EVENTUAL SP
	MOVEA.L FILELISTPTR(A5),A1
	CMPA.L  A0,A1
	BCC.S   ALLDONE
	CMPA.L  SP,A1
	BCS.S   ALLDONE
	MOVE.L  4(A1),FILELISTPTR(A5)
	CLR.L   4(A1)           FLAG UNINITIALIZED
	MOVE.L  IORESULT(A5),-(SP)
	MOVE.W  ESCAPECODE(A5),-(SP)
	PEA     (A1)
	CLR.W   -(SP)           NORMAL CLOSE
	JSR     FS_FCLOSE
	MOVE.W  (SP)+,ESCAPECODE(A5)
	MOVE.L  (SP)+,IORESULT(A5)
	BRA.S   ASM_CLOSEFILES
ALLDONE MOVE.L  (SP)+,(SP)
	RTS

NLGOTO  MOVE.W  (SP)+,D0        SAVE STATUS REG
	MOVEA.L (SP)+,A0
	TST.B   M68KTYPE                                        (rdq)
	BEQ.S   NLGOTOA                                         (rdq)
	ADDQ.L  #2,SP           POP VECTOR WORD                 (rdq)
NLGOTOA MOVE    D0,SR           RESTORE USER MODE
	MOVE.W  (A0)+,D1        STATIC DELTA
	BGE.S   NLGOTO1
	MOVEA.L INITSTACK,A6    DEST IS MAIN PROG
NLGOTO1 BLE.S   NLGOTO3
NLGOTO2 MOVEA.L 8(A6),A6
	SUBQ.W  #1,D1
	BGT.S   NLGOTO2
NLGOTO3 MOVE.L  (A0),D1         DESTINATION DELTA
	PEA     0(A0,D1.L)      COMPUTE RETURN ADDRESS
*
*  Check for LEA {4fee} or MOVEA {2e4e}
*  Code is either LEA <delta.w>(a6),sp or MOVEA.L a6,sp  ADDA.L #<delta.l>,sp
*
	CMPI.W  #$4FEE,0(A0,D1.L)   BUG FIX 5/13/85 JWS
	BEQ.S   DELTA16
	MOVE.L  4(A0,D1.L),D2   SP DELTA FROM A6 { 32 BIT VALUE }
	LEA     0(A6,D2.L),A1   EVENTUAL SP
	BRA.S   NLGOTO4
DELTA16 MOVE.W  2(A0,D1.L),D2   SP DELTA FROM A6 { 16 BIT VALUE }
	LEA     0(A6,D2.W),A1   EVENTUAL SP
NLGOTO4 CMPA.L  RECOVERBLOCK(A5),A1 POP OFF TRY RECOVER BLOCKS
	BLS.S   NLGOTO5         ABOVE THE EVENTUAL SP
	MOVEA.L RECOVERBLOCK(A5),A2
	MOVE.L  8(A2),RECOVERBLOCK(A5)
	BRA.S   NLGOTO4
NLGOTO5 MOVE.L  A1,-(SP)
	JSR     ASM_CLOSEFILES  CLOSE FILES BEING POPPED OFF
	RTS

LINKA6  MOVE    (SP)+,D0        STATUS
	MOVEA.L (SP)+,A0        PC
	TST.B   M68KTYPE                                        (rdq)
	BEQ.S   LINKA6A                                         (rdq)
	ADDQ.L  #2,SP           POP VECTOR WORD                 (rdq)
LINKA6A MOVE    D0,SR           RETURN TO ORIGINAL MODE
	MOVE.L  A6,-(SP)        EMULATE LINK A6
	MOVEA.L SP,A6
	MOVEA.L SP,A3           COPY FOR SP CALC.
	MOVE.W  (A0)+,D1
	EXT.L   D1
	BLE.S   LINKW
	SWAP    D1
	MOVE.W  (A0)+,D1
	BCLR    #30,D1           **** FIX FOR 3.1b
	NEG.L   D1
LINKW   ADDA.L  D1,A3           PRE CALCULATE NEW SP

	BTST    #13,D0          WHICH MODE?
	BEQ.S   UMODE

SMODE   LEA     32766(A5),A2
	BRA.S   SCHECK
UMODE   MOVEA.L HEAPPOINTER(A5),A2

SCHECK  LEA     -STACKFUDGE(A3),A1

	CMPA.L  A2,A1   CHECK STACK OVERFLOW
	BLS.S   STACKOV
	MOVEA.L A3,SP   NOW SET NEW SP
	JMP     (A0)

STACKOV TRAP    #2              SIGNAL STACK OVERFLOW

	PAGE
******************************************************************************
*                     INTERRUPT POLLING ROUTINE: LEVELS 1-7 (rdq)            *
******************************************************************************

*
* ISRIB STRUCTURE
*
INTREGADDR      EQU     0       (LONG)          CHARPTR
INTREGMASK      EQU     4       (BYTE)          BYTE
INTREGVALUE     EQU     5       (BYTE)          BYTE
CHAINFLAG       EQU     6       (WORD)          BOOLEAN IN MSB; OTHER BITS RESERVED
PROC.ADDR       EQU     8       (LONG)          PROCEDURE ADDRESS
PROC.LINK       EQU     12      (LONG)          PROCEDURE STATIC LINK
LINK            EQU     16      (LONG)          LINK TO NEXT ISRIB

*
*  INTERRUPT POLLING ROUTINE: LEVELS 1-7                                (rdq)
*
INTERRUPT       EQU *

	MOVEM.L D0-D7/A0-A6,-(SP)       SAVE CONTEXT, 64 BYTES
	MOVEA.L G_DOLLAR,A5             SET UP THE PASCAL GLOBAL ENVIRONMENT
	MOVE.L  IORESULT(A5),-(SP)      IORESULT IS PART OF THE CONTEXT
	MOVE.W  ESCAPECODE(A5),-(SP)    THE ESCAPE CODE IS PART OF THE CONTEXT

	MOVE.L  RECOVERBLOCK(A5),-(SP)  SET UP A TRY/RECOVER BLOCK
	PEA     RECOVER
	MOVE.L  SP,RECOVERBLOCK(A5)

	MOVE    SR,D0                   FETCH THE CURRENT INTERRUPT LEVEL
	LSR     #8-2,D0                 POSITION IN THE LOWER BYTE, MULTIPLIED BY 4
	AND.W   #$1C,D0                 MASK OUT THE OTHER BITS
	LEA     INTERRUPTTABLE(A5),A0
	MOVEA.L -4(A0,D0),A0            POINT TO THE FIRST ISRIB FOR THIS LEVEL

PLOOP   MOVE.L  A0,D0                   SET THE CONDITION CODES
	BEQ.S   NOISR                   BRANCH IF THE POINTER IS NILL
	MOVEA.L A0,A1                   USE A1 FOR SCANNING THE ISRIB
	MOVEA.L (A1)+,A2                INTERRUPT REGISTER ADDRESS
	MOVE.B  (A2),D0                 INTERRUPT REGISTER CONTENTS
	AND.B   (A1)+,D0                INTERRUPT REGISTER MASK
	CMP.B   (A1)+,D0                THIS SOURCE REQUESTING AN INTERRUPT?
	BNE.S   NEXT                    BRANCH IF NOT

	CLR     (A1)+                   CLEAR THE CHAIN FLAG
	MOVE.L  A0,-(SP)                SAVE THE POINTER TO THIS ISRIB
	MOVE.L  A0,-(SP)                ALSO, THE ISR GETS IT AS A PARAMETER

	BSR.S   CALLPROC                CALL THE ISR

	MOVEA.L (SP)+,A0                RESTORE THE POINTER TO THIS ISRIB
	TST     CHAINFLAG(A0)           DID THIS ISR CHOOSE TO SERVICE THE INTERRUPT?
	BEQ.S   RESTORE                 BRANCH IF SO; OTHERWISE...

NEXT    MOVEA.L LINK(A0),A0             POINT TO THE NEXT ISRIB IN THE LINKED LIST
	BRA     PLOOP                   AND POLL IT's associated interrupt bit
	PAGE
NOISR   MOVE    SR,D0                   CHECK INTERRUPT LEVEL       JS 9/12/83
	LSR     #8,D0                                               JS 9/12/83
	ANDI    #7,D0                   MASK ALL BUT LEVEL BITS     JS 9/12/83
	CMPI    #7,D0                   IS IT AN NMI ?              JS 9/12/83
	BNE.S   NOISRB                  NO, TREAT AS BEFORE         JS 9/12/83
	JSR     P_CHECK                 PARITY ERROR?               JS 9/12/83
	BEQ.S   NOISRB                  NO, SOMETHING ELSE          JS 9/12/83
	ADDQ.L  #4,SP                   POP ISR RECOVER ADDR        JS 9/12/83
	MOVE.L  (SP)+,RECOVERBLOCK(A5)  RESTORE OLD RECOVERBLOCK    JS 9/12/83
	MOVE.W  (SP)+,ESCAPECODE(A5)    ESCAPECODE AND IORESULT     JS 9/12/83
	MOVE.L  (SP)+,IORESULT(A5)      FROM USER CONTEXT           JS 9/12/83
	MOVEM.L (SP)+,D0-D7/A0-A6       AND LOOK AS IF WE DID A     JS 9/12/83
	MOVE.W  #-28,ESCAPECODE(A5)     ESCAPE(-28) FROM THE        JS 9/12/83
	CLR.L   FAULT_ADDR              USER PROGRAM                JS 9/12/83
	BRA     ESCN                                                JS 9/12/83

NOISRB  MOVE.L  A0,-(SP)                NILL POINTER
	JSR     INITUNITS_NOISR


RESTORE ADDQ.L  #4,SP                   POP OFF THE RECOVER BLOCK ADDRESS
RECOV_1 MOVE.L  (SP)+,RECOVERBLOCK(A5)  RESTORE THE ORIGINAL RECOVER BLOCK
	MOVE.W  (SP)+,ESCAPECODE(A5)    RESTORE THE ORIGINAL ESCAPE CODE
	MOVE.L  (SP)+,IORESULT(A5)      RESTORE IORESULT
	MOVEA.L ENDISRHOOK(A5),A0       CALL ISR HOOK TO ALLOW MULTI-TASKING
	JMP     (A0)

ENDISR  MOVEM.L (SP)+,D0-D7/A0-A6       RESTORE THE ORIGINAL CONTEXT
	RTE                             END OF INTERRUPT SERVICE

CALLPROC EQU *                          PROCEDURE CALL
	MOVEA.L (A1)+,A0                PROC ADDRESS
	MOVE.L  (A1)+,D0                STATIC LINK
	BEQ.S   CALLIT                  SKIP IF THERE IS NO STATIC LINK
	  MOVEA.L (SP)+,A1              SHUFFLE RETURN ADDRESS
	  MOVE.L  D0,-(SP)              PUSH STATIC LINK ON THE STACK
	  MOVE.L  A1,-(SP)
CALLIT  JMP     (A0)                    CALL THE PROCEDURE


*
* RECOVER BLOCK ROUTINES TO CATCH ESCAPES FROM ISR'S
*
RECOV_2 MOVEQ   #70,D0                  SETUP TO ENTER DEBUGGER         (rdq)
	MOVE.W  0(SP,D0),SRTEMP         SAVE THE STATUS REGISTER        (rdq)
	MOVE.W  #$2100,0(SP,D0)         DUMMY STATUS                    (rdq)
	MOVE.L  PCTEMP,D1               SAVE THE TARGET ADDRESS         (rdq)
	MOVE.L  2(SP,D0),PCTEMP         SWITCH PCTEMP                   (rdq)
	MOVE.L  D1,2(SP,D0)                                             (rdq)
	BRA.S   RECOV_1

RECOVER CMPI.W  #-22,ESCAPECODE(A5)     TEST FOR DEBUGGER CALL
	BEQ     RECOV_2
	CMPI.W  #-28,ESCAPECODE(A5)     CHECK FOR PARITY ERROR    JS 9/12/83
	BEQ.S   RECOVRX                 SAME TREATMENT AS STOP    JS 9/12/83
	CMPI.W  #-20,ESCAPECODE(A5)     TEST FOR STOP KEY
	BNE     RECOV_1

*       STOP KEY PRESSED                SIMULATE AN ESCAPE(-20)
RECOVRX MOVE.L  (SP)+,RECOVERBLOCK(A5)  RESTORE THE ORIGINAL RECOVER BLOCK
	ADDQ.L  #2,SP                   GET RID OF SAVED ESCAPECODE
	MOVE.L  (SP)+,IORESULT(A5)      RESTORE IORESULT
	LEA     STOP,A0
RECOVERA MOVE.L A0,62(SP)     REDIRECT INTERRUPTED PROGRAM TO STOP    (rdq)

* FIX FOR 3.1 STOPKEY DURING 68881 FLOAT OP BUG--SFB 8/14/85
* THE PROBLEM IS THAT THE 68881 CAN BE EXECUTING A float INSTRUCTION WHILE
* AN INTERRUPT OCCURS. IN THAT CASE A "MID-INSTRUCTION" EXCEPTION FRAME
* WILL BE DUMPED TO ALLOW 68881 RESTART/CONTINUANCE. ONLY IN THE CASE OF
* THE STOPKEY IS THERE A PROBLEM, AS THEN WE CHANGE THE PC IN THAT FRAME
* BEFORE DOING RTE. THIS RESTARTS THE 68881, AND IF THE FETCH OF THE float
* INSTRUCTION IS NOT COMPLETE, THE FIRST FETCH AFTER RTE IS EATEN BY THE
* 68881. FIX IS TO MODIFY THE MID-INSTRUCTION FRAME (FORMAT 9) TO A NORMAL
* FORMAT 0 FRAME, WHICH IS 12 BYTES SHORTER. TO DO THIS WE MOVE THE FRAME
* (INCLUDING REGISTER COPIES FOR THE MOVEM.L) UPWARD 12 BYTES IN RAM, AND
* SET THE FORMAT TO 0 (4-BIT FIELD AT BYTE 6 OF RTE FRAME). FINALLY
* WE DO FSAVE TO STOP THE 68881 IF IT THINKS IT'S STILL PROCESSING THE
* OPCODE, AND IGNORE THE DATA DUMPED BY FSAVE.
* NOTE- ONLY WORKS FOR 68881 (NO OTHER COPROCESSOR), AND ASSUMES 144 BYTES
* AVAILABLE ON THE STACK AT ENTRY.

	MOVE.B  66(SP),D0               NEED TO DETECT EXCEPT FRAME FMT 9
	ANDI.B  #$F0,D0
	CMPI.B  #$90,D0
	BNE.S   FRAME_OK

FRAME9  EQU     *                       UNUSED LABEL--FRAME TYPE KNOWN TO BE 9
	MOVEQ   #16,D0                  GOING TO MOVE 17 LONGWORDS UP ON STACK
	LEA     68(SP),A1               POINTS TO COMMON PART OF BOTH FRAMES
	LEA     80(SP),A2               OLD STACK FRAME+REGISTERS IS 80 BYTES

MOVEFRAME EQU   *                       FASTER THAN CALLING MOVELEFT
	MOVE.L  -(A1),-(A2)
	DBRA    D0,MOVEFRAME

	ADDA.W  #12,SP                  ADUST STACK FOR SMALLER FRAME SIZE
	ANDI.W  #$0FFF,66(SP)           AND SET FORMAT CODE 0 IN UPPER NIBBLE
*                                       OF FRAME FORMAT WORD

	FSAVE   256                     FINALLY, TURN OFF 68881 BY DUMPING
*                                       ITS CONTROL INFO (WHICH IS THEN
*                                       IGNORED) ONTO BOOTROM NOW SFB

	CLR.L   -(SP)                   NULL FRAME FOR 68882 SFB
	FRESTORE (SP)+                  RESTART COPROCESSOR (68882) SFB
	FMOVE.L #$FC00,FPCONTROL        ENABLE THE 881 EXCEPTIONS SFB

FRAME_OK EQU    *                       END OF 3.1 STOP KEY/68881 FIX SFB

	MOVEA.L ENDISRHOOK(A5),A0       CALL ISR HOOK TO ALLOW MULTI-TASKING
	JMP     (A0)

STOP    TRAP    #10

ADD_ERR MOVEA.L G_DOLLAR,A5             FIX A5
	MOVE.W  #-11,ESCAPECODE(A5)     SET ESCAPE CODE
	BRA.S   BE_INFO
BUS_ERR MOVEA.L G_DOLLAR,A5             FIX A5
	MOVE.W  #-12,ESCAPECODE(A5)     SET ESCAPE CODE
BE_INFO TST.B   M68KTYPE                                                (rdq)
	BEQ     BE_INFOA                                                (rdq)
*-(rdq)-new code for 680xx -----------------------------
	MOVE.W  (SP)+,EXCP_STATUS       SAVE RELEVANT DIAGNOSTIC INFO 680xx
	MOVE.L  (SP)+,EXCP_PC
E680XX  MOVE.W  (SP)+,EXCP_VOFFSET      other 680xx EXCEPTIONS enter here
	BTST    #7,EXCP_VOFFSET         ?0XX note: bit 6 is assumed 0
	BNE     BE02
	BTST    #6,EXCP_VOFFSET         0111 ? 68040
	BEQ     NOT_07                  68040
	MOVEM.L A0/D0,BE_END-8          68040 - got a $7 frame
*========================================================================
* All the code between the '=========' lines is unique to the problem
* of performing write-backs, if needed : $7 (68040) only. JWH 12/15/89.
*
	  MOVEM.L D1-D3,32(SP)    STEAL_IT uses D1-D3
WRITE_EM  JSR    STEAL_IT         steal the bus error vector
WB2       MOVE.W 8(SP),D0         get WB2 status byte from stack
	  BTST   #7,D0            see if we have a write to perform
	  BEQ    WB3              if not, check out WB3
*
* code added for bug discovered by Steve Elbinger. Before doing
* the write implied by WB2S, make sure the transfer type was
* not MOVE16 , i.e. TT (bits 4 and 3) are not 0, 1
	  BTST   #4,D0
	  BNE    DOO_IT           bit 4 = 1 so do it
	  BTST   #3,D0            bit 4 = 0 so check bit 3
	  BNE    WB3              it was TT = 01 so don't do it
* end of code to fix that bug
*
DOO_IT    PEA    WB3              address to 'recover' to
	  MOVEA.L 28(SP),A0       address to write to, from frame
	  BTST   #6,D0
	  BEQ    TRY_AGAIN2
	  MOVE.W 34(SP),D0        bit 6 = 1, word sized write
	  MOVE.W D0,(A0)          write it
	  NOP                     forces clean $7 frame if we B.E.
	  RTS                     puts us at WB3
TRY_AGAIN2 BTST #5,D0
	   BEQ  LONG_W2
	   MOVE.W 34(SP),D0       bit 6 = 0 bit 5 = 1, byte size
	   MOVE.B D0,(A0)
	   NOP
	   RTS                    puts us at WB3
LONG_W2    MOVE.L 32(SP),D0       bit 6 = 0 bit 5 = 0, long size
	   MOVE.L D0,(A0)
	   NOP
	   ADDQ  #4,SP            RTS would put us at WB3 , no point ...
WB3        MOVE.W 6(SP),D0        get WB3 status byte from stack
	   BTST  #7,D0            write pending ?
	   BEQ   CARRY_ON         carry on if not
	   PEA   CARRY_ON         place to 'recover' to
	   MOVEA.L 20(SP),A0      address to write to from stack
	   BTST   #6,D0
	   BEQ    TRY_AGAIN3
	   MOVE.W  26(SP),D0      bit 6 = 1, word sized write
	   MOVE.W  D0,(A0)
	   NOP
	   RTS                    lands us at CARRY_ON
TRY_AGAIN3 BTST #5,D0
	   BEQ  LONG_W3
	   MOVE.W  26(SP),D0      bit 6 = 0 bit 5 = 1, byte sized write
	   MOVE.B  D0,(A0)
	   NOP
	   RTS                    lands us at carry_on
LONG_W3    MOVE.L 24(SP),D0       bit 6 = 0, bit 5 = 0, long size
	   MOVE.L D0,(A0)
	   NOP
	   ADDQ    #4,SP    RTS puts us at CARRY_ON, no point ...
CARRY_ON   JSR     RES_IT   restore the bus error vector
	   MOVEM.L 32(SP),D1-D3    STEAL_IT used D1-D3
*========================================================================
* Rest of the $7 processing is just like we didn't have to worry about
* the possibility of writing anything back ...
*
	LEA     ERR_INFO,A0             68040
	MOVEQ   #12,D0                  68040 - 13 words to pitch
BE07    MOVE.L  (SP)+,(A0)+             68040
	DBRA    D0,BE07                 68040
	MOVEM.L BE_END-8,A0/D0          68040
	BRA     ESCNA                   68040
NOT_07  BTST    #5,EXCP_VOFFSET         00?X
	BEQ     ESCNA                   000X either 0000 or 0001
* Note - 001X could be a 0011 starting with the 68040
* Both $2 and $3 frames have 6 words, however, so
* For this purpose we can treat a $3 as a $2 ...
	MOVE.L  (SP)+,ERR_PC            001X assumed to be 0010
	BRA     ESCNA
*
BE02    MOVEM.L A0/D0,BE_END-8  SAVE SCRATCH REGS
	LEA     ERR_INFO,A0     FRONT OF SAVE AREA
	MOVEQ   #2,D0           SET FOR 1001
	BTST    #4,EXCP_VOFFSET         10X?
	BEQ.S   BE04
	BTST    #5,EXCP_VOFFSET         10?1
	BEQ.S   BE06    IF 0 THEN HAVE  1001
	MOVEQ   #18,D0          1011 (LONG 68020 EXECPTION)
BE03    MOVE.L  (SP)+,(A0)+
	DBRA    D0,BE03
	MOVEM.L BE_END-8,A0/D0  RESTORE SCRATCH REGS
	MOVE.L  (SP)+,BE_END_L_20-8     SAVE LAST 2 LONG WORDS
	MOVE.L  (SP)+,BE_END_L_20-4
	BRA.S   ESCNA
*
BE04    MOVEQ   #5,D0           SET FOR 1010
	BTST    #5,EXCP_VOFFSET         10?0
	BNE     BE06
	MOVE.W  (SP)+,(A0)+     HAVE 1000 MUST BE 68010
	MOVEQ   #11,D0
BE06    MOVE.L  (SP)+,(A0)+     MOVE FROM STACK TO SAVE AREA
	DBRA    D0,BE06
	MOVEM.L BE_END-8,A0/D0  RESTORE SCRATCH REGS
	BRA.S   ESCNA

*-------------------------------------------------------
BE_INFOA MOVE.W (SP)+,BE_SSW            SAVE RELEVANT DIAGNOSTIC INFO 68000
	MOVE.L  (SP)+,BE_FAULT_ADDR
	MOVE.W  (SP)+,BE_INSTR
	BRA.S   ESCN                    THE REST IS LIKE OTHER EXCEPTIONS

ESC     MOVE.L  A5,-(SP)                SAVE A5
	MOVEA.L 4(SP),A5                GET CODE POINTER
	MOVE.W  (A5),6(SP)              SAVE CODE
	MOVEA.L G_DOLLAR,A5
	MOVE.W  6(SP),ESCAPECODE(A5)    SET ERROR CODE
	MOVEA.L (SP)+,A5                RESTORE A5
	ADDQ.L  #4,SP                   POP SCRATCH SPACE

ESCN    MOVE.W  (SP)+,EXCP_STATUS       SAVE EXCEPTION DIAGNOSTIC INFO
	MOVE.L  (SP)+,EXCP_PC
	TST.B   M68KTYPE                                                (rdq)
	BNE     E680XX                                                  (rdq)
	CLR.W   EXCP_VOFFSET                                            (rdq)
ESCNA   MOVE.L  A0,-(SP)                SAVE A0                         (rdq)
	MOVE.L  #-1,EXCP_LINE           TRY TO GET LINE #
	MOVEA.L LASTLINE,A0
	CMPI.W  #$4E40,(A0)+            TRAP 0 ?
	BNE.S   NO_LINE
	CLR.W   EXCP_LINE
	MOVE.W  (A0),EXCP_LINE+2        FOUND LINE #
NO_LINE MOVEA.L (SP)+,A0                RESTORE A0
	JSR     DEBUGESCAPE             DEBUGGER HOOK
	TRAP    #11
	ADDQ.L  #2,SP                                                   (rdq)
	MOVEA.L G_DOLLAR,A5             FIX A5

* TRY TO DETECT CASES OF INTERRUPTED SUPERVISOR CALLS DURING USER PROGRAM
	MOVEA.L RECOVERBLOCK(A5),A0
	CMPA.L  SP,A0
	BGE.S   TEST_2
	BCLR    #5,EXCP_STATUS          MOVE BACK TO USER MODE BECAUSE USER
	BRA.S   NORMAL_RECOVER            STACK IS BELOW SUPERVISOR STACK
TEST_2  CMPA.L  INITRECOVER,A0
	BNE.S   NORMAL_RECOVER
	MOVE    INITSR,EXCP_STATUS      INITSR WAS SAVED WHEN INITRECOVER WAS

NORMAL_RECOVER  EQU *
	MOVE    EXCP_STATUS,SR          RETURN TO USER MODE
	MOVE.L  RECOVERBLOCK(A5),-(SP)  GO CLOSE ALL FILES ABOVE NEW (SP)
	BSR     ASM_CLOSEFILES
	MOVEA.L RECOVERBLOCK(A5),SP     CUT BACK USER's stack
	RTS

*=====================================================================
* Next 3 added for 68040 support Jwh 12/15/89, in particular the
* problem of performing write-backs.
* The fake bus error handler : just pitch the whole exception frame
TOSS_IT        EQU *
	       ADDA  #60,SP
	       RTS
* Steals the bus error vector, puts in the fake :
STEAL_IT       EQU *
	       MOVEM.W  buserrvec,D1-D3
	       MOVE.W   #JMP,buserrvec
	       MOVE.L   #TOSS_IT,buserrvec+2
* added 9/24/90 : flush i-cache after you take over
	       trap  #11
	       CPUSHA  IC/DC     just to be sure
	       move    (SP)+,SR
	       RTS
* Restores previous bus error vector :
RES_IT         EQU *
	       MOVEM.W  D1-D3,buserrvec
	       trap #11
	       CPUSHA   IC/DC      just to be sure
	       move     (SP)+,SR
	       RTS
*=====================================================================

P_BREAK SUBQ.L  #2,2(SP)        BACKUP TO OPCODE
	MOVE.L  2(SP),LASTLINE  SAVE THE PC
	ADDQ.L  #4,2(SP)        BUMP RETURN ADDRESS TO SKIP LINE NUMBER
	RTE                     RETURN FROM TRAP #0

ESCAPE_PROTO    JSR     ESCAPE
	PAGE
*
* HANDLING LEVEL 7 KEYBOARD RESET INTERUPTS
*
MONITOR     EQU  $FF880024
KBDSTATUS   EQU  $00428003
KBDDATA     EQU  $00428001
KBDCOMMAND  EQU  $00428003
*
RESET_ISR   MOVEM.L D0-D7/A0-A6,-(SP)   SAVE REGISTERS
	    MOVE.B #$B2,KBDCOMMAND      TURN OFF INTERRUPT
	    BSR.S  GETCTRL
	    BSR.S  GETCTRL
	    BTST   #1,D1
	    BNE.S  RESETX
	    MOVEM.L     (SP)+,D0-D7/A0-A6       RESTORE REGISTERS
	    JMP    CTL_RESETV       WATCH IF OUT OF RANGE

TRYMONITOR  PEA    MONITOR
	    JSR    RTN_TO_MONITOR       WILL RETURN IF NO MONITOR
	    ADDQ   #4,SP                POP MONITOR ADDRESS     {rdq}
	    MOVEM.L D0-D7/A0-A6,-(SP)   SAVE REGISTERS
*
RESETX      EQU *
	    PEA         7                       DEBUGGER(7,0,0)
	    CLR.L       -(SP)
	    CLR.L       -(SP)
	    MOVEA.L     G_DOLLAR,A5
	    LEA         DEBUGGER(A5),A1
	    BSR         CALLPROC
	    MOVEM.L     (SP)+,D0-D7/A0-A6       RESTORE REGISTERS
	    JSR         DEBUGESCAPE             GIVE DEBUGGER ANOTHER SHOT

	    RESET                               NO DEBUGGER, GIVE UP, CLEAR I/O
	    MOVEQ       #16,D0                  WAIT 1..2 SECONDS
LP1         DBRA        D1,LP1
	    DBRA        D0,LP1
	    JSR         ASM_COPY_OFF            JWH 5/28/91
	    JSR         ASM_ICACHE_OFF           CLEAR BOTH CACHES 3/27/85
	    JSR         ASM_CACHE_OFF
	    CLR         -574                    THEN REBOOT FROM SCRATCH
	    JMP         448                     CALL BOOT ROM TO BOOT A SYSTEM
*
GETCTRL     BSR.S  STALL
	    MOVE.B #5,KBDCOMMAND
GA          BSR.S  STALL
	    BTST   #0,D0
	    BEQ    GA
	    MOVE.B KBDDATA,D1
	    AND    #$F0,D0
	    CMP    #$40,D0
	    BNE    GA
	    RTS
STALL       MOVE.B KBDSTATUS,D0
	    BTST   #1,D0
	    BNE    STALL
	    RTS
*                               SUPERCALL CODE MOVED TO ASM_POWERUP     (rdq)
*
ASM_INTLEVEL    EQU *                   FUNCTION TO RETURN INTERRUPT LEVEL
	TRAP    #11                     SHIFT TO SUPERVISOR MODE        (rdq)
	MOVE.W  (SP)+,D0                POP OFF STATUS REGISTER         (rdq)
	MOVE    D0,SR                   RETURN TO PREVIOUS MODE         (rdq)
	AND.L   #$00000700,D0           EXTRACT LEVEL
	LSR     #8,D0                   MOVE IT OVER
	MOVE.L  D0,4(SP)                RETURN INTEGER RESULT
	RTS

ASM_SETINTLEVEL   EQU *                 PROCEDURE TO SET INTERRUPT LEVEL
	MOVEA.L (SP)+,A0                RETURN ADDRESS
	MOVE.L  (SP)+,D0                INTEGER PARAMETER
	AND     #7,D0                   TAKE MOD 8 FOR SAFETY
	LSL     #8,D0                   MOVE IT OVER
	TRAP    #11                     MOVE INTO SUPERVISOR MODE
	MOVE    (SP)+,D1                GET CURRENT STATUS REGISTER
	AND     #$F8FF,D1               CLEAR CURRENT LEVEL
	OR      D1,D0                   COMBINE WITH NEW LEVEL
	MOVE    D0,SR                   RESTORE STATUS
	JMP     (A0)

	page
************************  PARITY ERROR CHECKER  **************************
*                                                                  JS 9/12/83
*     RETURNS WITH CC=EQ IF NOT PARITY ERROR,                      JS 9/12/83
*                                                                  JS 9/12/83
P_CHECK MOVEM.L D0-D1/A0,-(SP)    SAVE REGS WE WILL USE            JS 9/12/83
	MOVEA.L #-4,A0            SETUP FOR VECTOR SWAPPING        JS 9/13/83
	MOVE.L  (A0),-(SP)        SAVE OLD BERR VECTOR             JS 9/12/83
	MOVE.L  #IGNOREBUS,(A0)   SETUP DUMMY BUS ERROR VECTOR     JS 1/23/84
	MOVE.W  -(A0),-(SP)                                        JS 9/13/83
	MOVE.W  #JMP,(A0)                                          JS 9/13/83
	JSR     ASM_FLUSH_ICACHE                                   JS 3/25/85
	MOVEQ   #1,D0          ASSUME WE HAVE A PARITY ERROR       JS 9/12/83
	PEA     PBERR
	MOVE.L  SP,BESPTEMP
	MOVE.W  P_STATUS,D1    TRY TO READ STATUS WORD             JS 9/12/83
	ADDQ.L  #4,SP          IF READ OK WE HAVE PARITY ERROR     JS 9/12/83
P_CHECK1 TST    D0             DID WE HAVE A PARITY ERROR?         JS 9/12/83
	BEQ.S   P_RTS          IF NOT THEN RESTORE AND RETURN      JS 9/12/83
	MOVE.W  #0,P_STATUS    ELSE WE MUST CLEAR THE INTERRUPT    JS 9/12/83
	MOVE.W  #1,P_STATUS    AND RE-ENABLE IT                    JS 9/12/83
P_RTS   MOVE.W  (SP)+,(A0)+    RESTORE OLD BERR VECTOR             JS 9/12/83
	MOVE.L  (SP)+,(A0)                                         JS 9/13/83
	JSR     ASM_FLUSH_ICACHE                                   JS 3/25/85
	TST     D0             SET THE CC                          JS 9/12/83
	MOVEM.L (SP)+,D0-D1/A0 RESTORE REGS                        JS 9/12/83
	RTS                    AND RETURN                          JS 9/12/83
*                                                                  JS 9/12/83
PBERR   MOVEQ   #0,D0          CLEAR D0 -- NO PARITY ERR           JS 9/12/83
	JMP     P_CHECK1       AND RETURN FROM BUS ERR ROUTINE     JS 1/23/84
	PAGE
*************************** TIMER JUNK ***************************************

	def     init_timer      initialize timer: call at powerup/scratch a
	def     check_timer     call after ~1ms to check w/ bpl
	def     delay_timer     wait for x microseconds
	def     asm_ticker      read timer in itcs

	smode   sysflag2

timer_present   equ     1               1 if there is a timer, 0 if not


sysflag2        equ     $fffffeda
buserrvec       equ     $fffffffa       bus error vector


*************************************************************************
* look_for_timer
*   Determine if you have a timer chip on the processor board.
*   Try to read from the status register of the chip and see if you get
*   a bus error.
*************************************************************************

look_for_timer equ *
	move.l  buserrvec+2,-(sp)       save old bus error vector
	move.w  buserrvec,-(sp)
	move.w  #$4ef9,buserrvec
	move.l  #ignorebus,buserrvec+2  point buserr vector to service routine
	pea     buserr_serv
	move.l  sp,besptemp
	tst.b   $5f8003                 test for the timer
	addq.l  #4,sp
	bclr    #timer_present,sysflag2 there is a timer
	bra.s   skip1

buserr_serv equ *
	bset    #timer_present,sysflag2 there is no timer

skip1   move.w  (sp)+,buserrvec         restore original bus error vector
	move.l  (sp)+,buserrvec+2
	rts

*************************************************************************
* init_timer                            initialize the timer
*   outputs enabled
*   no interrupts
*   continuous operating mode
*   16 bit for counter 1 and 2, 8 bit for counter 3
*   external clock source
*   divide by 8 (temporary)
*
*   CR1         x000000r
*   CR2         x000000a
*   CR3         10000101
*     x - don't care
*     r - counter reset
*     a - address bit (selects CR1 or CR3)
*************************************************************************

init_timer equ *
	bsr     look_for_timer          look for hardware timer
	btst    #timer_present,sysflag2 if hardware timer present
	bne.s   itskp
	lea     $5f8000,a0              a0 = address of timer
	move.b  #$00,3(a0)              address CR3
	move.b  #$84,1(a0)              set up CR3    ($84 for no divide by 8)
	move.b  #$01,3(a0)              set up CR2 (address CR1)
	move.b  #$01,1(a0)              set up CR1, stop timer
	move.b  #$ff,9(a0)              set timer 2 to $ffff
	move.b  #$ff,11(a0)
	move.b  #$ff,13(a0)             set timer 3 to $ffff
	move.b  #$ff,15(a0)
	move.b  #$00,1(a0)              start timer
itskp   rts

*************************************************************************
* asm_ticker   function ticker:integer
*       sp+4 is the long word to contain the current timer value
*
*************************************************************************
asm_ticker equ *
	clr.l   4(sp)                   default value
	btst    #timer_present,sysflag2 if hardware timer present
	bne.s   rtskp2
	lea     $5f8000,a0              address of timer counter 2
	movep.l 9(a0),d0                read counter 2 and 3
	movep.l 9(a0),d1                read them again
	eor.l   d0,d1                   see if the upper word has changed
	swap    d1
	tst.w   d1
	beq.s   rtskp1
	   swap    d1
	   eor.l   d1,d0                use second reading if MSW has changed
rtskp1  move.l  d0,4(sp)
rtskp2  rts
*************************************************************************
* check_timer                           check the timer
*                                 Assumes timer is present!!
*
*   sp+4 contains a pointer to the timer control data structure:
*           timer_control_var: long word
*           first_time: boolean  (first byte after timer_control_var)
*     if first_time then timer_control_var contains the timeout in milliseconds
*     if not first_time then timer_control_var contains timeout clock image
*   use bpl or bmi to check for timeout (bpl will branch if not timed out yet)
*
*************************************************************************

check_timer equ *

	movem.l d0-d1/a0,-(sp)          save registers
*                                       read timer
	lea     $5f8000,a0              address of timer counter 2
	movep.l 9(a0),d0                read counter 2 and 3
	movep.l 9(a0),d1                read them again
	eor.l   d0,d1                   see if the upper word has changed
	swap    d1
	tst.w   d1
	beq.s   ctskp1
	   swap    d1
	   eor.l   d1,d0                use second reading if MSW has changed

ctskp1  equ     *                       timer value in d0
	movea.l 16(sp),a0               a0 = ^timeout value
	move.l  12(sp),16(sp)           move up return address
	tst.b   4(a0)                   first_time?
	bne     setup_timer             branch if first_time
	   cmp.l   (a0),d0              check for timeout (test with bpl)
	   movem.l (sp)+,d0-d1/a0       restore registers
	   addq.l  #4,sp                fix up stack
	   rts

setup_timer equ *
	move.l  (a0),d1                 d1 = delay in milliseconds
	lsl.l   #6,d1                   multiply by 250
	sub.l   (a0),d1
	lsl.l   #1,d1
	sub.l   (a0),d1
	lsl.l   #1,d1                   d1 = delay in tics (1 tic = 4 us)
	sub.l   d1,d0                   d0 = timeout value
	move.l  d0,(a0)+                store timeout value at a0^
	clr.b   (a0)                    first_time = false
	movem.l (sp)+,d0-d1/a0          restore registers
	addq.l  #4,sp                   fix up stack
	rts

*************************************************************************
* delay_timer                           wait for specified amount of time
*   sp+4 contains the amount of time to wait in microseconds (long integer)
*************************************************************************

delay_timer  equ  *
	movem.l d0-d1/a0,-(sp)
	btst    #timer_present,sysflag2 check for hardware timer

* Use the timer to measure delay.
* There is 218 cycles of overhead in addition to the timer amount.
* It takes 351 cycles to go through the routine once.

	bne.s   dlskp2
	lea     $5f8000,a0              address of timer
	movep.l 9(a0),d0                read counter 2 and 3
	movep.l 9(a0),d1                read them again
	eor.l   d0,d1                   see if the upper word has changed
	swap    d1
	tst.w   d1
	beq.s   dlskp1
	swap    d1
	eor.l   d1,d0                   use second reading if MSW has changed
dlskp1  move.l  16(sp),d1               d1 = delay in microseconds
	lsr.l   #2,d1                   d1 = delay in tics (1 tic = 4 us)
	subq.l  #3,d1                   subtract overhead outside timing loop
	sub.l   d1,d0                   d0 = timeout value

dlloop1 movep.l 9(a0),d1                read counter 2 and 3
	cmp.l   d0,d1                   compare timer value to timeout value
	bpl.s   dlloop1
	movem.l (sp)+,d0-d1/a0
	move.l  (sp)+,(sp)
	rts

* Use timing loop if no timer is present.
* Number of cycles = 230+31n

dlskp2  move.l  16(sp),d1               d1 = delay in microseconds
	lsr.l   #2,d1                   d1 = number of loops (1 loop = 4 us)
	subq.l  #7,d1                   subtract overhead outside loop (230/31)
dlloop2 subq.l  #1,d1                   timing loop
	nop
	nop
	bpl.s   dlloop2
	movem.l (sp)+,d0-d1/a0
	move.l  (sp)+,(sp)              pop parameter
	rts


	page
*       TRAPS:

*       ADDRESS         TRAP    ESCAPECODE      USUAL MEANING

*       $FFFFFF3A       15      (NONE)          DEBUGGER
*       $FFFFFF40       14      -21             UNASSIGNED
*       $FFFFFF46       13      -21             UNASSIGNED
*       $FFFFFF4C       12      -21             UNASSIGNED
*       $FFFFFF52       11      (NONE)          SUPERVISOR MODE
*       $FFFFFF58       10      "N"             ESCAPE N
*       $FFFFFF5E       9       (NONE)          NON LOCAL GOTO
*       $FFFFFF64       8        -3             DEREFERENCE NIL POINTER
*       $FFFFFF6A       7        -8             VALUE RANGE ERROR
*       $FFFFFF70       6        -9             CASE STATEMENT ERROR
*       $FFFFFF76       5        -5             DIVIDE BY ZERO
*       $FFFFFF7C       4        -4             INTEGER OVERFLOW
*       $FFFFFF82       3       -10             IORESULT <> 0
*       $FFFFFF88       2        -2             STACK OVERFLOW
*       $FFFFFF8E       1       (-2 IF ANY)     LINK A6 EMULATOR WITH STACK CHECK
*       $FFFFFF94       0       (NONE)          PASCAL LINE BREAKPOINT


*       SYSTEM EXCEPTIONS:

*       ADDRESS                 ESCAPECODE      USUAL MEANING

*       $FFFFFFC4               -13             1111 OPCODE
*       $FFFFFFCA               -13             1010 OPCODE
*       $FFFFFFD0               (NONE)          TRACE
*       $FFFFFFD6               -14             PRIVILEGE VIOLATION
*       $FFFFFFDC                -4             INTEGER OVERFLOW (TRAPV)
*       $FFFFFFE2                -8             CHK INSTRUCTION
*       $FFFFFFE8                -5             DIVIDE BY ZERO (HARDWARE)
*       $FFFFFFEE               -13             ILLEGAL INSTRUCTION
*       $FFFFFFF4               -11             ADDRESS ERROR
*       $FFFFFFFA               -12             BUS ERROR

	NOSYMS
	END .
@


54.2
log
@Added a call to ASM_COPY_OFF to make sure caches/memory are in
sync before jumpimg into the boot rom for reboot. This fixes
the shift-reset problem discovered by Wyco.
@
text
@d19 1
a19 1
	REFA    ASM_ICACHE_OFF,ASM_CACHE_OFF
@


54.1
log
@Automatic bump of revision number for PWS version 3.24
@
text
@d967 1
@


53.1
log
@Automatic bump of revision number for PWS version 3.24B
@
text
@@


52.1
log
@Automatic bump of revision number for PWS version 3.24A
@
text
@@


51.2
log
@Added code to push unsupported data type exceptions into m881serv in
the case of the 68040. This keeps the unsupported data type exception
handler from being completely bare if you have an '040. Correct and
complete error reporting requires that the FP40 package be installed
in the system.
@
text
@@


51.1
log
@Automatic bump of revision number for PWS version 3.24d
@
text
@d53 1
d337 13
@


50.1
log
@Automatic bump of revision number for PWS version 3.23c
@
text
@@


49.3
log
@
pws2rcs automatic delta on Mon Oct 29 14:00:44 MST 1990
@
text
@@


49.2
log
@Fixed two bugs :

1.) for the WB2S word, i wasn't checking that the transfer type
    field was NOT 01 before doing the write
2.) modified the routines which take over the bus error handler
    to flush the caches after the takeover AND restore
@
text
@d899 1
a899 1
	       move.w  (SP)+,SR
d906 1
a906 1
	       move.w   (SP)+,SR
@


49.1
log
@Automatic bump of revision number for PWS version 3.24b
@
text
@d741 11
a751 1
	  PEA    WB3              address to 'recover' to
d896 4
d904 3
@


48.1
log
@Automatic bump of revision number for PWS version 3.24a
@
text
@@


47.1
log
@Automatic bump of revision number for PWS version 3.23
@
text
@@


46.1
log
@Automatic bump of revision number for PWS version 3.23
@
text
@@


45.1
log
@Automatic bump of revision number for PWS version 3.23C
@
text
@@


44.1
log
@Automatic bump of revision number for PWS version 3.23B
@
text
@@


43.1
log
@Automatic bump of revision number for PWS version 3.23aA
@
text
@@


42.1
log
@Automatic bump of revision number for PWS version 3.23e
@
text
@@


41.2
log
@

        Change to load the spurious interrupt vector with
    a long absolute jump to an RTE.
@
text
@@


41.1
log
@Automatic bump of revision number for PWS version 3.23d
@
text
@d25 1
d53 1
d306 1
d340 10
@


40.7
log
@
pws2rcs automatic delta on Thu Dec 21 14:54:59 MST 1989
@
text
@@


40.6
log
@

           More comments to 'explain' what's goin on ...

           Jeff.
@
text
@d709 1
a709 1
	BEQ.S   BE_INFOA                                                (rdq)
d715 1
a715 1
	BNE.S   BE02
d866 1
a866 1
	       ADD  #60,SP
@


40.5
log
@

           Added comments to the changes I previously made to
      handle the possibility of write-backs.  JWH  12/15/89.
@
text
@d862 3
a864 1
* Next 3 added for 68040 support Jwh 12/15/89.
d868 1
d874 1
@


40.4
log
@

           Added code to perform write-backs if required
      when the exception handler gets a $7 frame.

           Jeff, 12/15/89.
@
text
@d719 11
a729 8
* 68040 : Perform write-backs if needed :
	  MOVEM.L D1-D3,32(SP)
WRITE_EM  JSR    STEAL_IT
WB2       MOVE.W 8(SP),D0
	  BTST   #7,D0
	  BEQ    WB3
	  PEA    WB3      address to recover to ...
	  MOVEA.L 28(SP),A0
d732 4
a735 4
	  MOVE.W 34(SP),D0
	  MOVE.W D0,(A0)
	  NOP
	  RTS
d738 1
a738 1
	   MOVE.W 34(SP),D0
d741 2
a742 2
	   RTS
LONG_W2    MOVE.L 32(SP),D0
d745 6
a750 6
	   ADDQ  #4,SP     RTS would put us at WB3 , no point ...
WB3        MOVE.W 6(SP),D0
	   BTST  #7,D0
	   BEQ   CARRY_ON
	   PEA   CARRY_ON
	   MOVEA.L 20(SP),A0
d753 1
a753 1
	   MOVE.W  26(SP),D0
d756 1
a756 1
	   RTS
d759 1
a759 1
	   MOVE.W  34(SP),D0
d762 2
a763 2
	   RTS
LONG_W3    MOVE.L 32(SP),D0
d768 5
a772 1
	   MOVEM.L 32(SP),D1-D3
@


40.3
log
@

          Just added a comment concerning the set up of exception
      processing for floating point exceptions. JWH 12/1/89.

@
text
@d719 47
d853 15
@


40.2
log
@

         Started making the changes for 68040 support. Modified 
    the frame format testing code near label E680XX to handle
    the new $7 frame format. JWH 12/1/89.
@
text
@d321 4
@


40.1
log
@Automatic bump of revision number for PWS version 3.23c
@
text
@d7 2
d712 10
a721 1
	BTST    #5,EXCP_VOFFSET         00?X
d723 3
@


39.1
log
@Automatic bump of revision number for PWS version 3.23b
@
text
@@


38.1
log
@Automatic bump of revision number for PWS version 3.23a
@
text
@@


37.1
log
@Automatic bump of revision number for PWS version 3.3a
@
text
@@


36.1
log
@Automatic bump of revision number for PWS version 3.22
@
text
@@


35.1
log
@Automatic bump of revision number for PWS version 3.22
@
text
@@


34.1
log
@Automatic bump of revision number for PWS version 3.22
@
text
@@


33.1
log
@Automatic bump of revision number for PWS version 3.22D
@
text
@@


32.1
log
@Automatic bump of revision number for PWS version 3.22C
@
text
@@


31.1
log
@Automatic bump of revision number for PWS version 3.22B
@
text
@@


30.1
log
@Automatic bump of revision number for PWS version 3.22A
@
text
@@


29.1
log
@Automatic bump of revision number for PWS version 3.22b
@
text
@@


28.1
log
@Automatic bump of revision number for PWS version 3.3b
@
text
@@


27.2
log
@Contains 68882 mid-instruction exception frame handling (also corrects
68881 handling) for STOP key.
SFB and RDQ
@
text
@@


27.1
log
@Automatic bump of revision number for PWS version 3.3a
@
text
@d354 2
d682 1
a682 1
	FSAVE   -156(SP)                FINALLY, TURN OFF 68881 BY DUMPING
d684 5
a688 1
*                                       IGNORED)
@


26.1
log
@Automatic bump of revision number for PWS version 3.3 Synch
@
text
@@


25.1
log
@Automatic bump of revision number for PWS version 3.2Y
@
text
@@


24.1
log
@Automatic bump of revision number for PWS version 3.2
@
text
@@


23.1
log
@Automatic bump of revision number for PWS version 3.2P
@
text
@@


22.1
log
@Automatic bump of revision number for PWS version 3.2N
@
text
@@


21.1
log
@Automatic bump of revision number for PWS version 3.2M
@
text
@@


20.1
log
@Automatic bump of revision number for PWS version 3.2L
@
text
@@


19.1
log
@Automatic bump of revision number for PWS version 3.2K
@
text
@@


18.1
log
@Automatic bump of revision number for PWS version 3.2J
@
text
@@


17.1
log
@Automatic bump of revision number for PWS version 3.2I+
@
text
@@


16.1
log
@Automatic bump of revision number for PWS version 3.2I
@
text
@@


15.1
log
@Automatic bump of revision number for PWS version 3.2H
@
text
@@


14.1
log
@Automatic bump of revision number for PWS version 3.2G
@
text
@@


13.1
log
@Automatic bump of revision number for PWS version 3.2F
@
text
@@


12.1
log
@Automatic bump of revision number for PWS version 3.2E
@
text
@@


11.1
log
@Automatic bump of revision number for PWS version 3.2D
@
text
@@


10.1
log
@Automatic bump of revision number for PWS version 3.2C
@
text
@@


9.1
log
@Automatic bump of revision number for PWS version 3.2B
@
text
@@


8.1
log
@Automatic bump of revision number for PWS version 3.2A
@
text
@@


7.1
log
@Automatic bump of revision number for PWS version 3.2l
@
text
@@


6.1
log
@Automatic bump of revision number for PWS version 3.2k
@
text
@@


5.1
log
@Automatic bump of revision number for PWS version 3.2j
@
text
@@


4.1
log
@Automatic bump of revision number for PWS version 3.2i
@
text
@@


3.1
log
@Automatic bump of revision number for PWS version 3.2h
@
text
@@


2.2
log
@Remove IAND, IOR, now moved to ASM.
@
text
@@


2.1
log
@Auto bump rev number to 2.1 for sys 3.2e.
@
text
@a12 1
	DEF     ASM_IAND,ASM_IOR
a867 11
ASM_IAND MOVEA.L (SP)+,A0
	MOVE.L  (SP)+,D0
	AND.L   (SP)+,D0
	MOVE.L  D0,(SP)
	JMP     (A0)

ASM_IOR MOVEA.L (SP)+,A0
	MOVE.L  (SP)+,D0
	OR.L    (SP)+,D0
	MOVE.L  D0,(SP)
	JMP     (A0)
@


1.1
log
@Initial revision
@
text
@@
