TITLE "MP6 by Douglas Jones" ; a trap handler to virtualize the hawk 1X 8X instruction ; as the new instruction, MOVEM dst,src ; M[R[dst]] = M[R[src]] ; NOTE: This code contains general features that are unneeded ; in this example -- parts of the code are designed to be shared ; with other trap handlers -- these are preserved here in order ; to minimize dissonance between this code and the Hawk manual. USE "hawk.h" USE "monitor.h" STACKSIZE = 20 ; a small stack available for local variables ; inside the trap handler. Count your local ; variables carefully and if more are required, ; enlarge this stack! ; Trap save area, fleshed out from Section 13.3 of the Hawk Manual ; this save area is used only by the illegal instruction trap. COMMON INSSAVEAREA, svSIZE + STACKSIZE myCODE = 0 <<2 ; pointer to trap-specific routine entry myPSW = 1 <<2 ; initial PSW to use for trap service svPC = 2 <<2 ; save area for PC svR1 = 3 <<2 ; save area for registers svR2 = 4 <<2 svR3 = 5 <<2 svR4 = 6 <<2 svR5 = 7 <<2 svR6 = 8 <<2 svR7 = 9 <<2 svR8 = 10 <<2 svR9 = 11 <<2 svRA = 12 <<2 svRB = 13 <<2 svRC = 14 <<2 svRD = 15 <<2 svRE = 16 <<2 svRF = 17 <<2 svPSW = 18 <<2 ; save area for PSW svMA = 19 <<2 ; save area for trap MA svSIZE = 20 <<2 ; size of register-save area ; initialize myCODE and myPSW fields of save area LCSAVE = . . = INSSAVEAREA + myCODE W INSHANDLER ; the initial PC for the handler . = INSSAVEAREA + myPSW W #00000000 ; the initial PSW for the handler . = LCSAVE SUBTITLE "trap vector entry" INSTRTRAP = #20 LCSAVE = . . = INSTRTRAP ; code modified from Section 13.3 of the Hawk manual CPUSET R2,TSV ; 2 save R2 LIL R2,SAVEREGS ; 4 get the save area pointer JUMPS R2 ; 2 join common code for all traps . = LCSAVE SAVEREGS: ; enter with R2 pointing to save area and stack LIL R2,INSSAVEAREA STORE R1,R2,svR1 STORE R3,R2,svR3 CPUGET R1,TSV CPUGET R3,TPC STORE R1,R2,svR2 STORE R3,R2,svPC CPUGET R1,TMA CPUGET R3,PSW STORE R1,R2,svMA STORE R3,R2,svPSW ; straightforward code to save R4-15 STORE R4,R2,svR4 STORE R5,R2,svR5 STORE R6,R2,svR6 STORE R7,R2,svR7 STORE R8,R2,svR8 STORE R9,R2,svR9 STORE RA,R2,svRA STORE RB,R2,svRB STORE RC,R2,svRC STORE RD,R2,svRD STORE RE,R2,svRE STORE RF,R2,svRF LOAD R3,R2,myPSW LOAD R1,R2,myCODE CPUSET R3,PSW ; may enable interrupts LEA R3,R2,svPC ; parameter ADDI R2,R2,svSIZE JSRS R1,R1 ; call trap service subroutine ADDI R2,R2,-svSIZE ; code to restore R4-15 LOAD R4,R2,svR4 LOAD R5,R2,svR5 LOAD R6,R2,svR6 LOAD R7,R2,svR7 LOAD R8,R2,svR8 LOAD R9,R2,svR9 LOAD RA,R2,svRA LOAD RB,R2,svRB LOAD RC,R2,svRC LOAD RD,R2,svRD LOAD RE,R2,svRE LOAD RF,R2,svRF LOAD R3,R3,svPSW LOAD R1,R2,svPC CPUSET R3,PSW ; disables interrupts CPUSET R1,TPC LOAD R3,R2,svR3 LOAD R1,R2,svR1 LOAD R2,R2,svR2 RTT ; return to user! SUBTITLE "Instruction trap service routine" MOVEM = #8010 ; the MOVEM opcode, documented as 1X 8X ; activation record, if needed ;RETAD = 0 SAVEDPC = 4 ARSIZE = 8 INSHANDLER: ; expects: R1 - return address ; R2 - activation record pointer, if needed ; R3 = Rsaved - pointer to array of saved registers, ; the saved PC is R0, R1-15 are consecutive ; the saved PSW is in word 16 of the array ; the saved memory address is in word 17. ; must return with R2 unchanged. ; all other registers may be modified. ; changes to saved registers will be restored on return from trap. LOADS R4,R3 ; savedPC = Rsaved[0] LOADS R5,R4 EXTH R5,R5,R4 ; instr = M[savedPC] LIL R6,#F0F0 AND R6,R5 ; opcode = instr & 0xF0F0 LIL R7,MOVEM CMP R6,R7 BNE INSNOT ; if (opcode == MOVEM) { -- emulate MOVEM ADDSI R4,2 ; savedPC = savedPC + 2 STORES R4,R3 ; Rsaved[0] = savedPC MOVE R6,R5 SR R6,8 TRUNC R6,4 ; src = (instr >> 8) & 0xF TRUNC R5,4 ; dst = (instr ) & 0xF ADDSL R6,R3,2 LOADS R6,R6 ; Rsrc = Rsaved[src] ADDSL R5,R3,2 LOADS R5,R5 ; Rdst = Rsaved[dst] LOADS R7,R6 STORES R7,R5 ; M[Rdst] = M[Rsrc] BR INSDONE INSNOT: ; } else { -- opcode != MOVEM ; -- force a halt for all other instructions STORES R0,R3 ; Rsaved[0] = 0; STORES R1,R2 ; -- save return address STORE R4,R2,SAVEDPC ; -- save saved PC ADDI R2,R2,ARSIZE LIL R1,DSPINI JSRS R1,R1 ; call dspini() -- reinitialize the display ADDI R2,R2,-ARSIZE LEA R3,INSMSG ; -- parameter ADDI R2,R2,ARSIZE LIL R1,PUTS JSRS R1,R1 ; call puts( "Instruction Trap, PC = " ) ADDI R2,R2,-ARSIZE LOAD R4,R2,SAVEDPC ; -- parameter ADDI R2,R2,ARSIZE LIL R1,PUTHEX JSRS R1,R1 ; call puthex( savedPC ) ADDI R2,R2,-ARSIZE LOADS R1,R2 ; -- recover return address INSDONE: ; } JUMPS R1 ; return INSMSG: ASCII "Instruction Trap, PC = ",0 END