;Exam2016H28秋設問１私家版挿入削除
MAIN START
;--挿入：４番目のデータとして#0444を挿入する。
    LAD GR0,#0444 ; データ
    LAD GR1,ROOT
    LAD GR2,4 ; n=4 番目に挿入する。
    LAD GR3,0 ;挿入処理命令
    CALL LPROC
;--削除：3番目のデータを削除する。
    LAD GR1,ROOT
    LAD GR2,3 ; n=3 番目を削除する。
    LAD GR3,1 ;削除処理命令
    CALL LPROC
    RET
;各要素のデータのアドレスが数珠つなぎであることを確認する。
ROOT DC DATA
DATA DC DATB
    DC #0AAA
DATB DC DATC
    DC #0BBB
DATC DC DATD
    DC #0CCC
DATD DC DATE
    DC #0DDD
DATE DC DATF
    DC #0EEE
DATF DC #0000
    DC #0000
;--------
;記憶管理領域
EXTDAT DC #FFFF
    DC 0
    DC #FFFF
    DC 0
    DC #FFFF
    DC 0
    DC #FFFF
    DC 0
    DC #FFFF
    DC 0
    DC #FFFF
    DC 0
    DC #FFFF
    DC 0
    END
;---------------
;以下は試験の問題文のコードそのままです。
LPROC START
    RPUSH
    LD GR4,GR2  ;GR4 <-- n
LP LD GR2,0,GR1 ;次の要素をたどる
    JZE FIN    ; n > N ?
    SUBA GR4,=1
    JZE NEXT   ;要素 Nに達したか？
    LD GR1,GR2 ;問a答エ 次のデータのアドレス
    JUMP LP
    ;---------------
NEXT LD GR3,LTBL,GR3
    JUMP 0,GR3 ;指定された処理へジャンプ
LINS LD GR4,GR2
    CALL EGET ;GR2<--挿入する要素の先頭アドレスが返る
    ST GR2,0,GR1 ;問b答ウ
    ST GR4,0,GR2 ;挿入する要素の１語目を設定
    ST GR0,1,GR2
    JUMP FIN
    ;----------------------
LDEL LD GR4,0,GR2 ;GR4<--要素 n+1の先頭アドレス
    ST GR4,0,GR1 ;要素n-1の１語目を再設定
    CALL EFREE   ;削除された要素nの領域を解放
FIN RPOP
    RET
LTBL DC LINS ;処理の分岐先アドレステーブル
    DC LDEL
    END
;----------------
;以下は試験の問題文にはないので
;題意に沿うように自作したコードです。
EGET START
    RPUSH
    LAD GR1,EXDAT
    LAD GR3,0
LOOP LD GR4,EXDAT,GR3
    JZE EXIT
    SUBL GR4,=#FFFF
    JZE SPARI
    LAD GR3,2,GR3
    JUMP    LOOP
SPARI LAD GR2,EXDAT,GR3
    ST GR2,RETGR2
    RPOP
    LD GR2,RETGR2
EXIT    RET
RETGR2 DS 1
;記憶管理領域
;MAIN関数の中に設置した方がよいかもしれない。
EXDAT DC #FFF0
    DC 0
    DC #FFFF
    DC 0
    DC #FFFF
    DC 0
    DC #FFFF
    DC 0
FIN DC #0000
    DC 0
    END
;----------------
;削除要素のアドレスはGR2に入れられてEFREEが呼ばれる。
;削除要素の先頭アドレスに#FFFFを格納して解放する。
;#FFFFを格納して解放の印とするのは問題文にはない独自仕様です。
EFREE START
    LAD GR0,#FFFF
    ST GR0,0,GR2
    RET
    END
;--------------
