Login

Subversion Repositories NedoOS

Rev

Rev 1406 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

        DEVICE ZXSPECTRUM1024
        include "../_sdk/sys_h.asm"

DEBUG=0;1
CRUTCH=1 ;костыль для movb
DEBUGWR=0
BASIC=1;0

        include "bk.ini"

STACK=0x4000

;PC=0x4000...
;data=0xC000...
        include "macros.asm"

        org PROGSTART
begin
        jp init
initq
Reset
       ld a,(pgprog)
       SETPG4000
       jp resetpp

quiter
       ld a,(pgprog)
       SETPG4000
       jp farquiter

       if 0
jpiyer
        ld hl,jpiyer
        push hl
        jp (iy)
       endif

EMUCHECKQ
        ;call getflags_bc
        ;call makeflags_frombc
        ;call getflags_bc
       if DEBUG
      bit 0,e
      jr nz,$
      ld a,d
      sub 0x40
      cp 0x40
      jr nc,$

      push de
       decodePC
      if 1;0
       ;ld a,(_SP)
       ;rra
       ;jr c,$
       ;ld (oldpc),de
oldpcaddr=$+1
        ld hl,oldpc
        ld (hl),e
        inc l
        ld (hl),d
        inc l
        ld bc,(_R1)
        ld (hl),c
        inc l
        ld (hl),b
        inc l
        ld (oldpcaddr),hl
       endif
       ld a,d
       ;sub 0x40+((STARTPC/256)&0x3f);0x7c
       ;or e;cp 0x30
       ;cp 1
       ;jr z,$
      ld hl,0x954;0x228;0x8252;0x0318;0x32c8;0x3222;0x3262;0x1f74;0x0258;0x3dc8
      or a
      sbc hl,de
      pop de
      ;jr z,$
       endif
        get
        next
        ld c,a
        get
        next
        LD L,A
        ld H,MAINCOMS/256
        LD b,(HL)
        INC H
        LD H,(HL)
        ld L,b ;ac=cmd
        JP (HL)

;иначе pop iy запорет iy от обработчика прерывания
disable_iff0_keep_iy
      ;di
        ld (iykeeper_iy),iy
        ld a,55 ;scf
        ld (iykeeper_on),a ;keep hl,de!
        ret
;иначе pop iy запорет iy от обработчика прерывания
enable_iff0_remember_iy
iykeeper_iy=$+2
        ld iy,0
        ld hl,iykeeper_on
        ld (hl),55+128 ;or a ;keep a!
      ;ei
        ret

on_int
        PUSH AF,HL
        push bc,de
        exx
        push bc
        push de
        push hl
        push ix
        push iy
        ex af,af' ;'
        push af
        call oldimer ;делает ei!!! двигать позже нельзя, он ставит палитру в верхнем бордере и потом не будет второй раз!

        ;ld hl,(timer)
        ;inc hl
        ;ld (timer),hl
       ld a,0xf7
       in a,(0xfe)
       and 0b10101
       jp z,quiter ;1+3+5 = quit

       ld a,(curpg4000) ;ok
       push af
       ld a,(pgprog)
       SETPG4000

       ld a,0xf7
       in a,(0xfe)
       and 0b11000
on_int_oldchgfxmodekey=$+1
        cp 0
        ld (on_int_oldchgfxmodekey),a
        cp c
        jr z,on_int_nochgfxmode
       or a
       call z,changegfxmode ;4+5 = change gfx mode
on_int_nochgfxmode

        call KEYB
;iskeymessage=$
;        or a ;/scf
;        jr c,int_alreadyhavekey
       ;ld a,(bk_curkey)
       ;or a
       ;jr nz,int_alreadyhavekey
        call keyscan_getkey
       jr z,int_alreadyhavekey ;no keys in buf
        ld (bk_curkey),a
        ;ld a,55 ;"scf"
        ;ld (iskeymessage),a ;message
int_alreadyhavekey
       pop af
       SETPG4000
        ;OS_GETKEY
;        A - код символа(кнопки). Допустимые коды смотри в 'sysdefs.asm' секция 'Usable key codes'
;        C - код символа(кнопки) без учета текущего языкового модификатора. Как правило, используется для обработки "горячих кнопок"
;        DE - позиция мыши (y,x) (возвращает 0 при отсутствии фокуса)
;        L - кнопки мыши (bits 0(LMB),1(RMB),2(MMB): 0=pressed; bits 7..4=положение колёсика)
;        LX - Kempston joystick (0bP2JFUDLR): 1=pressed, - при отсутствии джойстика 0 (а не 0xff)
;        Флаг Z - если 0(NZ), то отсутствует фокус.
        pop af
        ex af,af' ;'
        pop iy
        pop ix
        pop hl
        pop de
        pop bc
        exx
        pop de,bc
       LD A,(iff1)
       OR A
       jr NZ,IMEREI
        POP HL,AF
        EI
       RET

IMEREI
        XOR A
        LD (iff1),A
;перед эмуляцией INT завершаем тек.команду (перехват на EMULOOP)
        LD (keepemuchecker),IY
        LD IY,IMINT
        POP HL,AF
        RET  ;di!

IMINT
keepemuchecker=$+2
        LD IY,0
iykeeper_on=$
        or a ;scf=on
        jr nc,IMINT_noiykeeperdata
        ld iy,(iykeeper_iy)
IMINT_noiykeeperdata

      ld a,(tpgs)
      SETPGC000

GKEYADR=$+1
        LD HL,KEYBUFF ;адрес конца списка

;04 -- ошибка шины/HALT/"СТОП"
;60 (0x30) -- клавиатура
;274 (0xbc) -- клавиатура с нажатой АР2
;на 11М еще 100 (0x40) -- кадровое прерывание
;10 (0x08) -- нелегальная команда
;ещё есть программные EMT/TRAP/BPT/IOT

      ld hl,(0x30+0xc000) ;pc
      ld bc,(0x30+0xc002) ;psw
      ld a,h
      or l
     ;xor a
      jp z,STIer ;костыль для неинициализированного прерывания

;должно вызываться только при нажатии на клавишу
        ld a,(bk_curkey)
        or a
        jp z,STIer

        ld a,-1
        LD (iff1),A ;почему-то сам обработчик в бейсике не выставляет??? но всё равно не работает ввод в бейсике
;gotoint
;push psw; push pc (адрес после команды)
       push hl
       call getflags_bc
        set 7,c ;interrupt enable
       putmemspBC

       decodePC_to_ae
        LD b,a
        ld c,e ;=old PC
       pop de ;new PC
        putmemspBC

       _LoopC_JP

       if 1;AFFLAG_16BIT
;как сформировать ZF,SF, не трогая AF?
;для этого надо сформировать число с нужными свойствами и сделать inc
         ;ZF SF AF OF
;ff даёт  1  0  1  0 ;имитирует флаги после inc ffff
;7f даёт  0  1  1  1 ;имитирует флаги после inc 7fff
;80 даёт  0  1  0  0 ;имитирует флаги после inc 8000
;8f даёт  0  1  1  0 ;имитирует флаги после inc 800f
;т.е. ff, 7f надо формировать только для 7fff, ffff
;а в остальных случаях надо брать (h&0x80) + (l&0x08)
;если l!=ff, l!=7f, то можно просто сделать inc l
;если l=ff, то нельзя просто сделать inc h - запортится AF!
inchlwithflags_l00 ;inc h needed
        inc h
        ret z ;set ZF=1(ok), AF=1(ok), OF=0(ok)
        jp pe,inchlwithflags_overflow
inchlwithflags_a0_setAF ;set ZF=0(ok), SF=h7(ok), AF=1, keep CY
;a=0
        jp m,$+5
        ld a,0x80 ;after dec: a7=h7
        dec a ;set ZF=0, SF=h7, AF=1, keep CY
        ret
incbcwithflags_c00 ;inc b needed
        inc b
        ret z ;set ZF=1(ok), AF=1(ok), OF=0(ok)
        jp po,inchlwithflags_a0_setAF
inchlwithflags_overflow
        exx
        ld e,0x80 ;overflow (e7!=e6)
        exx
        ret

inchlwithflags_l80 ;fix SF, keep AF=1, ZF=0
;a=0x80
        bit 7,h
        jr z,inchlwithflags_l80_p
inchlwithflags_l80_m
        ld a,0 ;keep CY!
        dec a ;00->ff ;set ZF=0, SF=h7, AF=1, keep CY
        ret
incbcwithflags_c80 ;fix SF, keep AF=1, ZF=0
;a=0x80
        bit 7,b
        jr nz,inchlwithflags_l80_m
inchlwithflags_l80_p
        dec a ;80->7f ;set ZF=0, SF=h7, AF=1, keep CY
        ret

dechlwithflags_fixflags
        ex af,af' ;'
        dec l
        ld a,l
        exx
        ld d,a ;parity data
        ld e,0 ;overflow data
        exx
        jr z,dechlwithflags_l00 ;maybe zero
        inc a
        jp pe,inchlwithflags_l80;dechlwithflags_l7f ;fix SF, keep AF=1, ZF=0
        ret nz
        dec h
        jp pe,inchlwithflags_overflow
        jr nz,inchlwithflags_a0_setAF ;set ZF=0, SF=h7, AF=1, keep CY
;a=0, hl=0x00ff
        inc a ;set ZF=0, SF=0, AF=0, keep CY
        ret
dechlwithflags_l00 ;maybe zero
;a=0
        inc h
        dec h
        ret z ;set ZF=1, SF=0, AF=0
        ld a,h
        res 0,a ;for ZF=0, AF=0
        inc a ;set ZF=0, SF=h7, AF=0, keep CY
        ret

decbcwithflags_fixflags
        ex af,af' ;'
        dec c
        ld a,c
        exx
        ld d,a ;parity data
        ld e,0 ;overflow data
        exx
        jr z,decbcwithflags_c00 ;maybe zero
        inc a
        jp pe,inchlwithflags_l80;dechlwithflags_l7f ;fix SF, keep AF=1, ZF=0
        ret nz
        dec b
        jp pe,inchlwithflags_overflow
        jr nz,inchlwithflags_a0_setAF ;set ZF=0, SF=h7, AF=1, keep CY
;a=0, bc=0x00ff
        inc a ;set ZF=0, SF=0, AF=0, keep CY
        ret
decbcwithflags_c00 ;maybe zero
;a=0
        inc b
        dec b
        ret z ;set ZF=1, SF=0, AF=0
        ld a,b
        res 0,a ;for ZF=0, AF=0
        inc a ;set ZF=0, SF=h7, AF=0, keep CY
        ret

       endif

recountpc_inc ;keep CY!
        inc d
        ret p ;<0x8000
        push af
        push bc
         dec de
         decodePC ;de->de
         inc de
        encodePC ;de->de, setpg
        pop bc
        pop af
        ret

inchnextpg
        inc h
        ret nz
hlnextpg
        push af
        push bc
        ld a,lx
        add a,0x40
        ;adc a,0
        ld c,a
        ld b,tpgs/256
        ld a,(bc)
        SETPGC000
        pop bc
        pop af
        ld h,0xc0
        ret

putscreen_c
putscreen_c_patch=$
PUTSCREEN_C_PATCH_MONO=0x3e
PUTSCREEN_C_PATCH_COLOR=0x18
        jr putscreen_c_color
       push hl
       push bc
       ld b,tmirror/256
       ld a,(bc)
       push af
;y=%TTYYYyyy
;hl=%01TTYYYy yyxxxxxx
       ld b,0
       bit 0,l
       jr z,$+4
       ld b,0x20
        ld a,l
        rra
        and 0x1f
       add hl,hl
       add hl,hl
       ld l,h
        ld h,ty/256
        ld c,(hl)
        inc h
        ld h,(hl) ;hc = ybase
        ld l,a
        add hl,bc
;addr=0x8000+(half*0x2000)+y*40+x
        ld a,(user_scr0_high) ;ok
        SETPG8000 ;TODO щёлкать только в color
       pop af
        ld (hl),a
       pop bc
       pop hl
        ret

putscreen_c_color
       push hl
       push bc
;y=%TTYYYyyy
;hl=%01TTYYYy yyxxxxxx
       ld b,0
       bit 0,l
       jr z,$+4
       ld b,0x20
        ld a,l
        rra
        and 0x1f
       add hl,hl
       add hl,hl
       ld l,h
        ld h,ty/256
        ld c,(hl)
        inc h
        ld h,(hl) ;hc = ybase
        ld l,a
        add hl,bc
;addr=0x8000+(half*0x2000)+y*40+x
        ld a,(user_scr0_low) ;ok
        SETPG8000
       pop bc
       push bc
        ld b,tleftpixels/256
        ld a,(bc)
        ld (hl),a
        ld a,c
        rlca
        rlca
        rlca
        rlca
        ld c,a
        ld a,(bc)
       push af
        ld a,(user_scr0_high) ;ok
        SETPG8000
       pop af
        ld (hl),a
       pop bc
       pop hl
        ret

getflags_bc
;формат PSW такой: IxxTNZVC
;разрешение прерываний -- маска 0200(0x80) в PSW
;T - разрешение трассировочного прерывания
        ex af,af' ;'
        push af
        ex af,af' ;'
        pop bc
;c=%SZ???V?C
        ld a,c ;flags
        ld bc,0
        add a,a
        jr nc,$+4
        set 3,c ;N=S
        jp p,$+5
        set 2,c ;Z
        rra ;a=flags
        rra
        jr nc,$+3
        inc c ;C
        rra
        rra
        jr nc,$+4
        set 1,c ;V
        ld a,(iff1)
       and 0x80
       or c
       ld c,a
        ret

makeflags_frombc
;c=IxxTNZVC
        ld a,c
        rla ;interrupt enable
        sbc a,a
        ld (iff1),a
        ld a,c
        ld c,0
        rra
        jr nc,$+3
        inc c ;C
        rra
        jr nc,$+4
        set 2,c ;V
        rra
        jr nc,$+4
        set 6,c ;Z
        rra
        jr nc,$+4
        set 7,c ;Z
;c=%SZ???V?C
        push bc
        ex af,af' ;'
        pop af
        ex af,af' ;'
        ret

STIer
        ld a,-1
        ld (iff1),a
       _LoopC

getmemspBCpp
        ld hl,(_SP)
        inc hl
        inc hl
        ld (_SP),hl
        dec hl
        dec hl
        ld a,h
        and 0xc0
        ld c,a
        ld b,tpgs/256
        set 7,h
        set 6,h
        ld a,(bc)
        SETPGC000
        ld c,(hl)
        inc l
        ld b,(hl)
        ret nz
        push bc
        ld hl,(_SP)
        dec hl
        ld a,h
        and 0xc0
        ld c,a
        ld b,tpgs/256
        set 7,h
        set 6,h
        ld a,(bc)
        SETPGC000
        pop bc
        ld b,(hl)
        ret

recountsp_inc
        push bc
        ld hl,(_SP)
        inc hl
        ld a,h
        and 0xc0
        ld c,a
        ld b,tpgs/256
        set 7,h
        set 6,h
        ld a,(bc)
        SETPGC000
        pop bc
        ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

getdest8_aisc
;out: c=dest, a=cmdLSB
;15-12 Opcode
;11-9 Src
;8-6 Register
;5-3 Dest
;2-0 Register
        rla
        and 0x0e
        ld l,a ;0000rrr0
        ld h,_R0/256
         ;ld l,(hl) ;TODO
        bit 3,c
        jr nz,rddest8_xx1
        bit 4,c
        jr nz,rddest8_x10
        bit 5,c
        jr nz,rddest8_100
;000 Register ;TODO pc
       cp 0x0e
       jr z,$
         ld a,c
        ld c,(hl)
        ret
rddest8_x10
        bit 5,c
        jp nz,rddest8_110
        jp rddest8_010
rddest8_xx1
        bit 4,c
        jr nz,rddest8_x11
        bit 5,c
        jp nz,rddest8_101
        jp rddest8_001
rddest8_x11
        bit 5,c
        jp nz,rddest8_111
        ;jp rddest8_011
;rddest8_011 ;@(Rn)+ ;всегда +=2
        ld a,l
       ld hx,c
        cp 0x0e
        jr z,rddest8_011_pc
        UNTESTED ;GOOD ;road2cafe ;нет в leopol
        ld c,(hl)
        inc l
        ld a,(hl)
        jp rdsrc8_addrfromaddr_ac
rddest8_011_pc
        UNTESTED ;GOOD ;bubbler ;нет в leopol
;инкремент не делаем, чтобы его делал putdest
        get
        inc e ;next без переключения страниц!!! FIXME
        ld c,a
        get
        dec e ;FIXME
        RDMEM8_ac_ret ;c=result, a=hx

rddest8_100
;100 -(Rn)
;при адресациях (reg)+ и -(reg), есть особый случай: если регистр -- это r6 или r7, то регистр всегда изменяется на 2, даже если команда байтовая
        ld a,l
       ld hx,c
       cp 0x0e
       jr z,$;rddest8_100_pc
        cp 0x0c
        ld c,(hl)
        inc l
        ld b,(hl)
        dec bc
       jr c,$+3
       dec bc ;sp/pc +=2
        UNTESTED
rdmem8_bc_to_c
        ld a,b
        RDMEM8_ac_ret ;c=result, a=hx

rddest8_101
        ld a,l
;101 @-(Rn) ;всегда -=2
       ld hx,c
       cp 0x0e
       jr z,$;rddest8_101_pc
        UNTESTED
        ld c,(hl)
        inc l
        ld b,(hl)
        dec bc
        dec bc
        ld a,b
        jp rdsrc8_addrfromaddr_ac

rddest8_110
        ld a,l
;X(Rn)
       ld hx,c
       cp 0x0e
       jr z,rddest8_110_pc
        GOOD ;pacman ;leopol демо2
        get
        inc e
        add a,(hl)
        ld c,a
        inc l
        get
        dec e ;FIXME
        adc a,(hl) ;ac=Rn+X
        RDMEM8_ac_ret ;c=result, a=hx
rddest8_110_pc ;for mona
        GOOD ;morf
        get
        inc e
        ld c,a
        ;inc l
        get
        dec e ;FIXME
        ld b,a
       decodePC_to_ae
      inc bc
      inc bc
        ld h,a
       ld a,c
       add a,e
       ld c,a
       ld a,b
       adc a,h ;ac=pc+X
        RDMEM8_ac_ret ;c=result, a=hx

rddest8_111
       ld a,l
;111 Index deferred: @X(Rn): Rn+X is the address of the address of the operand
       ld hx,c
       cp 0x0e
       jr z,rddest8_111_pc
        UNTESTED
        get
        inc e
        add a,(hl)
        ld c,a
        inc l
        get
        dec e ;FIXME
        adc a,(hl) ;ac=Rn+X
        jp rdsrc8_addrfromaddr_ac
rddest8_111_pc ;for leopol?
;[[pc+X]]
        UNTESTED ;GOOD ;leopold когда уже появилась грязь вместо мышей
        get
        inc e
        ld c,a
        ;inc l
        get
        dec e ;FIXME
        ld b,a
       decodePC_to_ae
      inc bc
      inc bc ;TODO надо ли?
        ld h,a
       ld a,c
       add a,e
       ld c,a
       ld a,b
       adc a,h ;ac=pc+X
        jp rdsrc8_addrfromaddr_ac

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;c=data, a=cmdLSB = %??fmtRRR
putdest8_Loop
;15-12 Opcode
;11-9 Src
;8-6 Register
;5-3 Dest
;2-0 Register
        ld h,a
        rla
        and 0x0e
        ld l,a ;0000rrr0
        ld a,h
        ld h,_R0/256
         ;ld l,(hl) ;TODO
        rla
        rla
        rla
        jp c,wrdest8_1xx
        add a,a
        jr c,wrdest8_01x
        jp m,wrdest8_001
;000 Register
        ld a,l
        cp 0x0e
        jp z,$;bctoPCLoop
        ld (hl),c ;не надо расширять знак (Alexander Tishin), кроме movb (см. там отдельно)
        _LoopC

wrdest8_001 ;(Rn): Rn contains the address of the operand
       ld a,l
       cp 0x0e
       jr z,$
        GOOD ;leopol начало
        ld a,(hl)
        inc l
        ld h,(hl)
        ld l,a
        WRMEM8_hl_LoopC
wrdest8_01x
        jp m,wrdest8_011
;wrdest_010 ;(Rn)+
;при адресациях (reg)+ и -(reg), есть особый случай: если регистр -- это r6 или r7, то регистр всегда изменяется на 2, даже если команда байтовая
        ld a,l
        cp 0x0c
        ld a,(hl)
       jr c,$+2+2+1
       jr nz,wrdest8_010_pc
       inc (hl) ;sp/pc +=2 ;TODO нечётный?
        GOOD ;leopol демо
        inc (hl)
        inc hl
        jr nz,$+2+3+2
         inc (hl)
         ld h,(hl)
         dec h
         jr $+3
       ld h,(hl)
        ld l,a
        WRMEM8_hl_LoopC
wrdest8_010_pc ;TODO так ли при dest=(pc+)? bkscope
        GOOD ;bkscope ;нет в leopol
        ld a,c
        ld (de),a
        next
        ;ld a,b
        ;ld (de),a
        next
       _LoopC

wrdest8_011 ;@(Rn)+
        ld a,l
        cp 0x0e
        jr z,wrdest8_011_pc
        UNTESTED
       push de
        ld e,(hl)
        inc l
        ld d,(hl)
        inc de
        inc de
        ld (hl),d
        dec l
        ld (hl),e
        dec de
        dec de
        ex de,hl
       pop de
wrdest8_memfrommem
       push bc
        ld a,h
        and 0xc0
        ld c,a
       ld lx,a
        ld b,tpgs/256
        set 7,h
        set 6,h
        ld a,(bc)
        SETPGC000
        ld b,(hl)
        inc l
        call z,inchnextpg
        ld h,(hl)
        ld l,b
       pop bc
        WRMEM8_hl_LoopC
wrdest8_011_pc
        GOOD ;pacman
        get
        next
        ld l,a
        get
        next
        ld h,a
        WRMEM8_hl_LoopC

wrdest8_1xx
        add a,a
        jp c,wrdest8_11x
        jp m,wrdest8_101
;wrdest8_100
;100 -(Rn)
;при адресациях (reg)+ и -(reg), есть особый случай: если регистр -- это r6 или r7, то регистр всегда изменяется на 2, даже если команда байтовая
        ld a,l
        cp 0x0c
       push de
        ld e,(hl)
        inc l
        ld d,(hl)
        dec de
       jr c,$+2+2+1
       jr nz,wrdest8_100_pc
       dec de ;sp/pc +=2
        GOOD ;leopol начало
        ld (hl),d
        dec l
        ld (hl),e
        ex de,hl
       pop de
     ;inc hl
       ;jr $
        WRMEM8_hl_LoopC
wrdest8_100_pc ;TODO так ли при -(pc)?
       jr $
       pop af ;skip
        decodePC
        dec de
        dec de
        encodePC
        ld a,c
        ld (de),a
       _LoopC

wrdest8_101
;101 @-(Rn) ;всегда -=2
       ld a,l
       cp 0x0e
       jr z,$;wrdest8_101_pc ;TODO pc
        UNTESTED
        ld c,(hl)
        inc l
        ld b,(hl)
        dec bc
        dec bc
        ld (hl),b
        dec l
        ld (hl),c
        ld h,b
        ld l,c
        jp wrdest8_memfrommem
wrdest8_11x
        jp m,wrdest8_111
;wrdest8_110
;110 Index: X(Rn): Rn+X is the address of the operand
       ld a,l
       cp 0x0e
       jr z,wrdest8_110_pc
        GOOD ;bkscope
        get
        next
        add a,(hl)
       push af
        inc l
        get
        next
        adc a,(hl)
        ld h,a
       pop af
        ld l,a ;hl=Rn+X
        WRMEM8_hl_LoopC
wrdest8_110_pc
        GOOD ;leopol начало
       push bc
        get
        next;inc e
        ld c,a
        get
        next;dec e
        ld b,a
       decodePC_to_ae
        ld h,a
        ld l,e
        add hl,bc ;hl=pc+X
       pop bc
        WRMEM8_hl_LoopC

wrdest8_111
;111 Index deferred: @X(Rn): Rn+X is the address of the address of the operand
       ld a,l
       cp 0x0e
       jr z,wrdest8_111_pc
        UNTESTED
        get
        next
        add a,(hl)
       push af
        inc l
        get
        next
        adc a,(hl)
        ld h,a
       pop af
        ld l,a ;hl=Rn+X
        jp wrdest8_memfrommem
wrdest8_111_pc
        GOOD ;pacman
       push bc
        get
        next;inc e
        ld c,a
        get
        next;dec e
        ld b,a
       decodePC_to_ae
        ld h,a
        ld l,e
        add hl,bc ;hl=pc+X
       pop bc
        jp wrdest8_memfrommem

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;a=cmdLSB = %??fmtRRR
getdest_aisc
;out: bc=dest, a=cmdLSB
;15-12 Opcode
;11-9 Src
;8-6 Register
;5-3 Dest
;2-0 Register
        rla
        and 0x0e
        ld l,a ;0000rrr0
        ld h,_R0/256
         ;ld l,(hl) ;TODO
        bit 3,c
        jr nz,rddest_xx1
        bit 4,c
        jr nz,rddest_x10
        bit 5,c
        jp nz,rddest_100
;000 Register
       cp 0x0e
       jr z,rddest_000_pc
         ld a,c
        ld c,(hl)
        inc l
        ld b,(hl)
        ret
rddest_000_pc ;cd.bk - TODO правильно ли? программа не работает
        GOOD ;basic
      ld hx,c
       decodePC_to_ae
       ld b,a
       ld c,e
      ld a,hx
        ret
rddest_x10
        bit 5,c
        jp nz,rddest_110
        jp rddest_010
rddest_xx1
        bit 4,c
        jr nz,rddest_x11
        bit 5,c
        jp nz,rddest_101
        jp rddest_001
rddest_x11
        bit 5,c
        jp nz,rddest_111
        ;jp rddest_011
;rddest_011 ;@(Rn)+ ;всегда +=2
       ld hx,c
        cp 0x0e
        jr z,rddest_011_pc
        GOOD ;road2cafe ;нет в leopol
        ld c,(hl)
        inc l
        ld a,(hl)
        jp rdsrc_addrfromaddr_ac
rddest_011_pc
        GOOD ;bubbler ;нет в leopol
;инкремент не делаем, чтобы его делал putdest
        get
        inc e ;next без переключения страниц!!! FIXME
        ld c,a
        get
        dec e ;FIXME
        RDMEM_ac_ret ;bc=result, a=hx

rddest_100
;100 -(Rn)
;при адресациях (reg)+ и -(reg), есть особый случай: если регистр -- это r6 или r7, то регистр всегда изменяется на 2, даже если команда байтовая
       ld hx,c
       cp 0x0e
       jr z,$;rddest_100_pc ;TODO pc
        GOOD ;sokoban ;нет в leopol
        ld c,(hl)
        inc l
        ld b,(hl)
        dec bc
        dec bc
        ld a,b
        RDMEM_ac_ret ;bc=result, a=hx

rddest_101
;101 @-(Rn) ;всегда -=2
       ld hx,c
       cp 0x0e
       jr z,rddest_101_pc
        UNTESTED
        ld c,(hl)
        inc l
        ld b,(hl)
        dec bc
        dec bc
        ld a,b
        jp rdsrc_addrfromaddr_ac
rddest_101_pc ;TODO
        jr $

rddest_110
;X(Rn)
       ld hx,c
       cp 0x0e
       jr z,rddest_110_pc
        GOOD ;leopol демо2
        get
        inc e
        add a,(hl)
        ld c,a
        inc l
        get
        dec e ;FIXME
        adc a,(hl) ;ac=Rn+X
        RDMEM_ac_ret ;bc=result, a=hx
rddest_110_pc ;for mona
        GOOD ;leopol начало
        get
        inc e
        ld c,a
        ;inc l
        get
        dec e ;FIXME
        ld b,a
       decodePC_to_ae
      inc bc
      inc bc
        ld h,a
       ld a,c
       add a,e
       ld c,a
       ld a,b
       adc a,h ;ac=pc+X
        RDMEM_ac_ret ;bc=result, a=hx

rddest_111
;111 Index deferred: @X(Rn): Rn+X is the address of the address of the operand
       ld hx,c
       cp 0x0e
       jr z,rddest_111_pc
        UNTESTED ;miraclebk
        get
        inc e
        add a,(hl)
        ld c,a
        inc l
        get
        dec e ;FIXME
        adc a,(hl) ;ac=Rn+X
        jp rdsrc_addrfromaddr_ac
rddest_111_pc ;for leopol?
;[[pc+X]]
        GOOD ;leopold когда уже появилась грязь вместо мышей
        get
        inc e
        ld c,a
        ;inc l
        get
        dec e ;FIXME
        ld b,a
       decodePC_to_ae
      inc bc
      inc bc ;TODO надо ли?
        ld h,a
       ld a,c
       add a,e
       ld c,a
       ld a,b
       adc a,h ;ac=pc+X
        jp rdsrc_addrfromaddr_ac

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;bc=data, a=cmdLSB = %??fmtRRR
putdest_Loop
;15-12 Opcode
;11-9 Src
;8-6 Register
;5-3 Dest
;2-0 Register
        ld h,a
        rla
        and 0x0e
        ld l,a ;0000rrr0
        ld a,h
        ld h,_R0/256
         ;ld l,(hl) ;TODO
        rla
        rla
        rla
        jp c,wrdest_1xx
        add a,a
        jr c,wrdest_01x
        jp m,wrdest_001
;000 Register
        ld a,l
        cp 0x0e
        jp z,bctoPCLoop
        ld (hl),c
        inc l
        ld (hl),b
        _LoopC
wrdest_001 ;(Rn): Rn contains the address of the operand
       ld a,l
       cp 0x0e
       jr z,$
        ld a,(hl)
        inc l
        ld h,(hl)
        ld l,a
        WRMEM_hl_LoopC
wrdest_01x
        jp m,wrdest_011
;wrdest_010 ;(Rn)+
;при адресациях (reg)+ и -(reg), есть особый случай: если регистр -- это r6 или r7, то регистр всегда изменяется на 2, даже если команда байтовая
;а тут небайтовая, значит, всегда +=2
        ld a,l
        cp 0x0e
       jr z,wrdest_010_pc
        GOOD ;textshow
       push de
        ld e,(hl)
        inc l
        ld d,(hl)
        inc de
        inc de
        ld (hl),d
        dec l
        ld (hl),e
        dec de
        dec de
        ex de,hl
       pop de
        WRMEM_hl_LoopC

wrdest_010_pc
;dest=(pc+) mona: mov r4,#0 ;space4k: dec #6000
        ld a,c
        ld (de),a
        next
        ld a,b
        ld (de),a
        next
       _LoopC

wrdest_011 ;@(Rn)+
        ld a,l
        cp 0x0e
        jr z,wrdest_011_pc
        GOOD;UNTESTED ;road2cafe после этого портит экран
       push de
        ld e,(hl)
        inc l
        ld d,(hl)
        inc de
        inc de
        ld (hl),d
        dec l
        ld (hl),e
        dec de
        dec de
        ex de,hl
       pop de
wrdest_memfrommem
       push bc
        ld a,h
        and 0xc0
        ld c,a
       ld lx,a
        ld b,tpgs/256
        set 7,h
        set 6,h
        ld a,(bc)
        SETPGC000
        ld a,(hl)
       push af
        inc l
        call z,inchnextpg
        ld h,(hl)
       pop af
        ld l,a
       pop bc
        WRMEM_hl_LoopC
wrdest_011_pc
        GOOD ;textshow
        get
        next
        ld l,a
        get
        next
        ld h,a
        WRMEM_hl_LoopC

wrdest_1xx
        add a,a
        jp c,wrdest_11x
        jp m,wrdest_101
;wrdest_100
;100 -(Rn)
;при адресациях (reg)+ и -(reg), есть особый случай: если регистр -- это r6 или r7, то регистр всегда изменяется на 2, даже если команда байтовая
        ld a,l
        cp 0x0e
        jr z,wrdest_100_pc
        GOOD ;textshow
       push de
        ld e,(hl)
        inc l
        ld d,(hl)
        dec de
        dec de
        ld (hl),d
        dec l
        ld (hl),e
        ex de,hl
       pop de
        WRMEM_hl_LoopC
wrdest_100_pc ;TODO так ли при -(pc)?
       jr $
        decodePC
        dec de
        dec de
        encodePC
        ld a,c
        ld (de),a
        inc e
        ld a,b
        ld (de),a
        dec e
       _LoopC

wrdest_101
;101 @-(Rn) ;всегда -=2
       ld a,l
       cp 0x0e
       jr z,$;rddest_101_pc ;TODO pc
        UNTESTED
        ld c,(hl)
        inc l
        ld b,(hl)
        dec bc
        dec bc
        ld (hl),b
        dec l
        ld (hl),c
        ld h,b
        ld l,c
        jp wrdest_memfrommem
wrdest_11x
        jp m,wrdest_111
;wrdest_110
;110 Index: X(Rn): Rn+X is the address of the operand
        ld a,l
       cp 0x0e
       jr z,wrdest_110_pc
        GOOD ;leopol демо3
        get
        next
        add a,(hl)
       push af
        inc l
        get
        next
        adc a,(hl)
        ld h,a
       pop af
        ld l,a ;hl=Rn+X
        WRMEM_hl_LoopC
wrdest_110_pc ;for mona, leopol
        GOOD ;leopol начало
       push bc
        get
        next;inc e
        ld c,a
        get
        next;dec e
        ld b,a
       decodePC_to_ae
        ld h,a
        ld l,e
        add hl,bc ;hl=pc+X
       pop bc
        WRMEM_hl_LoopC

wrdest_111
;111 Index deferred: @X(Rn): Rn+X is the address of the address of the operand
        ld a,l
       cp 0x0e
       jr z,wrdest_111_pc
        UNTESTED ;miraclebk
        get
        next
        add a,(hl)
       push af
        inc l
        get
        next
        adc a,(hl)
        ld h,a
       pop af
        ld l,a ;hl=Rn+X
        jp wrdest_memfrommem
wrdest_111_pc
;[[pc+X]]
        GOOD ;leopold глубоко во время игрового процесса (появление мышей?)
       push bc
        get
        next;inc e
        ld c,a
        get
        next;dec e
        ld b,a
       decodePC_to_ae
        ld h,a
        ld l,e
        add hl,bc ;hl=pc+X
       pop bc
        jp wrdest_memfrommem


;15c2
;0001 0101 1100 0010
;0 001 010 111 000 010
;mov  ;src;(pc)+;dst ;r2

;65c0
;0110 0101 1100 0000
;0 110 010 111 000 000
;add ;src;(pc)+;dst ;r0

;02fc
;0000 0010 1111 1100
;0 000 001 011 111 100
     ;bne

;1c71 ;mov barofs(r1), nhbar(r1)
;0001 1100 0111 0001
;0 001 110 001 110 001
      ;src;X(r1);dst;X(r1)

;7951
;0111 1001 0101 0001
;0 111 100 101 010 001
     ;XOR ;r5;dst;(r1)+

;7e85 ;sob
;0111 1110 1000 0101
;0 111 111 010 000 101

;[025c]:2017 ;cmp r0,#...
;0010 0000 0001 0111
;0 010 000 000 010 111
      ;src;r0 ;dst;(pc)+

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;a=cmdLSB = %??fmtRRR
getdest_aisc_autoinc ;TODO всегда +=2
;out: bc=dest, a=cmdLSB
       rra
       rra
       ld b,a
        ld a,c
        rla
        jp rdsrc_go

getdest8_aisc_autoinc
;out: c=dest, a=cmdLSB
       rra
       rra
       ld b,a
        ld a,c
        rla
        jp rdsrc8_go

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

rdsrcop
;ac=cmd
;out: bc=sourceop, a=cmdLSB
;15-12 Opcode
;11-9 Src
;8-6 Register
;5-3 Dest
;2-0 Register
        ld b,a
        rra
        ld a,c
        rra ;rrr?????
         rra
         rra
         rra
         rra
rdsrc_go
         and 0x0e
        ld l,a ;0000rrr0
        ld h,_R0/256
         ;ld l,(hl) ;TODO

;0n     Register        Rn      The operand is in Rn
;1n     Register deferred       (Rn)    Rn contains the address of the operand
;2n     Autoincrement   (Rn)+   Rn contains the address of the operand, then increment Rn
;3n     Autoincrement deferred  @(Rn)+  Rn contains the address of the address of the operand, then increment Rn by 2
;4n     Autodecrement   ?(Rn)   Decrement Rn, then use the result as the address of the operand
;5n     Autodecrement deferred  @?(Rn)  Decrement Rn by 2, then use the result as the address of the address of the operand
;6n     Index   X(Rn)   Rn+X is the address of the operand
;7n     Index deferred  @X(Rn)  Rn+X is the address of the address of the operand
        bit 1,b
        jr nz,rdsrc_xx1
        bit 2,b
        jr nz,rdsrc_x10
        bit 3,b
        jp nz,rdsrc_100
;000 Register
       cp 0x0e
       jr z,rdsrc_000_pc
         ld a,c
        ld c,(hl)
        inc l
        ld b,(hl)
        ret
rdsrc_000_pc
        GOOD ;leopol начало
        decodePC_to_ae
        ld b,a
         ld a,c
        ld c,e
        ret

rdsrc_xx1
        bit 2,b
        jp nz,rdsrc_x11
        bit 3,b
        jp nz,rdsrc_101
;001: (Rn)
rddest_001 ;(Rn): Rn contains the address of the operand
rddest_010 ;(Rn)+ ;инкремент не делаем, чтобы его делал putdest
       ld hx,c
       cp 0x0e
       jr z,rdsrc_001_pc
        ld c,(hl)
        inc l
        ld a,(hl)
        RDMEM_ac_ret ;bc=result
rdsrc_001_pc
        GOOD ;bkscope
        get
        ld c,a
        inc e
        get
        ld b,a
        dec e ;TODO нечётные
       ld a,hx
        ret

rdsrc_x10
        bit 3,b
        jp nz,rdsrc_110
;(Rn)+
;при адресациях (reg)+ и -(reg), есть особый случай: если регистр -- это r6 или r7, то регистр всегда изменяется на 2, даже если команда байтовая
       ld hx,c
        cp 0x0e
       jr z,rdsrc_010_pc
        GOOD ;textshow
        ld c,(hl)
        inc (hl) ;sp/pc +=2 ;TODO нечётный?
        inc (hl)
        inc hl
        ld a,(hl)
        jr nz,$+3
        inc (hl)
        RDMEM_ac_ret ;bc=result, a=hx
rdsrc_010_pc
        GOOD ;textshow
        get
        next
        ld c,a
        get
        next
        ld b,a
       ld a,hx
        ret

rdsrc_x11
        bit 3,b
        jp nz,rdsrc_111
rdsrc_011 ;@(Rn)+ ;всегда +=2
       ld hx,c
        cp 0x0e
        jr z,rdsrc_011_pc
        GOOD ;mars1
        ld c,(hl)
        inc l
        ld b,(hl)
        inc bc
        inc bc
        ld (hl),b
        dec l
        ld (hl),c
        dec bc
        dec bc
        ld a,b
rdsrc_addrfromaddr_ac
        ld l,c
        ld h,a
        and 0xc0
        ld c,a
       ld lx,a
        ld b,tpgs/256
        set 7,h
        set 6,h
        ld a,(bc)
        SETPGC000
        ld c,(hl)
        inc l
        call z,inchnextpg
        ld a,(hl)
        RDMEM_ac_ret ;bc=result, a=hx
rdsrc_011_pc
        GOOD ;leopol демо4(кот у цифр)
        get
        next
        ld c,a
        get
        next
        RDMEM_ac_ret ;bc=result, a=hx

rdsrc_100
;100 -(Rn)
;при адресациях (reg)+ и -(reg), есть особый случай: если регистр -- это r6 или r7, то регистр всегда изменяется на 2, даже если команда байтовая
       ld hx,c
        cp 0x0e ;TODO pc
        jr z,$ ;ninza_1 сюда не должен попадать
        GOOD ;leopol начало
        ld c,(hl)
        inc l
        ld b,(hl)
        dec bc
        dec bc
        ld (hl),b
        dec l
        ld (hl),c
rdmem_bc_to_bc
        ld a,b
rdmem_ac_to_bc
        RDMEM_ac_ret ;bc=result, a=hx

rdsrc_101
;101 @-(Rn) ;всегда -=2
       ld hx,c
        cp 0x0e
        jr z,$;rdsrc_101_pc ;TODO pc
        UNTESTED
        ld c,(hl)
        inc l
        ld b,(hl)
        dec bc
        dec bc
        ld (hl),b
        dec l
        ld (hl),c
        ld a,b
        jp rdsrc_addrfromaddr_ac

rdsrc_110
;110 Index: X(Rn): Rn+X is the address of the operand
       ld hx,c
        cp 0x0e
        jr z,rdsrc_110_pc
        GOOD ;leopol начало
        get
        next
        add a,(hl)
        ld c,a
        inc l
        get
        next
        adc a,(hl) ;ac=Rn+X
        RDMEM_ac_ret ;bc=result, a=hx
rdsrc_110_pc
        GOOD ;leopol демо
        get
        next
        ld c,a
        get
        next
        ld b,a
        decodePC_to_ae
         ld h,a
        ld a,c
        add a,e
        ld c,a
        ld a,b
        adc a,h;d
        RDMEM_ac_ret ;bc=result, a=hx

rdsrc_111
;111 Index deferred: @X(Rn): Rn+X is the address of the address of the operand
       ld hx,c
       cp 0x0e
       jr z,rdsrc_111_pc
        GOOD ;klad ;нет в leopol
        get
        next
        add a,(hl)
        ld c,a
        inc l
        get
        next
        adc a,(hl) ;ac=Rn+X
        jp rdsrc_addrfromaddr_ac
rdsrc_111_pc ;for morf
        GOOD ;leopol появление мышей2?
        get
        next
        ld c,a
        get
        next
        ld b,a
        decodePC_to_ae
        ld h,a
        ld l,e
        add hl,bc
        ld a,h
        ld c,l ;ac=Rn+X
        jp rdsrc_addrfromaddr_ac

;;;;;;;;;;;;;;;;;;;;;;;
rdsrc8op
;ac=cmd
;out: c=sourceop, a=cmdLSB
;15-12 Opcode
;11-9 Src
;8-6 Register
;5-3 Dest
;2-0 Register
        ld b,a
        rra
        ld a,c
        rra ;rrr?????
         rra
         rra
         rra
         rra
rdsrc8_go
         and 0x0e
        ld l,a ;0000rrr0
        ld h,_R0/256
         ;ld l,(hl) ;TODO

;0n     Register        Rn      The operand is in Rn
;1n     Register deferred       (Rn)    Rn contains the address of the operand
;2n     Autoincrement   (Rn)+   Rn contains the address of the operand, then increment Rn
;3n     Autoincrement deferred  @(Rn)+  Rn contains the address of the address of the operand, then increment Rn by 2
;4n     Autodecrement   ?(Rn)   Decrement Rn, then use the result as the address of the operand
;5n     Autodecrement deferred  @?(Rn)  Decrement Rn by 2, then use the result as the address of the address of the operand
;6n     Index   X(Rn)   Rn+X is the address of the operand
;7n     Index deferred  @X(Rn)  Rn+X is the address of the address of the operand
        bit 1,b
        jr nz,rdsrc8_xx1
        bit 2,b
        jr nz,rdsrc8_x10
        bit 3,b
        jp nz,rdsrc8_100
;000 Register
         ld a,c
        ld c,(hl)
        ;inc l
        ;ld b,(hl)
        ret

rdsrc8_xx1
        bit 2,b
        jp nz,rdsrc8_x11
        bit 3,b
        jp nz,rdsrc8_101
;001: (Rn)
rddest8_001 ;(Rn): Rn contains the address of the operand
rddest8_010 ;(Rn)+ ;инкремент не делаем, чтобы его делал putdest
       ld hx,c
       cp 0x0e
       jr z,rdsrc8_001_pc
        ld c,(hl)
        inc l
        ld a,(hl)
        RDMEM8_ac_ret ;bc=result
rdsrc8_001_pc
        UNTESTED ;GOOD ;bkscope
        get
        ld c,a
       ld a,hx
        ret

rdsrc8_x10
        bit 3,b
        jp nz,rdsrc8_110
;(Rn)+
;при адресациях (reg)+ и -(reg), есть особый случай: если регистр -- это r6 или r7, то регистр всегда изменяется на 2, даже если команда байтовая
       ld hx,c
        cp 0x0e
       jr z,rdsrc8_010_pc
        GOOD ;textshow
        ld c,(hl)
      cp 0x0c
      jr c,$+3 ;для textshow
         inc (hl) ;sp/pc +=2 ;TODO нечётный?
        inc (hl)
        inc hl
        ld a,(hl)
        jr nz,$+3
        inc (hl)
        RDMEM8_ac_ret ;bc=result, a=hx
rdsrc8_010_pc
        GOOD ;dark
        get
        next
        ld c,a
        next
       ld a,hx
        ret

rdsrc8_x11
        bit 3,b
        jp nz,rdsrc8_111
rdsrc8_011 ;@(Rn)+ ;всегда +=2
       ld hx,c
        cp 0x0e
       jr z,rdsrc8_011_pc
        UNTESTED
        ld c,(hl)
        inc l
        ld b,(hl)
       push bc
      cp 0x0c
      jr c,$+3 ;не проверяется в textshow!
         inc bc
        inc bc
        ld (hl),b
        dec l
        ld (hl),c
       pop bc
        ld a,b
rdsrc8_addrfromaddr_ac
        ld l,c
        ld h,a
        and 0xc0
        ld c,a
       ld lx,a
        ld b,tpgs/256
        set 7,h
        set 6,h
        ld a,(bc)
        SETPGC000
        ld c,(hl)
        inc l
        call z,inchnextpg
        ld a,(hl)
        RDMEM8_ac_ret ;c=result, a=hx
rdsrc8_011_pc
        GOOD ;digger
        get
        next
        ld c,a
        get
        next
        RDMEM8_ac_ret ;c=result, a=hx

rdsrc8_100
;100 -(Rn)
;при адресациях (reg)+ и -(reg), есть особый случай: если регистр -- это r6 или r7, то регистр всегда изменяется на 2, даже если команда байтовая
       ld hx,c
        cp 0x0e
       jr z,$;rdsrc8_100_pc
        GOOD ;leopol начало
        ld c,(hl)
        inc l
        ld b,(hl)
        dec bc
       cp 0x0c
       jr c,$+3
       dec bc ;sp/pc +=2
        ld (hl),b
        dec l
        ld (hl),c
        ld a,b
        RDMEM8_ac_ret ;bc=result, a=hx

rdsrc8_101
;101 @-(Rn) ;всегда -=2
       ld hx,c
        cp 0x0e
       jr z,$;rdsrc8_101_pc
        UNTESTED
        ld c,(hl)
        inc l
        ld b,(hl)
         dec bc
        dec bc
        ld (hl),b
        dec l
        ld (hl),c
        ld a,b
        jp rdsrc8_addrfromaddr_ac

rdsrc8_110
;110 Index: X(Rn): Rn+X is the address of the operand
       ld hx,c
        cp 0x0e
       jr z,rdsrc8_110_pc
        GOOD ;cindy2 начало
        get
        next
        add a,(hl)
        ld c,a
        inc l
        get
        next
        adc a,(hl) ;ac=Rn+X
        RDMEM8_ac_ret ;c=result, a=hx
rdsrc8_110_pc
        GOOD ;dark
        get
        next
        ld c,a
        get
        next
        ld b,a
        decodePC_to_ae
         ld h,a
        ld a,c
        add a,e
        ld c,a
        ld a,b
        adc a,h;d
        RDMEM8_ac_ret ;c=result, a=hx

rdsrc8_111
;111 Index deferred: @X(Rn): Rn+X is the address of the address of the operand
       ld hx,c
        cp 0x0e
       jr z,rdsrc8_111_pc
        GOOD ;klad
        get
        next
        add a,(hl)
        ld c,a
        inc l
        get
        next
        adc a,(hl) ;ac=Rn+X
        jp rdsrc8_addrfromaddr_ac
rdsrc8_111_pc ;for morf
        GOOD ;klad ;pacman
        get
        next
        ld c,a
        get
        next
        ld b,a
        decodePC_to_ae
        ld h,a
        ld l,e
        add hl,bc
        ld a,h
        ld c,l ;ac=Rn+X
        jp rdsrc8_addrfromaddr_ac

;;;;;;;;;;;;;;;;;;;;;;;;
rdport_c
;out: a=hx!!!
       ;ld b,a
        ld a,c
;FFB0=177660 регистр состояния клавиатуры (Разряд 6 - маска прерываний от клавиатуры. разряд доступен по записи и чтению. "0" - разрешено прерывание от клавиатуры; "1" - запрещено прерывание от клавиатуры. Разряд 7 - флаг состояния клавиатуры. Устанавливается в единицу при поступлении в регистр данных клавиатуры нового кода. Сбрасывается в "0" при чтении регистра данных клавиатуры.)
;FFB2=177662 Регистр данных клавиатуры
;bit #100,@#177716 (ffce): tapestate, Разряд 6 служит индикатором нажатия клавиши ("лог 0" - клавиша нажата, "лог 1" - клавиша отжата). Используется при реализации режима "повтор".
;177714: Регистр порта ввода-вывода
;177664 предназначен для указания начала экранного ОЗУ и организации рулонного сдвига экрана. При начальной установке экрана в регистре записывается значение 1330 (0x02d8). Изменение этого значения на 1 приводит к сдвигу изображения на экране по вертикали на 1 точечную строку. Сразу же после включения питания разряд 9 устанавливается в "1". При включении режима расширенной памяти разряд сбрасывается в "0". Разряды 8, 10-15 не используются.
        cp 0xb0 ;177660
        jr z,2f ;kbd state
         cp 0xb4 ;177662
         jr z,rdport_c_scrshift ;Bubbler
         cp 0xcc
         jr z,rdport_c_io ;Клад
         cp 0xc8 ;177710 ;Таймер работает независимо от работы программы. Содержимое счётчика времени определяется как результат функции PEEK(&O177710) и периодически уменьшается от S0 до 0 (рис. 10).
         jr z,rdport_c_timer ;kld19nm_bk10
        cp 0xce ;177716
        jr z,rdport_c_tapestate
        cp 0xcf
        jr z,rdport_c_tapestate_hsb
         ;cp 0x70 ;В *560м регистре имеются два бита, 6й и 7й. 7 бит *560го регистра устанавливается по reset или если во входной регистр *562 поступил новый байт, а если перед приемом байтов установить в 1 6й бит *560го регистра, то произойдет прерывание с вектором, адрес которого читается из регистра *566
         ;cp 0x72 ;*562й регистр - буфер приемника, оттуда считывается последний принятый байт, по записи регистр ничего не делает
         cp 0x74 ;В регистре *564 имеются тоже два бита, 6й и 7й, с тем же назначением, что и у приемника, 7й бит устанавливается в 0, когда процессор пишет байт в буфер передатчика, *566, и устанавливается в 1, когда заканчивается передача, т.е. когда буфер готов к приему следующего байта. Если при установке 7го бита был установлен 6й, то по готовности передатчика возникает прерывание с вектором, на 4 бОльшим, чем считываемое из регистра *566 значение.
         jr z,rdport_c_testconsole_txstate
         ;cp 0x76 ;буфер передатчика
        cp 0xb2
        jr nz,9f ;no ports
;kbd data
bk_oldkey=$+1
        ld c,0
bk_curkey=$+1
        ld a,0
        or a
        jr z,bk_port_getkey_no
        ld (bk_oldkey),a
        ld c,a
bk_port_getkey_no
        xor a
        ld (bk_curkey),a ;no message (INT прочитает новую кнопку)
       ld a,hx
       ld b,0
        ret
2 ;kbd state
        ;ld a,(iskeymessage) ;a7=no message
        ;rra
       ld a,(bk_curkey)
       sub 1
       sbc a,a ;CY=no message
        and 0x40
        ld c,a
       ld a,hx
       ld b,0
        ret
rdport_c_io
       ld a,hx
       ld bc,0
        ret
rdport_c_scrshift
       ld a,hx
bkscroll=$
       ld bc,0x02d8
        ret
9
;TODO прерывание ошибки шины
        ;jr $ ;бейсик читает ff5a
       ld a,hx
        ret
rdport_c_timer ;kld19nm_bk10
;177710 ;Таймер работает независимо от работы программы. Содержимое счётчика времени определяется как результат функции PEEK(&O177710) и периодически уменьшается от S0 до 0 (рис. 10).
bktimer=$+1
        ld bc,0
        dec bc
        ld (bktimer),bc
       ld a,hx
        ret

rdport_c_testconsole_txstate
;В регистре *564 имеются тоже два бита, 6й и 7й, с тем же назначением, что и у приемника, 7й бит устанавливается в 0, когда процессор пишет байт в буфер передатчика, *566, и устанавливается в 1, когда заканчивается передача, т.е. когда буфер готов к приему следующего байта. Если при установке 7го бита был установлен 6й, то по готовности передатчика возникает прерывание с вектором, на 4 бОльшим, чем считываемое из регистра *566 значение.
       ld bc,0x80 ;ready
       ld a,hx
        ret
rdport_c_tapestate
;Разряд 6 служит индикатором нажатия клавиши ("лог 0" - клавиша нажата, "лог 1" - клавиша отжата). Используется при реализации режима "повтор".
;labyrinh ждёт в (0xffce) 0x80a0
iskeypressed=$+1
        ld a,0;(iskeypressed) ;0=not pressed
       ;ld a,(bk_curkey) ;не помогает
        sub 1
       ;scf ;не помогает (Клад не видит нажатий в игре)
        sbc a,a ;-1=not pressed
        and 0x40
       or 0xa0
        ld c,a
       ld a,hx
       ld b,0x80
        ret
rdport_c_tapestate_hsb ;for morf
       ld a,hx
       ld bc,0x0080
        ret

buserror
;из rdmem
JMPer_error
        ld sp,STACK
;TRAP to 4
        call getflags_bc
        putmemspBC
        decodePC_to_ae
        ld b,a
        ld c,e
        putmemspBC
        ld bc,0x06
        call rdmem_bc_to_bc
        call makeflags_frombc
        ld bc,0x04
        call rdmem_bc_to_bc
        ld d,b
        ld e,c
       _LoopC_JP

wrongcmd
        ld sp,STACK
;TRAP to 10
        call getflags_bc
        putmemspBC
        decodePC_to_ae
        ld b,a
        ld c,e
        putmemspBC
        ld bc,0x0a
        call rdmem_bc_to_bc
        call makeflags_frombc
        ld bc,0x08
        call rdmem_bc_to_bc
        ld d,b
        ld e,c
       _LoopC_JP


cls_bk
        ld a,(tpgs+0x40)
       ;jp clpga
clpga
        ld e,0
clpga_e
        SETPGC000
        ld hl,0xc000
       ld a,e
        ld d,h
        ld e,l
        inc e
        ld bc,0x3fff
       ld (hl),a;0
        ldir
        ret

        include "bkcmd.asm"

        align 256
tpgs
        ds 256 ;%10765432

        align 256
tmirror
tleftpixels
       dup 256
_7=$&0x80
_6=$&0x40
_5=$&0x20
_4=$&0x10
_3=$&0x08
_2=$&0x04
_1=$&0x02
_0=$&0x01
        db (_7>>7)+(_6>>5)+(_5>>3)+(_4>>1)+(_3<<1)+(_2<<3)+(_1<<5)+(_0<<7)
       edup

        align 256
ty
__=0
        dup 32
        dup 8
_=__-8 ;логический номер строки БК
       if (_<0)
_=200
       endif
       if (_>200)
_=200
       endif
       if ($&7)==0
_=200
       endif
        db 0xff&(_*40+4)
       if ($&7)
__=__+1
       endif
        edup
        edup
__=0
        dup 32
        dup 8
_=__-8 ;логический номер строки БК
       if (_<0)
_=200
       endif
       if (_>200)
_=200
       endif
       if ($&7)==0
_=200
       endif
        db (_*40+4)/256+0x80
       if ($&7)
__=__+1
       endif
        edup
        edup


        align 256
;8 r16s
_R0
        dw 0
_R1
        dw 0
_R2
        dw 0
_R3
        dw 0
_R4
        dw 0
_R5
        dw 0
_R6
_SP
        dw 0
_R7
        dw 0

pc_high
        db 0
iff1
        db 0
pgprog
        db 0 ;там можно хранить дополнительный код (напр., отладчик)
oldimer
        jp on_int
        jp 0x0038+3

print_bc_to_log
print_bc_to_log_addr=$+1
        ld hl,log
        ld (hl),c
        inc l
        ld (print_bc_to_log_addr),hl
        ret

        align 256
log
        ds 256

        align 256
        include "bktable.asm"

       if DEBUG
       align 256
oldpc
        ;dw 0
        ds 256
       endif

font
        incbin "866_code.fnt"
        display "tkoi=",$
tkoi
        dup 0xc0
        db $&0xff
        edup
        db "юабцдефгхийклмнопярстужвьызшэщч "
        db "ЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧ "

;генерируется для textmode
        align 256
ttextaddr
        ds 128

        display "killable=",$
;killable

        display "lowend=",$
        ds 0x3fc0-$
        ds 0x4000-$
        include "ints.asm"
        include "keyscan.asm"
        display "end=",$
end

        savebin "bk.com",begin,end-begin

        LABELSLIST "../../us/user.l",1