misc/flineprivilege.s
;========================================================================================
; flineprivilege.s
; Copyright (C) 2003-2024 Makoto Kamada
;
; This file is part of the XEiJ (X68000 Emulator in Java).
; You can use, modify and redistribute the XEiJ if the conditions are met.
; Read the XEiJ License for more details.
; https://stdkmd.net/xeij/
;========================================================================================
;----------------------------------------------------------------------------------------
;
; flineprivilege.x
; MC68030でユーザモードのとき$FE00~$FFFFのどれで特権違反例外が発生するか調べます。
; 「.」はFライン例外が発生したものを示しており、「!」は特権違反例外が発生したものを示しています。
; cpSAVEまたはcpRESTOREでアドレッシングモードが正しい場合に限り、Fライン例外ではなく特権違反例外が発生します。
;
; 更新履歴
; 2024-11-29
; 公開。
;
;----------------------------------------------------------------------------------------
.include doscall.mac
.include iocscall.mac
.include control2.mac
.text
;結果のバッファを準備する
lea.l result_buffer,a2 ;a2=結果のバッファのポインタ
;自己書き換えするためキャッシュをOFFにする
moveq.l #-1,d3 ;d3=元のキャッシュモード
movem.l sp,-(sp)
cmpa.l (sp)+,sp
if ne ;68020以上
moveq.l #0,d2
moveq.l #4,d1
IOCS _SYS_STAT
move.l d0,d3
endif
;特権違反例外ベクタを保存して変更する
moveq.l #$08,d1 ;特権違反例外
lea.l privilege_routine,a1 ;特権違反例外処理ルーチン
IOCS _B_INTVCS
movea.l d0,a3 ;a3=元の特権違反例外ベクタ
;Fライン例外ベクタを保存して変更する
moveq.l #$0B,d1 ;Fライン例外
lea.l fline_routine,a1 ;Fライン例外処理ルーチン
IOCS _B_INTVCS
movea.l d0,a4 ;a4=元のFライン例外ベクタ
;$FE00~$FFFFを実行する
move.w #$FE00,d1 ;d1=命令コード
do
move.w d1,@f ;自己書き換え
nop
.align 4,$4E71 ;おまじない
@@: nop
addq.w #1,d1
moveq.l #63,d0 ;64桁毎に
and.w d1,d0
if eq
move.b #13,(a2)+ ;改行
move.b #10,(a2)+
else
moveq.l #15,d0 ;16桁毎に
and.w d1,d0
if eq
move.b #' ',(a2)+ ;空白
endif
endif
while <tst.w d1>,ne
;特権違反例外ベクタを復元する
moveq.l #$08,d1 ;特権違反例外
movea.l a3,a1 ;元の特権違反例外ベクタ
IOCS _B_INTVCS
;Fライン例外ベクタを復元する
moveq.l #$0B,d1 ;Fライン例外
movea.l a4,a1 ;元のFライン例外ベクタ
IOCS _B_INTVCS
;キャッシュモードを復元する
move.l d3,d2 ;元のキャッシュモード
if pl ;68020以上
moveq.l #4,d1
IOCS _SYS_STAT
endif
;結果を表示する
clr.b (a2)
pea.l result_buffer
DOS _PRINT
addq.l #4,sp
;終了する
DOS _EXIT
;特権違反例外処理ルーチン
privilege_routine:
move.b #'!',(a2)+
addq.l #2,2(sp) ;次の命令に進む
rte
;Fライン例外処理ルーチン
fline_routine:
move.b #'.',(a2)+
addq.l #2,2(sp) ;次の命令に進む
rte
.bss
;結果のバッファ
result_buffer:
.ds.b 4096