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