
           ORG  #6000

;窠 室  樨  㫥
;ᨢ RW_MEMORY:

           JR   EMUL_1

;窠 室  樨  㫥
;ᨢ RW_MEMORY:

           JR   EMUL_2

;窠 室  ⠭ 
;祭 ᯮ㥬 祥 :

           JR   SET_UNUSED

 ࠬ 

; ࠡ뢠 :

MOD_START  DW   #C000

; ࠡ뢠 :

MOD_LEN    DW   #17A5

;ᨢ,    祩 
;࠭ 0, ᫨    뫮 -
;, 1 - ᫨  뫮 ⥭, 2 -
;᫨ ࢮ 뫠 :

RW_MEMORY  DW   #8000

; 設 ⥪  樨:

EMUL_STACK DW   #8000 ;⥪  !

; 楤 INIT . 
;(뢠 1 ࠧ  砫):

ADR_INIT   DW   #C000

; 楤 PLAY . :

ADR_PLAY   DW   #C005

;⢮ 맮 PLAY:

N_PLAY     DW   85*50

; 楤 STOP . 
;(뢠 1 ࠧ  ; ᫨ 
;㦭 - #0052).

ADR_STOP   DW   #C008

  

;室: 䫠 C 襭 - Ok,
;       ⠭ - , 㦥
;       㬥஢ , 
;        -  EM_PC.

EMUL_1     LD   HL,(RW_MEMORY) ;⪠
           LD   D,H            ;ᨢ.
           LD   E,L
           INC  DE
           LD   BC,(MOD_LEN)
           DEC  BC
           LD   (HL),0
           LDIR

;믮 楤 INIT:

EMUL_2     LD   HL,(ADR_INIT)
           CALL RUN_PROC
           RET  C

;믮 楤 PLAY:

           LD   HL,(N_PLAY)
LOOP_PLAY  PUSH HL
           LD   HL,(ADR_PLAY)
           CALL RUN_PROC
           POP  HL
           RET  C
           DEC  HL
           LD   A,H
           OR   L
           JR   NZ,LOOP_PLAY

;믮 楤 STOP:

           LD   HL,(ADR_STOP)
           CALL RUN_PROC
           RET

 ⠭ ᯮ㥬 祥 

SET_UNUSED LD   HL,(MOD_START)
           LD   DE,(RW_MEMORY)
           LD   BC,(MOD_LEN)

;᫨  ᨢ RW_MEMORY  ࠢ
;1, .. ࢮ砫쭮 祭 祩
; ᯮ짮,  ⠭
;祭 ⮩ 祩 ࠢ 祭
;।饩 -  襣 ᦠ.

UNUSED_1   LD   A,(DE)
           DEC  A
           JR   Z,UNUSED_2

           DEC  HL
           LD   A,(HL)
           INC  HL
           LD   (HL),A

UNUSED_2   INC  HL
           INC  DE
           DEC  BC
           LD   A,B
           OR   C
           JR   NZ,UNUSED_1

           RET

 믮 楤 

;室: HL -  楤.
;
;室:  ⠭ - 㦥
;㬥஢  䫠 C
;⠭ (  EM_PC -  ⮩
;),  - 襭.

RUN_PROC   LD   (EM_PC),HL

;⠭ ᮤন IY  SP 
;믮塞 楤:

           LD   HL,#5C3A
           LD   (EM_IY),HL
           LD   HL,(EMUL_STACK)
           LD   (EM_SP),HL

;믮塞:

           DI

           LD   HL,0
RUN_LOOP   PUSH HL
           CALL ONE_COMM
           POP  HL
           INC  HL
           JR   NC,RUN_LOOP

           EI

           AND  A  ;室?
           RET  Z

           SCF     ;㬥஢
           RET     ;.

;---------------------------------------
;ONE_COMM - 믮  .
;
;室: ᫨ 䫠 C 襭 - Ok; ,
;᫨ A=0 - ,  ⢫
;室  믮塞 楤 (RET);
;᫨ A=1 -   㬥-
;஢.

ONE_COMM   LD   DE,0  ; 
EM_PC      EQU  $-2

           LD   HL,0           ;⪠
           LD   (COMMAND),HL   ;
           LD   (COMMAND+2),HL ;

;㥬   :

           CALL READ_BYTE
           LD   A,(DE)
           LD   (COMMAND),A
           INC  DE

           CP   #CB
           JR   Z,PREFIX_CB
           CP   #ED
           JR   Z,PREFIX_ED
           CP   #DD
           JR   Z,PREFIX_I
           CP   #FD
           JR   Z,PREFIX_I

;--------   䨪 ---------

; ⠡ TBL_SIMPLE ।塞, 
;  :

           LD   H,0
           LD   L,A
           ADD  HL,HL
           LD   BC,TBL_SIMPLE
           ADD  HL,BC
           LD   A,(HL)

           PUSH HL

;७ᨬ ⮪  (᫨ 
;)  :

           AND  7     ; ⪠ + 1
           LD   B,A
           LD   HL,COMMAND+1

           JR   LOOP_MOVE

;------   䨪ᮬ #CB --------

; ᥣ 2 .  ⠥
; (HL), ᫨ 訥   ࠢ 6,
;  ࠡ⠥  .

PREFIX_CB  CALL READ_BYTE
           LD   A,(DE)
           LD   (COMMAND+1),A

           LD   A,2
           LD   (LEN_COM),A
           LD   HL,(EM_PC)
           INC  HL
           INC  HL
           LD   (EM_PC),HL

           LD   A,(DE)
           AND  7
           CP   6
           JR   NZ,TO_RUN

           LD   DE,(EM_HL)
           CALL READ_BYTE

;믮塞  ।⢥
;᪮:

TO_RUN     CALL RUN_COMM

           AND  A
           RET

;------   䨪ᮬ #ED --------

PREFIX_ED  CALL READ_BYTE
           LD   A,(DE)
           LD   (COMMAND+1),A
           INC  DE

;᫨ ன   䨪ᮬ, 
;뢠 ஢ - "㬥-
; ":

           CP   #CB
           JP   Z,ERROR
           CP   #ED
           JP   Z,ERROR
           CP   #DD
           JP   Z,ERROR
           CP   #FD
           JP   Z,ERROR

; ⠡ TBL_ED ।塞,  
; :

           LD   H,0
           LD   L,A
           ADD  HL,HL
           LD   BC,TBL_ED
           ADD  HL,BC
           LD   A,(HL)
           CP   undoc
           JP   Z,ERROR

           JR   MOVE_TAIL

;---   䨪ᮬ #DD  #FD ---

PREFIX_I   CALL READ_BYTE
           LD   A,(DE)
           LD   (COMMAND+1),A
           INC  DE

;᫨ ன  - #DD, #FD  #ED, 
;뢠 ஢ - "㬥-
; ":

           CP   #ED
           JP   Z,ERROR
           CP   #DD
           JP   Z,ERROR
           CP   #FD
           JP   Z,ERROR

           CP   #CB
           JR   Z,PR_I_CB

; ⠡ TBL_INDEX ।塞, 
;  :

           LD   H,0
           LD   L,A
           ADD  HL,HL
           LD   BC,TBL_INDEX
           ADD  HL,BC
           LD   A,(HL)

;     䨪ᠬ
;#DD, #FD  #ED...

MOVE_TAIL  PUSH HL

;७ᨬ ⮪  (᫨ 
;)  :

           AND  7     ; ⪠ + 1
           LD   B,A
           LD   HL,COMMAND+2

;     䨪 
;  䨪ᠬ #DD, #FD  #ED...

LOOP_MOVE  DEC  B
           JR   Z,MOVE_ALL
           CALL READ_BYTE
           LD   A,(DE)
           LD   (HL),A
           INC  DE
           INC  HL
           JR   LOOP_MOVE

;  , ⥯ ⠭
;EM_PC -  ᫥饩 :

MOVE_ALL   LD   DE,COMMAND
           AND  A
           SBC  HL,DE
           LD   A,L
           LD   (LEN_COM),A
           LD   DE,(EM_PC)
           ADD  HL,DE
           LD   (EM_PC),HL

           POP  HL

;⠫ ࠡ  : 
; 믮 ।⢥
;( ⮣  ᫥饬  ⠡ -
;ଠ  ⢨ ⮩  
;),   믮
;ᯥ樠쭮 ணࠬ,  ⮣ 
;᫥饬  -  .

           LD   A,(HL)
           INC  HL
           BIT  6,A
           JR   NZ,TO_SUBR

;ࠡ뢠 ⢨  .
;砫 ⥭:

           PUSH HL

           LD   A,(HL)
           RRA
           RRA
           RRA
           RRA
           AND  #0F
           LD   DE,S_READ
           CALL CALL_DE_A

           POP  HL

; :

           LD   A,(HL)
           AND  #0F
           LD   DE,S_WRITE
           CALL CALL_DE_A

;믮塞  ।⢥
;᪮:

           CALL RUN_COMM

           AND  A
           RET

; 믮 ணࠬ:

TO_SUBR    LD   A,(HL)
           LD   DE,S_RUN
           CALL CALL_DE_A

;᫨  믮 RET' ,
; SP=EMUL_STACK, , ந襫
;室  믮塞 楤. 
;ᥩ EM_PC=0.

           LD   HL,(EM_PC)
           LD   A,H
           OR   L
           RET  NZ

;믮 楤 祭:

           SCF
           RET  ;A=0

;᫥ #DD  #FD  䨪 #CB -
;  4 , ந室
;⥭    (IX+s) 
;(IY+s).

PR_I_CB    CALL READ_BYTE
           LD   A,(DE)
           LD   (COMMAND+2),A
           INC  DE

           CALL READ_BYTE
           LD   A,(DE)
           LD   (COMMAND+3),A

;  .

           CALL S_R1_INDEX

;⠭ EM_PC - 
;᫥饩 :

           LD   HL,(EM_PC)
           LD   DE,4
           ADD  HL,DE
           LD   (EM_PC),HL

;믮塞  ।⢥
;᪮:

           CALL RUN_COMM

           AND  A
           RET

;---------------------------------------
;室  㦥 㬥஢-
; :

ERROR      SCF
           LD   A,1
           RET

;---------------------------------------
;ணࠬ ࠡ⪨ ࠧ
;権,  믮塞 
;⢫ ⥭  .

S_READ     DW   #0052
           DW   S_R1_NN
           DW   S_R2_NN
           DW   S_R1_BC
           DW   S_R1_DE
           DW   S_R1_HL
           DW   S_R1_INDEX
           DW   S_R2_SP

;⥭     NN.
;   ᫥  .

S_R1_NN    LD   HL,COMMAND
           LD   D,0
           LD   A,0
LEN_COM    EQU  $-1   ; .
           SUB  2
           LD   E,A
           ADD  HL,DE
           LD   E,(HL)
           INC  HL
           LD   D,(HL)
           CALL READ_BYTE
           RET

;⥭  ⮢   NN.
;   ᫥  .

S_R2_NN    CALL S_R1_NN
           INC  DE
           CALL READ_BYTE
           RET

;⥭     (BC).

S_R1_BC    LD   DE,(EM_BC)
           CALL READ_BYTE
           RET

;⥭     (DE).

S_R1_DE    LD   DE,(EM_DE)
           CALL READ_BYTE
           RET

;⥭     (HL).

S_R1_HL    LD   DE,(EM_HL)
           CALL READ_BYTE
           RET

;⥭     (IX+s)
; (IY+s). ᫨    -
;#DD,  IX, ᫨ #FD - IY.
;⭮⥫쭮 ᬥ饭 s -  쥬
; .

S_R1_INDEX LD   HL,(EM_IX)
           LD   A,(COMMAND)
           CP   #DD
           JR   Z,S_R1_I2
           LD   HL,(EM_IY)

S_R1_I2    LD   A,(COMMAND+2)
           LD   C,A
           RLA
           SBC  A,A ;塞  ᫮
           LD   B,A
           ADD  HL,BC
           EX   DE,HL

           CALL READ_BYTE
           RET

;⥭  ⮢   (SP).

S_R2_SP    LD   DE,(EM_SP)
           CALL READ_BYTE
           INC  DE
           CALL READ_BYTE
           RET

;---------------------------------------
;ணࠬ ࠡ⪨ ࠧ
;権,  믮塞 
;⢫   .

S_WRITE    DW   #0052
           DW   S_W1_NN
           DW   S_W2_NN
           DW   S_W1_BC
           DW   S_W1_DE
           DW   S_W1_HL
           DW   S_W1_INDEX
           DW   S_W2_SP

;     NN.
;   ᫥  .

S_W1_NN    LD   HL,COMMAND
           LD   D,0
           LD   A,(LEN_COM)
           SUB  2
           LD   E,A
           ADD  HL,DE
           LD   E,(HL)
           INC  HL
           LD   D,(HL)
           CALL WRITE_BYTE
           RET

;  ⮢   NN.
;   ᫥  .

S_W2_NN    CALL S_W1_NN
           INC  DE
           CALL WRITE_BYTE
           RET

;     (BC).

S_W1_BC    LD   DE,(EM_BC)
           CALL WRITE_BYTE
           RET

;     (DE).

S_W1_DE    LD   DE,(EM_DE)
           CALL WRITE_BYTE
           RET

;     (HL).

S_W1_HL    LD   DE,(EM_HL)
           CALL WRITE_BYTE
           RET

;     (IX+s)
; (IY+s). ᫨    -
;#DD,  IX, ᫨ #FD - IY.
;⭮⥫쭮 ᬥ饭 s -  쥬
; .

S_W1_INDEX LD   HL,(EM_IX)
           LD   A,(COMMAND)
           CP   #DD
           JR   Z,S_W1_I2
           LD   HL,(EM_IY)

S_W1_I2    LD   A,(COMMAND+2)
           LD   C,A
           RLA
           SBC  A,A ;塞  ᫮
           LD   B,A
           ADD  HL,BC
           EX   DE,HL

           CALL WRITE_BYTE
           RET

;  ⮢   (SP-2).

S_W2_SP    LD   DE,(EM_SP)
           DEC  DE
           CALL WRITE_BYTE
           DEC  DE
           CALL WRITE_BYTE
           RET

;---------------------------------------
;ணࠬ ࠡ⪨  ।
;ࠢ  ࠡ  .

S_RUN      DW   S_DJNZ
           DW   S_JR
           DW   S_JRNZ
           DW   S_JRZ
           DW   S_JRNC
           DW   S_JRC
           DW   S_RETNZ
           DW   S_JPNZ
           DW   S_JP
           DW   S_CLNZ
           DW   S_RETZ
           DW   S_RET
           DW   S_JPZ
           DW   S_CLZ
           DW   S_CL
           DW   S_RETNC
           DW   S_JPNC
           DW   S_CLNC
           DW   S_RETC
           DW   S_JPC
           DW   S_CLC
           DW   S_RETPO
           DW   S_JPPO
           DW   S_CLPO
           DW   S_RETPE
           DW   S_JPHL
           DW   S_JPPE
           DW   S_CLPE
           DW   S_RETP
           DW   S_JPP
           DW   S_CLP
           DW   S_RETM
           DW   S_JPM
           DW   S_CLM
           DW   S_LDIR
           DW   S_CPIR
           DW   S_LDDR
           DW   S_CPDR
           DW   S_JPINDEX

S_DJNZ     LD   HL,EM_B
           DEC  (HL)
           RET  NZ
           JR   S_JR

S_JRNZ     LD   BC,%0100000001000000
           JR   S_JR_1

S_JRZ      LD   BC,%0100000000000000
           JR   S_JR_1

S_JRNC     LD   BC,%0000000100000001
           JR   S_JR_1

S_JRC      LD   BC,%0000000100000000

S_JR_1     LD   A,(EM_FLAGS)
           AND  B
           XOR  C
           RET  Z

S_JR       LD   HL,COMMAND
           LD   D,0
           LD   A,(LEN_COM)
           DEC  A
           LD   E,A
           ADD  HL,DE
           LD   A,(HL)
           LD   HL,(EM_PC)
           LD   C,A
           RLA
           SBC  A,A ;塞  ᫮
           LD   B,A
           ADD  HL,BC
           LD   (EM_PC),HL
           RET

S_JPNZ     LD   BC,%0100000001000000
           JR   S_JP_1

S_JPZ      LD   BC,%0100000000000000
           JR   S_JP_1

S_JPNC     LD   BC,%0000000100000001
           JR   S_JP_1

S_JPC      LD   BC,%0000000100000000
           JR   S_JP_1

S_JPPO     LD   BC,%0000010000000100
           JR   S_JP_1

S_JPPE     LD   BC,%0000010000000000
           JR   S_JP_1

S_JPP      LD   BC,%1000000010000000
           JR   S_JP_1

S_JPM      LD   BC,%1000000000000000

S_JP_1     LD   A,(EM_FLAGS)
           AND  B
           XOR  C
           RET  Z
           JR   S_JP

S_JPHL     LD   HL,(EM_HL)
           LD   (EM_PC),HL
           RET

S_JPINDEX  LD   HL,(EM_IX)
           LD   A,(COMMAND)
           CP   #DD
           JR   Z,S_JPI_1
           LD   HL,(EM_IY)
S_JPI_1    LD   (EM_PC),HL
           RET

S_CLNZ     LD   BC,%0100000001000000
           JR   S_CL_1

S_CLZ      LD   BC,%0100000000000000
           JR   S_CL_1

S_CLNC     LD   BC,%0000000100000001
           JR   S_CL_1

S_CLC      LD   BC,%0000000100000000
           JR   S_CL_1

S_CLPO     LD   BC,%0000010000000100
           JR   S_CL_1

S_CLPE     LD   BC,%0000010000000000
           JR   S_CL_1

S_CLP      LD   BC,%1000000010000000
           JR   S_CL_1

S_CLM      LD   BC,%1000000000000000

S_CL_1     LD   A,(EM_FLAGS)
           AND  B
           XOR  C
           RET  Z

S_CL       LD   DE,(EM_PC)
           LD   HL,(EM_SP)
           DEC  HL
           LD   (HL),D
           DEC  HL
           LD   (HL),E
           LD   (EM_SP),HL

S_JP       LD   HL,COMMAND
           LD   D,0
           LD   A,(LEN_COM)
           SUB  2
           LD   E,A
           ADD  HL,DE
           LD   E,(HL)
           INC  HL
           LD   D,(HL)
           LD   (EM_PC),DE
           RET

S_RETNZ    LD   BC,%0100000001000000
           JR   S_RET_1

S_RETZ     LD   BC,%0100000000000000
           JR   S_RET_1

S_RETNC    LD   BC,%0000000100000001
           JR   S_RET_1

S_RETC     LD   BC,%0000000100000000
           JR   S_RET_1

S_RETPO    LD   BC,%0000010000000100
           JR   S_RET_1

S_RETPE    LD   BC,%0000010000000000
           JR   S_RET_1

S_RETP     LD   BC,%1000000010000000
           JR   S_RET_1

S_RETM     LD   BC,%1000000000000000

S_RET_1    LD   A,(EM_FLAGS)
           AND  B
           XOR  C
           RET  Z

S_RET      LD   HL,(EM_SP)
           LD   DE,(EMUL_STACK)
           AND  A
           PUSH HL
           SBC  HL,DE
           POP  HL
           LD   DE,0
           JR   Z,S_RET_2

           LD   E,(HL)
           INC  HL
           LD   D,(HL)
           INC  HL
           LD   (EM_SP),HL

S_RET_2    LD   (EM_PC),DE
           RET

S_CPIR     LD   DE,(EM_HL)
           LD   BC,(EM_BC)
           LD   HL,(EM_A)  ;L:=EM_A

S_CPIR_1   CALL READ_BYTE
           LD   A,(DE)
           INC  DE
           DEC  BC
           CP   L
           JR   Z,RUN_COMM

           LD   A,B
           OR   C
           JR   NZ,S_CPIR_1

           JR   RUN_COMM

S_CPDR     LD   DE,(EM_HL)
           LD   BC,(EM_BC)
           LD   HL,(EM_A)  ;L:=EM_A

S_CPDR_1   CALL READ_BYTE
           LD   A,(DE)
           DEC  DE
           DEC  BC
           CP   L
           JR   Z,RUN_COMM

           LD   A,B
           OR   C
           JR   NZ,S_CPDR_1

           JR   RUN_COMM

S_LDIR     LD   HL,(EM_HL)
           LD   DE,(EM_DE)
           LD   BC,(EM_BC)

S_LDIR_1   EX   DE,HL
           CALL READ_BYTE
           EX   DE,HL
           CALL WRITE_BYTE

           INC  HL
           INC  DE
           DEC  BC
           LD   A,B
           OR   C
           JR   NZ,S_LDIR_1

           JR   RUN_COMM

S_LDDR     LD   HL,(EM_HL)
           LD   DE,(EM_DE)
           LD   BC,(EM_BC)

S_LDDR_1   EX   DE,HL
           CALL READ_BYTE
           EX   DE,HL
           CALL WRITE_BYTE

           DEC  HL
           DEC  DE
           DEC  BC
           LD   A,B
           OR   C
           JR   NZ,S_LDDR_1

           JR   RUN_COMM

;---------------------------------------
;믮 , 饭  :

EM_REGS            ;
EM_IY      DS   2  ;믮塞
EM_IX      DS   2  ;楤.
EM_HL_     DS   2
EM_DE_     DS   2
EM_BC_     DS   2
EM_AF_     DS   2
EM_HL      DS   2
EM_DE      DS   2
EM_BC      DS   2
EM_B       EQU  $-1
EM_FLAGS   DS   1
EM_A       DS   1
EM_REGS_E

RUN_COMM   LD   (SAVE_SP),SP
           LD   SP,EM_REGS
           POP  IY,IX,HL,DE,BC,AF
           EXX
           EX   AF,AF' 
           POP  HL,DE,BC,AF
           LD   SP,0
EM_SP      EQU  $-2

COMMAND    DS   4 ;. ᫨ 
                  ; 4 , 
                  ;⠫  ࠢ
                  ; ( NOP).
           DI
           LD   (EM_SP),SP
           LD   SP,EM_REGS_E
           PUSH AF,BC,DE,HL
           EXX
           EX   AF,AF' 
           PUSH AF,BC,DE,HL,IX,IY
           LD   SP,0
SAVE_SP    EQU  $-2

           RET

;---------------------------------------
;楤 READ_BYTE  WRITE_BYTE
;⠭ 祭 
;RW_MEMORY, ᮮ⢥饣 祩, 
;ன ந室 ⥭ ,
;ᮮ⢥⢥, 㤠 ந室 
;(᫨ 祩 ਭ   
;⮣    ந 権
;⥭  ).
;
;室:  DE -  祩.
;室: BC,DE,HL  .

READ_BYTE  LD   A,1
           JR   RW_BYTE

WRITE_BYTE LD   A,2
RW_BYTE    LD   (N_1_OR_2),A

           PUSH HL,DE,BC
           LD   HL,(MOD_START)
           LD   BC,(MOD_LEN)
           ADD  HL,BC
           EX   DE,HL
           SBC  HL,DE
           POP  BC,DE,HL
           RET  NC

           PUSH HL,DE
           LD   HL,(MOD_START)
           EX   DE,HL
           AND  A
           SBC  HL,DE
           JR   C,RW_BYTE_Q
           LD   DE,(RW_MEMORY)
           ADD  HL,DE
           LD   A,(HL)
           AND  A
           JR   NZ,RW_BYTE_Q
           LD   (HL),1        ;1  2
N_1_OR_2   EQU  $-1
RW_BYTE_Q  POP  DE,HL

           RET

;---------------------------------------
;楤 CALL_DE_A 믮
;ᥢ CALL (DE+A).

CALL_DE_A  LD   H,0
           LD   L,A
           ADD  HL,HL
           ADD  HL,DE
           LD   E,(HL)
           INC  HL
           LD   D,(HL)
           EX   DE,HL
           JP   (HL)
