home *** CD-ROM | disk | FTP | other *** search
- ; INPUT *************************************************************** #
- ; none #
- ; #
- ; OUTPUT ************************************************************** #
- ; If exiting through isp_dacc... #
- ; a0 = failing address #
- ; d0 = FSLW #
- ; else #
- ; none #
- ; #
- ; ALGORITHM *********************************************************** #
- ; Decode the movep instruction words stored at EXC_OPWORD and #
- ; either read or write the required bytes from/to memory. Use the #
- ; _dmem_{read,write}_byte() routines. If one of the memory routines #
- ; returns a failing value, we must pass the failing address and a FSLW #
- ; to the _isp_dacc() routine. #
- ; Since this instruction is used to access peripherals, make sure #
- ; to only access the required bytes. #
-
- ; XDEF _moveperipheral ; emulate movep instruction
-
- ; XREF _dmem_read_byte ; read byte from memory
- ; XREF _dmem_write_byte ; write byte to memory
- ; XREF _isp_dacc ; handle data access error exception
-
- ; ###########################
- ; movep.(w,l) Dx,(d,Ay) #
- ; movep.(w,l) (d,Ay),Dx #
- ; ###########################
-
- EXC_AREGS equ 4+$20
- EXC_DREGS equ 4+$0
- EXC_PC equ 4+$42
-
- EXC_OPWORD equ $0
- EXC_EXTWORD equ $2
-
- _moveperipheral:
-
- move.l EXC_PC(a7),a6
- move.w EXC_OPWORD(a6),d1 ; fetch the opcode word
-
- move.b d1,d0
- and.w #$7,d0 ; extract Ay from opcode word
-
- dc.w $2077,$0424 ; move.l (EXC_AREGS,a7,d0.w*4),a0 ; fetch ay
- ; lsl.w #2,d0
- ; move.l EXC_AREGS(a7,d0.w),a0
- ; lsr.w #2,d0
-
- add.w EXC_EXTWORD(a6),a0 ; add: an + sgn_ext(disp)
-
- btst #$7,d1 ; (reg 2 mem) or (mem 2 reg)
- beq.w mem2reg
-
- ; reg2mem: fetch dx, then write it to memory
- reg2mem:
- move.w d1,d0
- rol.w #$7,d0
- and.w #$7,d0 ; extract Dx from opcode word
-
- dc.w $2037,$0404 ; move.l (EXC_DREGS,a7,d0.w*4),d0 ; fetch dx
- ; lsl.w #2,d0
- ; move.l EXC_DREGS(a7,d0.w),d0
- ; lsr.w #2,d0
-
- btst #$6,d1 ; word or long operation?
- beq.b r2mwtrans
-
- ; a0 = dst addr
- ; d0 = Dx
- r2mltrans:
- move.l d0,d2 ; store data
- move.l a0,a2 ; store addr
- rol.l #$8,d2
- move.l d2,d0
-
- bsr.l _dmem_write_byte ; os : write hi
-
- tst.l d1 ; dfetch error?
- bne.w movp_write_err ; yes
-
- add.w #$2,a2 ; incr addr
- move.l a2,a0
- rol.l #$8,d2
- move.l d2,d0
-
- bsr.l _dmem_write_byte ; os : write lo
-
- tst.l d1 ; dfetch error?
- bne.w movp_write_err ; yes
-
- add.w #$2,a2 ; incr addr
- move.l a2,a0
- rol.l #$8,d2
- move.l d2,d0
-
- bsr.l _dmem_write_byte ; os : write lo
-
- tst.l d1 ; dfetch error?
- bne.w movp_write_err ; yes
-
- add.w #$2,a2 ; incr addr
- move.l a2,a0
- rol.l #$8,d2
- move.l d2,d0
-
- bsr.l _dmem_write_byte ; os : write lo
-
- tst.l d1 ; dfetch error?
- bne.w movp_write_err ; yes
-
- bra _movep_exit ; (rts)
-
- ; a0 = dst addr
- ; d0 = Dx
- r2mwtrans:
- move.l d0,d2 ; store data
- move.l a0,a2 ; store addr
- lsr.w #$8,d0
-
- bsr.l _dmem_write_byte ; os : write hi
-
- tst.l d1 ; dfetch error?
- bne.w movp_write_err ; yes
-
- add.w #$2,a2
- move.l a2,a0
- move.l d2,d0
-
- bsr.l _dmem_write_byte ; os : write lo
-
- tst.l d1 ; dfetch error?
- bne.w movp_write_err ; yes
-
- bra _movep_exit ; (rts)
-
- ; mem2reg: read bytes from memory.
- ; determines the dest register, and then writes the bytes into it.
- mem2reg:
- btst #$6,d1 ; word or long operation?
- beq.b m2rwtrans
-
- ; a0 = dst addr
- m2rltrans:
- move.l a0,a2 ; store addr
-
- bsr.l _dmem_read_byte ; read first byte
-
- tst.l d1 ; dfetch error?
- bne.w movp_read_err ; yes
-
- move.l d0,d2
-
- add.w #$2,a2 ; incr addr by 2 bytes
- move.l a2,a0
-
- bsr.l _dmem_read_byte ; read second byte
-
- tst.l d1 ; dfetch error?
- bne.w movp_read_err ; yes
-
- lsl.w #$8,d2
- move.b d0,d2 ; append bytes
-
- add.w #$2,a2 ; incr addr by 2 bytes
- move.l a2,a0
-
- bsr.l _dmem_read_byte ; read second byte
-
- tst.l d1 ; dfetch error?
- bne.w movp_read_err ; yes
-
- lsl.l #$8,d2
- move.b d0,d2 ; append bytes
-
- add.w #$2,a2 ; incr addr by 2 bytes
- move.l a2,a0
-
- bsr.l _dmem_read_byte ; read second byte
-
- tst.l d1 ; dfetch error?
- bne.w movp_read_err ; yes
-
- lsl.l #$8,d2
- move.b d0,d2 ; append bytes
-
- move.b EXC_OPWORD(a6),d1
- lsr.b #$1,d1
- and.w #$7,d1 ; extract Dx from opcode word
-
- dc.w $2F82,$1404 ; move.l d2,(EXC_DREGS,a7,d1.w*4) ; store dx
- ; lsl.w #2,d1
- ; move.l d2,EXC_DREGS(a7,d1.w)
- ; lsr.w #2,d1
-
- bra _movep_exit ; (rts)
-
- ; a0 = dst addr
- m2rwtrans:
- move.l a0,a2 ; store addr
-
- bsr.l _dmem_read_byte ; read first byte
-
- tst.l d1 ; dfetch error?
- bne.w movp_read_err ; yes
-
- move.l d0,d2
-
- add.w #$2,a2 ; incr addr by 2 bytes
- move.l a2,a0
-
- bsr.l _dmem_read_byte ; read second byte
-
- tst.l d1 ; dfetch error?
- bne.w movp_read_err ; yes
-
- lsl.w #$8,d2
- move.b d0,d2 ; append bytes
-
- move.b EXC_OPWORD(a6),d1
- lsr.b #$1,d1
- and.w #$7,d1 ; extract Dx from opcode word
-
- dc.w $3F82,$1406 ; move.w d2,(EXC_DREGS+2,a7,d1.w*4) ; store dx
- ; lsl.w #2,d1
- ; move.w d2,EXC_DREGS+2(a7,d1.w)
- ; lsr.w #2,d1
-
- bra _movep_exit ; (rts)
-
- ; if dmem_{read,write}_byte() returns a fail message in d1, the package
- ; must create an access error frame. here, we pass a skeleton fslw
- ; and the failing address to the routine that creates the new frame.
- ; FSLW:
- ; write = true
- ; size = byte
- ; TM = data
- ; software emulation error = true
- movp_write_err:
- move.l a2,a0 ; pass failing address
- move.l #$00a10001,d0 ; pass fslw
- bra.l _isp_dacc
-
- ; FSLW:
- ; read = true
- ; size = byte
- ; TM = data
- ; software emulation error = true
- movp_read_err:
- move.l a2,a0 ; pass failing address
- move.l #$01210001,d0 ; pass fslw
- bra.l _isp_dacc
-
- _dmem_read_byte:
- movem.l a1-a4,-(a7)
-
- move.l a7,a4 ; save for later
-
- dc.w $4E7A,$B801 ; movec vbr,a3
- ; sub.l a3,a3
-
- move.l $08(a3),a1 ; (bus err vector)
- lea _dmem_read_EXIT(pc),a2
- move.l a2,$08(a3)
-
- moveq #-1,d1
- move.b (a0),d0 ; read byte
- moveq #0,d1
-
- _dmem_read_EXIT:
- move.l a1,$08(a3) ; (bus err vector)
-
- move.l a4,a7 ; tidy up stack
-
- movem.l (a7)+,a1-a4
- rts
-
- _dmem_write_byte:
- movem.l a1-a4,-(a7)
-
- move.l a7,a4 ; save for later
-
- dc.w $4E7A,$B801 ; movec vbr,a3
- ; sub.l a3,a3
-
- move.l $08(a3),a1 ; (bus err vector)
- lea _dmem_write_EXIT(pc),a2
- move.l a2,$08(a3)
-
- moveq #-1,d1
- move.b d0,(a0) ; write byte
- moveq #0,d1
-
- _dmem_write_EXIT:
- move.l a1,$08(a3) ; (bus err vector)
-
- move.l a4,a7 ; tidy up stack
-
- movem.l (a7)+,a1-a4
- rts
-
- _isp_dacc: ; just ignore
-
- _movep_exit:
- addq.l #4,EXC_PC(a7)
- rts
-