home *** CD-ROM | disk | FTP | other *** search
/ APDL Public Domain 1 / APDL_PD1A.iso / program / virtual / VSI_C / a / VSImanass < prev    next >
Encoding:
Text File  |  1992-10-05  |  9.5 KB  |  276 lines

  1. ; > vsimanass
  2.  
  3. ; Assembler code for vsi manager
  4.  
  5. .include "a.IncAsm"
  6. .cinclude "c:h.swis"
  7.  
  8. .area  WA$$data
  9.  
  10.                     .EXTERN  VSI_Check
  11.                     .EXTERN  VSI_Service
  12.                     .EXTERN  Image$$ZI$$PBase
  13.                     .EXTERN  Image$$ZI$$PLimit
  14.  
  15. VSI_ZI_Base::       .ADDRESS Image$$ZI$$PBase
  16. VSI_ZI_Limit::      .ADDRESS Image$$ZI$$PLimit
  17.  
  18.  
  19. VSI_Old_Abort_Pre:: .LONG   0               ; void (*VSI_Old_Abort_Pre)(void);
  20. VSI_Old_Abort_Adr:: .LONG   0               ; void (*VSI_Old_Abort_Adr)(void);
  21.  
  22.  
  23. VSI_Stack:: .LONG   0
  24.  
  25. RegDump:    .LONG   0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
  26. RestartPC:  .LONG   0
  27.  
  28. VSI_RegDump:    .LONG   0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
  29. VSI_RestartPC:: .LONG   0
  30.  
  31.  
  32.  
  33. ;  Special code to deal with an emulated floating point
  34. ;  operation having a data abort
  35. ;  ********************************************************
  36. ;  ***** Rather heuristic and may fail with Risc-OS 3 *****
  37. ;  ********************************************************
  38. ;  Must be in supervisor mode in a module
  39. ;  The stack must have the registers in and nothing else.
  40. ;  and the saved pc should be for user mode.
  41. ;  Fp emulator seems to update all the registers correctly for
  42. ;  a data abort except the PC - whew, thank you Acorn.
  43.  
  44. Fp_Stack:   .LONG   0x01C01FC0              ; stack top-0x40, may change
  45.  
  46. Fp_data_abort:
  47.             MOV     r0, #0
  48.             LDR     r1, Fp_Stack
  49.             CMP     sp, r1
  50.             BNE     Do_Old_Abort
  51.             AND     r2, lr, #0x0C000003
  52.             CMP     r2, #3
  53.             BNE     Do_Old_Abort
  54.             LDR     r3, [r1, #4*pc]
  55.             TST     r3, #0x0C000003
  56.             BNE     Do_Old_Abort
  57.             ADR     r0, RegDump
  58.             LDMIA   sp!, {r1-r8}
  59.             STMIA   r0!, {r1-r8}
  60.             LDMIA   sp!, {r1-r7, lr}
  61.             ADD     lr, lr, #4              ; Make it look like a data abort
  62.             STMIA   r0!, {r1-r7, lr}
  63.             B       Fp_Comeback
  64.  
  65. ;  Pre-Fetch Abort
  66. ;  Undefined instruction in last word of page will
  67. ;  cause a pre-fetch abort first. This is handled
  68. ;  in Load_Page.
  69.  
  70. VSI_Int_Abort_Pre::
  71.             STR     r0, RegDump
  72.             ADR     r0, RegDump+4
  73.             STMIA   r0, {r1-lr}^            ; Dump User registers
  74.             MOV     r0, r0                  ; NOP
  75.             STR     lr, RegDump+4*pc
  76.             MVN     r0, #0                  ; Pre-Fetch , bit 20 set for read
  77.             TST     lr, #0x0C000003         ; Only handle VSI in User mode
  78.             BNE     Do_Old_Abort
  79.             SUB     r1, lr, #4              ; -> op to retry
  80.             STR     r1, RestartPC
  81.             BIC     r1, r1, #Status_bits    ; VSI address
  82.             B       Load_Page
  83.  
  84. ;  Data Abort
  85. ;  Restore any base address
  86. ;  Calculate address causing fault, or at least pointer
  87. ;  into valid page before the fault.
  88.  
  89. VSI_Int_Abort_Adr::
  90.             STR     r0, RegDump
  91.             ADR     r0, RegDump+4
  92.             STMIA   r0, {r1-lr}^            ; Dump User registers
  93.             MOV     r0, r0                  ; NOP
  94.             STR     lr, RegDump+4*pc
  95.             TST     lr, #0x0C000003         ; Only handle VSI in user mode
  96.             BNE     Fp_data_abort           ; Do special Emulated Fp frig
  97. Fp_Comeback:
  98.             SUB     r1, lr, #8              ; -> op to retry
  99.             STR     r1, RestartPC
  100.             BIC     r1, r1, #Status_bits
  101.  
  102. ; Now analyse the failing operation
  103. ;  r0 op code
  104. ;  r1 VSI address
  105. ;  r2 ->RegDump
  106. ;  r3 base register number
  107.  
  108.             ADR     r2, RegDump
  109. ;            LDRT    r0, [r1]                ; Get failing op
  110.             LDR     r0, [r1]                ; Get failing op
  111.             MOV     r3, r0, LSR #16
  112.             AND     r3, r3, #15             ; Get base register number
  113.             LDR     r1, [r2, r3, LSL #2]    ; And get the value
  114.             AND     r7, r0, #0x0E000000
  115.             CMP     r7, #0x04000000
  116.             CMPNE   r7, #0x06000000
  117.             BEQ     ldrstr
  118.             CMP     r7, #0x08000000
  119.             BEQ     ldmstm
  120.             CMP     r7, #0x0C000000
  121.             BEQ     ldcstc
  122.             AND     r7, r0, #0x0FB00000     ; & 0x0FB00FF0 = 0x01000090
  123.             CMP     r7, #0x01000000
  124.             ANDEQ   r7, r0, #0x00000FF0
  125.             CMPEQ   r7, #0x00000090
  126.             BNE     Do_Old_Abort
  127. swp:
  128.  
  129. ; Bit 20 = 0 for write op so leave op code in r0 unchanged
  130.             B       Load_Page
  131.  
  132. ;  Code for handling LDM, STM
  133. ;  Restore base if necessary (not if pc)
  134. ;  Calculate start transfer address
  135.  
  136. ldmstm:     AND     r5, r0, #0x00A00000
  137.             CMP     r5, #0x00800000         ; increment, no writeback
  138.             BEQ     indexedup
  139.             MOV     r5, #0                  ; Size of register list
  140.             MOVS    r6, r0, LSL #16         ; Top bits contain register list
  141. regcount:   ADDNE   r5, r5, #4              ; 4 bytes per register
  142.             SUB     r7, r6, #1              ; expose next 1 bit
  143.             ANDS    r6, r7, r6
  144.             BNE     regcount
  145.             TST     r0, #0x00200000         ; Writeback?
  146.             CMPNE   r3, #pc                 ; does not apply to pc
  147.             BEQ     NoWriteback
  148.             TST     r0, #0x00800000         ; Add offset to base?
  149.             SUBNE   r1, r1, r5              ; Reverse writeback
  150.             ADDEQ   r1, r1, r5
  151.             STR     r1, [r2, r3, LSL #2]    ; Base register restored
  152. NoWriteback:
  153.             TST     r0, #0x00800000         ; Add offset to base?
  154.             BNE     indexedup               ; Split incrementing and decrementing
  155.             SUB     r1, r1, r5
  156.             TST     r0, #0x01000000         ; Pre-indexing?
  157.             ADDEQ   r1, r1, #4
  158.             B       Load_Page
  159.  
  160. indexedup:  TST     r0, #0x01000000
  161.             ADDNE   r1, r1, #4
  162.             B       Load_Page
  163.  
  164. ;  Code for handling LDR and STR
  165. ;  Base does not need to be restored.
  166. ;  Immediate constant is 0..4095
  167. ;  Register offset is as for basic op except no shift by register.
  168.  
  169. ldrstr:     CMP     r3, #pc
  170.             BICEQ   r1, r1, #0xFC000003     ; Mask if base is pc
  171.             TST     r0, #0x01000000         ; Pre-indexing?
  172.             BEQ     Load_Page
  173.             TST     r0, #0x02000000         ; index is register?
  174.             BNE     indexreg
  175.             MOV     r5, r0, LSL #20
  176.             TST     r0, #0x00800000         ; Add offset to base?
  177.             ADDNE   r1, r1, r5, LSR #20
  178.             SUBEQ   r1, r1, r5, LSR #20
  179.             B       Load_Page
  180.  
  181. indexreg:   AND     r4, r0, #0x0000000F     ; contains index register
  182.             LDR     r4, [r2, r4, LSL #2]    ; And index value, keep psr if pc
  183.             AND     r5, r0, #0x00000FF0     ; Get shift operand
  184.             ORR     r5, r5, #0xE0000000+4   ; Cond AL, Index register
  185.             ORR     r5, r5, #(1<<12)+(1<<16)    ; base register, result
  186.             TST     r0, #0x00800000         ; Add offset to base?
  187.             ORRNE   r5, r5, #0x00800000     ; add
  188.             ORREQ   r5, r5, #0x00400000     ; sub
  189.             STR     r5, IndexAdd            ; mea maxima culpa
  190.             MOV     r0, r0                  ; NOP
  191. IndexAdd:   ADD     r1, r1, r4, LSL #2      ; ***** OVERWRITTEN OPERATION *****
  192.             B       Load_Page
  193.  
  194. ;  Code for handling Coprocessor data transfer
  195. ;  , not that I've got one!  Same code works for
  196. ;  the floating point emulator.
  197.  
  198. ldcstc:     CMP     r3, #pc
  199.             BICEQ   r1, r1, #0xFC000003     ; Mask if base is pc
  200.             AND     r5, r0, #0x000000FF
  201.             TST     r0, #0x00200000         ; Write-back?
  202.             CMPNE   r3, #pc                 ; does not apply to pc
  203.             BEQ     ldc_NoWriteback
  204.             TST     r0, #0x00800000         ; Add offset to base?
  205.             SUBNE   r1, r1, r5, LSL #2      ; Reverse writeback
  206.             ADDEQ   r1, r1, r5, LSL #2
  207.             STR     r1, [r2, r3, LSL #2]    ; Base register restored
  208. ldc_NoWriteback:
  209.             TST     r0, #0x01000000         ; Pre-indexing?
  210.             BEQ     Load_Page
  211.             TST     r0, #0x00800000         ; Add offset to base?
  212.             ADDNE   r1, r1, r5, LSL #2
  213.             SUBEQ   r1, r1, r5, LSL #2
  214.             B       Load_Page
  215.  
  216. ; Do old abort if anything wrong
  217. ; Only registers r0 to r7 at most changed
  218. ; before such an error is detected
  219.  
  220. Do_Old_Abort:
  221.             CMN     r0, #1
  222.             ADR     r0, RegDump
  223.             LDMIA   r0, {r0-lr}^
  224.             MOV     r0, r0
  225.             LDR     lr, RegDump+4*pc
  226.             LDREQ   pc, VSI_Old_Abort_Pre
  227.             LDRNE   pc, VSI_Old_Abort_Adr
  228.  
  229. ; Load Page
  230. ; Try to load a page of virtual store
  231. ; r0 = op, -1 if Pre_Fetch, bit 20 = 0 write else read
  232. ;   not used here
  233. ; r1 = address to load
  234.  
  235. Load_Page:
  236.             MOV    sl, sp, ASR #20
  237.             MOV    sl, sl, ASL #20
  238.             LDR    r2, RegDump+4*sp
  239.             BL     VSI_Check
  240.             CMP    r0, #0
  241.             BMI    Do_Old_Abort
  242.  
  243. ; Start up in user mode with interrupts enabled
  244. ; Should not cause another VSI interrupt whilst
  245. ; dealing with this one.
  246.  
  247.             TEQP    pc, #0
  248.             MOV     r0, r0
  249.  
  250.             CMP     r0, #0
  251.             BNE     Load_InUse
  252.  
  253.             ADR     r0, RegDump
  254.             ADR     r1, VSI_RegDump
  255.             LDMIA   r0!, {r2-r9}
  256.             STMIA   r1!, {r2-r9}
  257.             LDMIA   r0!, {r2-r9}
  258.             STMIA   r1!, {r2-r9}
  259.             LDR     r0, RestartPC
  260.             STR     r0, VSI_RestartPC
  261.  
  262. Load_InUse:
  263.             LDR     sl, VSI_Stack
  264.             LDR     sp, [sl, #12]           ; stack_size
  265.             ADD     sp, sp, sl
  266.             ADD     sl, sl, #0x230
  267.             BL      VSI_Service
  268.  
  269. ; Restore registers and return
  270.  
  271. VSI_Restore_Regs::
  272.             LDR     r0, VSI_RestartPC
  273.             STR     r0, VSI_RegDump+4*pc
  274.             ADR     r0, VSI_RegDump
  275.             LDMIA   r0, {r0-pc}^
  276.