Rev 997 |
Rev 1012 |
Go to most recent revision |
Blame |
Compare with Previous |
Last modification |
View Log
| Download
| RSS feed
DEVICE ZXSPECTRUM1024
include "../_sdk/sys_h.asm"
;STACK=0x4000
atm=1
;emul=в 0 [#8000..#BFFF]
;основной набор регистров=в альтернативном наборе
;PC=в DE
;текущий индексный=в IX
;не текущий индексный=в _IZ
;SP=в _SP (todo в (SP)?)
;брякпойнты для скорости можно ставить на обработчиках
;КОНКРЕТНОЙ команды
STACK=#BB00
D1SBUF=#BB00
;IMTAB=#BC00
;IMER=#BDBD
stats=0 ;статистика по опкодам
margins=0
fullmem=1 ;0=16k mem (fast, don't work without ROM), 1=48/128/512k mem (slow)
extpg5=0 ;1=стр5 лежит в pg5,иначе в #4000(без перехвата экрана)
;для 16k нельзя
;экран надо строить редко, в scr2
skipIM1=1 ;1=вместо трассировки #38 вызываем ее (если IY=23610)
showimtime=0 ;на бордюре
MACRO OUTPG
SETPGC000
ENDM
MACRO getmem
mem
LD A,(HL)
ENDM
MACRO _Loop_
JP (IY) ;EMULOOP (нужный marg или нужный обработчик b/p)
ENDM
;если вместо стр.команд включили др.стр.
MACRO _LoopC
OUTcom
JP (IY)
ENDM
;если резко сменился PC (полный DE)
MACRO _LoopJP
CALCiypgcom
JP (IY)
ENDM
;если выключили др.стр. и резко сменился PC (полный DE)
MACRO _LoopC_JP
CALCiypgcom
JP (IY)
ENDM
;если IN/OUT (могла измениться конфигурация памяти)
MACRO _LoopSWI
CALCpgcom
JP (IY)
ENDM
MACRO next
INC DE
ENDM
;BC,DE,HL,AF -> BC
;rp=A
MACRO rptoBC
AND #30
OR #C5 ;PUSH rp
LD ($+5),A
EXX
EXA
PUSH BC ;DE;HL;AF
EXX
EXA
POP BC
ENDM
;BC,DE,HL,AF <- BC
;rp=A
MACRO BCtorp
AND #30
OR #C1 ;POP rp
PUSH BC
LD ($+5),A
EXX
EXA
POP BC ;DE;HL;AF
EXX
EXA
ENDM
;берем смещение d
;результат HL=IX+d
MACRO getdIXtoHL
get
next
LD L,A
RLA
SBC A,A
LD H,A
PUSH IX
POP BC
ADD HL,BC
ENDM
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
IF fullmem
;портит HL,BC!
;оптимизен slow (там в 95% случаев стек)
MACRO mem
;LOCAL
LD A,H
ADD A,A
jr NC,4f;lo
JP M,3f;pg
SET 6,H
LD A,(curpg2)
JP 5f;o
3;pg
LD A,(curpghi)
JP 5f;o
4;lo
JP M,6f;sl
LD A,H
OR #C0
LD H,A
LD A,(currom)
IF extpg5
JP 5f;o
6;sl
LD A,(curpg5)
SET 7,H
ENDIF
5;o
OUTPG
IF extpg5==0
6;sl
ENDIF
;ENDL
ENDM
;портит HL,A!
IF 1
MACRO getmemBC
;LOCAL
PUSH HL
mem
LD C,(HL)
INC L
JP NZ,1f;q
POP HL
PUSH BC
INC HL
mem
POP BC
JP $+4
1;q
POP AF ;просто скипаем
LD B,(HL)
;ENDL
ENDM
ELSE
MACRO getmemBC
;LOCAL
PUSH HL
INC HL
getmem
POP HL
PUSH AF
getmem
POP BC
LD C,A
;ENDL
ENDM
ENDIF
;портит BC,HL!
MACRO putmem
;LOCAL
;module lcl
;LD (aa),A
ld ($+0x28),a
LD A,H
ADD A,A
jr NC,4f;lo
JP M,3f;pg
SET 6,H
LD A,(@curpg2)
JP 5f;o
3;pg
LD A,(@curpghi)
IF @extpg5
CP @pg5
JP NZ,5f;o
RES 7,H
JP 6f;sl
ELSE
JP 5f;o
ENDIF
4;lo
JP M,6f;sl
LD A,(@romon0) ;0=ПЗУ, #C0=ОЗУ
OR H
JP P,1f;q ;невозможно putmem в ПЗУ
LD H,A
LD A,(@currom)
IF extpg5
JP 5f;o
6;sl
BIT 5,H
jr NZ,7f;ns
LD A,L
AND #1F
CP 24
jr NC,ns
LD A,(aa)
LD (HL),A ;экран
7;ns
SET 7,H
LD A,@pg5
ENDIF
5;o
OUTPG
IF @extpg5==0
6;sl
ENDIF
;aa=$+1
LD (HL),0
1;q
;ENDL
;endmodule
ENDM
;портит HL,A,BC!
;нельзя ускорить, иначе не перехватить экран
;сделать ветку?
;вообще не перехватывать экран?
MACRO putmemBC
;LOCAL
PUSH HL
PUSH BC
LD A,C
putmem
POP AF
POP HL
INC HL
putmem
;ENDL
ENDM
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IF margins
MACRO get
LD A,(DE)
ENDM
MACRO getHL
get
next
LD L,A
get
next
LD H,A
ENDM
MACRO OUTcom
LD A,(curpgcom)
OUTPG
ENDM
MACRO CALCpgcom
LD HL,(curquart)
LD A,(HL)
LD (curpgcom),A
OUTPG
ENDM
;перед JR/CALL/RST
MACRO CALCpc
LD A,(curquart)
SUB currom
RRCA
RRCA
XOR D
AND #C0
XOR D
LD D,A
ENDM
;после JR/JP/CALL/RST/RET (на входе - полный DE)
MACRO CALCiypgcom
LOCAL
LD A,D
ADD A,A
jr NC,lo
JP M,pg
SET 6,D
LD HL,curpg2
LD IY,marg2
JP o
pg LD HL,curpghi
LD IY,marg3
JP o
lo JP M,sl
LD A,D
OR #C0
LD D,A
LD HL,currom
LD IY,marg0
JP o
sl LD HL,curpg5
LD IY,marg1
SET 7,D
o
ENDL
LD (curquart),HL
LD A,(HL)
LD (curpgcom),A
OUTPG
ENDM
;########################################
ELSE
;без ускорения через margins
MACRO OUTcom
ENDM
MACRO CALCpgcom
ENDM
MACRO CALCpc
ENDM
MACRO CALCiypgcom
ENDM
;оптимизено ПЗУ и pg2
;портит BC!
MACRO getnp
;LOCAL
LD A,D
ADD A,A
jr NC,4f;lo
JP M,3f;pg
SET 6,D
LD A,(curpg2)
JP 5f;o
3;pg
LD A,(curpghi)
JP 5f;o
4;lo
IF extpg5
JP P,8f;r
LD A,(curpg5)
SET 7,D
JP 5f;o
ELSE
JP M,9f;q
ENDIF
8;r
LD A,D
OR #C0
LD D,A
LD A,(currom)
5;o
OUTPG
9;q
LD A,(DE)
;ENDL
ENDM
MACRO get
PUSH DE
getnp
POP DE
ENDM
;портит BC!
IF 1
MACRO getHL
;LOCAL
PUSH DE
getnp
LD L,A
INC E
JP NZ,2f;x
POP DE
PUSH BC
next
get
POP BC
JP $+6
2;x
LD A,(DE)
POP DE
INC DE
next
LD H,A
;ENDL
ENDM
ELSE
MACRO getHL
get
next
LD L,A
get
next
LD H,A
ENDM
ENDIF
ENDIF
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
ELSE ;16k mem
MACRO OUTcom
ENDM
MACRO mem
ENDM
MACRO getmemBC
LD C,(HL)
INC HL
LD B,(HL)
ENDM
MACRO putmem
BIT 7,H
jr NZ,$+3
LD (HL),A
ENDM
MACRO putmemBC
BIT 7,H
jr NZ,$+3
LD (HL),C
INC HL
BIT 7,H
jr NZ,$+3
LD (HL),B
ENDM
MACRO get
LD A,(DE)
ENDM
MACRO getHL
get
next
LD L,A
get
next
LD H,A
ENDM
MACRO CALCpgcom
ENDM
;перед JR/CALL/RST
MACRO CALCpc
ENDM
;после JR/JP/CALL/RST/RET (на входе - полный DE)
MACRO CALCiypgcom
ENDM
ENDIF ;16k mem
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
;ORG #8000
org PROGSTART
begin
ld sp,STACK
OS_HIDEFROMPARENT
ld e,3+0x80 ;keep
OS_SETGFX ;e=0:EGA, e=2:MC, e=3:6912, e=6:text ;+SET FOCUS ;e=-1: disable gfx (out: e=old gfxmode)
ld e,0
OS_SETSCREEN
ld e,0 ;color byte
OS_CLS
;ld e,1
;OS_SETSCREEN
;ld e,0 ;color byte
;OS_CLS
ld a,(user_scr0_high) ;ok
ld (curpg5),a
SETPG4000
OS_GETMAINPAGES ;out: d,e,h,l=pages in 0000,4000,8000,c000, c=flags, b=id
ld a,h
ld (curpg2),a
ld a,l
ld (temulpgs+0),a
ld b,25
waitstart0
push bc
YIELD
pop bc
djnz waitstart0
if 1
OS_NEWPAGE
ld a,e
ld (temulpgs+1),a
OS_NEWPAGE
ld a,e
ld (temulpgs+3),a
OS_NEWPAGE
ld a,e
ld (temulpgs+4),a
OS_NEWPAGE
ld a,e
ld (temulpgs+6),a
OS_NEWPAGE
ld a,e
ld (temulpgs+7),a
endif
ld de,path
OS_CHDIR
ld de,diskname
OS_OPENHANDLE
ld a,b
ld (diskhandle),a
OS_NEWPAGE
ld a,e
LD (pgrom48),a
ld de,trom48
ld hl,0xc000
;de=имя файла
;hl=куда грузим (0xc000)
;a=в какой странице
call loadfile_in_ahl
OS_NEWPAGE
ld a,e
LD (pgrom128),a
ld de,trom128
ld hl,0xc000
;de=имя файла
;hl=куда грузим (0xc000)
;a=в какой странице
call loadfile_in_ahl
OS_NEWPAGE
ld a,e
LD (pgromDOS),a
ld de,tromDOS
ld hl,0xc000
;de=имя файла
;hl=куда грузим (0xc000)
;a=в какой странице
call loadfile_in_ahl
OS_NEWPAGE
ld a,e
LD (pgromSYS),a
ld de,tromSYS
ld hl,0xc000
;de=имя файла
;hl=куда грузим (0xc000)
;a=в какой странице
call loadfile_in_ahl
JP GO
align 256
temulpgs
ds 8
diskname
db "SYS.TRD",0
pgrom48
db 0
pgrom128
db 0
pgromDOS
db 0
pgromSYS
db 0
rrdbuf DB 0
_AF DW 0 ;AF'
_BC DW 0 ;BC'
_DE DW 0 ;DE'
_HL DW 0 ;HL'
_SP DW 0
_IZ DW 0
_R DB 0
_I DB 0
iff1 DB 0
iff2 DB 0
immode DB 0 ;#18=IM2, иначе IM1
_fd DB 0;#10 ;с точки зрения эмулимой проги
_fe DB 0
dos3F DB 0
dos5F DB 0
dosFF DB 0
;реальные банки
currom DB 0;rom48;0
curpg5 DB 0;pg5
curpg2 DB 0;pg2
curpghi DB 0;pg0;#10
curscr DB 0 ;0/8
romon0 DB 0 ;#C0=ОЗУ, 0=ПЗУ в нижних 16k
doson0 DB 0;-1 ;0=SYS/DOS, -1=48/128
loadfile_in_ahl
;de=имя файла
;hl=куда грузим (0xc000)
;a=в какой странице
SETPGC000 ;включили страницу A в 0xc000
push hl ;куда грузим
OS_OPENHANDLE
pop de ;куда грузим
push bc ;b=handle
ld hl,0x4000 ;столько грузим (если столько есть в файле)
OS_READHANDLE
pop bc ;b=handle
OS_CLOSEHANDLE
ret;jp setpgmainc000 ;включили страницу программы в c000, как было
path
db "z80",0
trom48
;DB "2006.ROM",0
;DB "1982.ROM",0
DB "48for128.rom",0
trom128
DB "128tr.rom",0
tromSYS
DB "GLUKPEN.ROM",0
tromDOS
DB "DOS6_10E.ROM",0
sysvars
incbin "goodsysv"
sz_sysvars=$-sysvars
swapimer
di
ld de,0x0038
ld hl,oldimer
ld bc,3
swapimer0
ld a,(de)
ldi ;[oldimer] -> [0x0038]
dec hl
ld (hl),a ;[0x0038] -> [oldimer]
inc hl
jp pe,swapimer0
ei
ret
oldimer
jp on_int
jp 0x0038+3
on_int
jp IMER
GO
LD SP,STACK
ld hl,sysvars
ld de,0x5b00
ld bc,sz_sysvars
ldir
LD A,(curpg5);pg5
CALL OUTA
LD HL,#C000
LD DE,#4000
LD BC,#4000
LDIR
IF 0
LD A,#10
CALL CLPG
LD A,#11
CALL CLPG
LD A,#13
CALL CLPG
LD A,#14
CALL CLPG
LD A,#16
CALL CLPG
LD A,#17
CALL CLPG
ENDIF
if 1
call swapimer
else
LD HL,IMTAB
LD BC,256
LD D,H
ld E,B
LD (HL),IMER&0xff
LD A,H
LDIR
LD I,A
IM 2
endif
LD A,(_fd)
CALL eout7FFD
LD BC,0
LD DE,0
LD HL,0
PUSH HL
POP AF
EXX
EXA
LD IX,0
LD DE,#0000 ;=PC
EI
IF margins
LD HL,currom
LD (curquart),HL
LD A,(HL)
LD (curpgcom),A
OUTPG
LD D,#C0
LD IY,marg0 ;или адрес обработчика b/p, идущего туда
JP (IY)
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
curquart
DW currom
curpgcom
DB 0;pg0;#10
marg0
LD A,(DE) ;уже ORed #C000
INC E
JZ marg0i ;проигрыш 5 тактов
marg0iq LD L,A
ld H,MAINCOMS/256
LD C,(HL)
INC H
LD H,(HL)
ld L,C
JP (HL) ;след. байт команды - в (DE)
marg0i INC D
JP NZ,marg0iq
LD HL,curpg5
LD (curquart),HL
LD A,(HL)
LD (curpgcom),A
OUTPG
LD D,#C0
marg1adr=$+2
LD IY,marg1 ;или адрес обработчика b/p, идущего туда
JP marg1iq
marg1
LD A,(DE) ;уже ORed #C000
INC E
jr Z,marg1i ;проигрыш 5 тактов
marg1iq LD L,A
ld H,MAINCOMS/256
LD C,(HL)
INC H
LD H,(HL)
ld L,C
JP (HL) ;след. байт команды - в (DE)
marg1i INC D
JP NZ,marg1iq
LD HL,curpg2
LD (curquart),HL
LD A,(HL)
LD (curpgcom),A
OUTPG
LD D,#C0
marg2adr=$+2
LD IY,marg2 ;или адрес обработчика b/p, идущего туда
JP marg2iq
marg2
LD A,(DE) ;уже ORed #C000
INC E
jr Z,marg2i ;проигрыш 5 тактов
marg2iq LD L,A
ld H,MAINCOMS/256
LD C,(HL)
INC H
LD H,(HL)
ld L,C
JP (HL) ;след. байт команды - в (DE)
marg2i INC D
JP NZ,marg2iq
LD HL,curpghi
LD (curquart),HL
LD A,(HL)
LD (curpgcom),A
OUTPG
LD D,#C0
marg3adr=$+2
LD IY,marg3 ;или адрес обработчика b/p, идущего туда
JP marg2iq
marg3
LD A,(DE)
INC E
jr Z,marg3i ;проигрыш 5 тактов
marg3iq LD L,A
ld H,MAINCOMS/256
LD C,(HL)
INC H
LD H,(HL)
ld L,C
JP (HL) ;след. байт команды - в (DE)
marg3i INC D
JP NZ,marg3iq
LD HL,currom
LD (curquart),HL
LD A,(HL)
LD (curpgcom),A
OUTPG
LD D,#C0
marg0adr=$+2
LD IY,marg0 ;или адрес обработчика b/p, идущего туда
JP marg0iq
ENDIF ;margins
;---------------------------
IF showimtime
LD IY,EMUSHOWIMTIME
ELSE
LD IY,EMUCHECKQ
ENDIF
;EMUDATABUS ;ШД0..2 на бордюр
;EMUADDRBUS ;ША8..10 ма бордюр
;EMUCHECKPOINT ;проверка адреса или условия
;проверка числа тактов до INT?
EMUCHECKQ
get
next
IF stats
PUSH HL
LD L,A
LD H,comstats/256-1
INC H
INC (HL)
jr Z,$-2
POP HL
ENDIF
LD L,A
ld H,MAINCOMS/256
LD C,(HL)
INC H
LD H,(HL)
ld L,C
JP (HL)
;можно выиграть 11(-JP=1) тактов:
;LD L,A
;AND 3 ;3 для JP, а можно(?) целые п/п: 7/15/31
;ADD A,'MAINCOMS
;LD H,A
;JP (HL) ;L=код команды, если надо
CBPREFIX
get
next
LD L,A
ld H,CBCOMS/256
LD C,(HL)
INC H
LD H,(HL)
ld L,C
JP (HL)
EDPREFIX
get
next
LD L,A
ld H,EDCOMS/256
LD C,(HL)
INC H
LD H,(HL)
ld L,C
JP (HL)
FDPREFIX
DDPREFIX
oldprefix=$+1
CP #DD
jr Z,DDFDOLD
LD (oldprefix),A
;сменили префикс! меняем местами IX и _IZ
LD HL,(_IZ)
LD (_IZ),IX
PUSH HL
POP IX
DDFDOLD get
next
LD L,A
ld H,DDCOMS/256
LD C,(HL)
INC H
LD H,(HL)
ld L,C
JP (HL)
DDCBPREFIX
getdIXtoHL
PUSH HL
get
next
LD L,A
ld H,DDCBCOMS/256
LD C,(HL)
INC H
LD H,(HL)
ld L,C
EX (SP),HL
RET
EMUDATABUS
LD A,(DE)
call outFE;OUT (-2),A
JP EMUCHECKQ
EMUADDRBUS
LD A,D
call outFE;OUT (-2),A
JP EMUCHECKQ
EMUCHECKPOINT
retfromim=$+1
LD HL,0
XOR A
SBC HL,DE
JP NZ,EMUCHECKQ
LD A,(_fe)
call outFE;OUT (-2),A
JP EMUCHECKQ
OUTA
PUSH BC
;LD BC,32765
;OUT (C),A
OUTPG
POP BC
RET
EMUOUT
;BC=port, A=value
BIT 0,C
jr Z,eoutFE
BIT 1,C
jr Z,eoutFD
PUSH AF
LD A,(doson0)
OR A
jp Z,EMUOUTDOS
POP AF
RET
eoutFD
BIT 7,B
jr Z,eout7FFD
BIT 6,B
jr NZ,eoutFFFD
LD BC,#BFFD
OUT (C),A
RET
eoutFFFD
LD BC,#FFFD
OUT (C),A
RET
eout7FFD
LD (_fd),A
LD C,A
;пересчитываем номер банки (A=C -> A)
AND #C7
CP 5
JR NZ,$+7
LD A,(curpg5)
JR eout7FFDOK
CP 2
JR NZ,$+7
LD A,(curpg2)
JR eout7FFDOK
;
IF 0;atm
;%bb000bbb
RRCA
RRCA
RRCA
XOR C
AND %11000
XOR C
AND %11111
XOR #7F
else
and 7 ;TODO мегабайт захватывать динамически постранично
ld l,a
ld h,temulpgs/256
ld a,(hl)
ENDIF
eout7FFDOK
LD (curpghi),A
LD A,C
AND 8 ;номер экрана
LD B,A
LD (curscr),A
LD A,(doson0)
OR A
jr Z,eo7FFDdos
BIT 4,C ;номер ПЗУ
LD A,(pgrom48)
jr NZ,$+5
LD A,(pgrom128)
JR eo7FFDo
eo7FFDdos
BIT 4,C ;номер ПЗУ
LD A,(pgromDOS)
jr NZ,$+4
LD A,(pgromSYS)
JR eo7FFDo
eo7FFDo
IF atm
LD (currom),A
ELSE
LD C,#F7
AND C
OR B
LD (currom),A
LD HL,curpg5
LD A,(HL)
AND C
OR B
LD (HL),A
LD HL,curpg2
LD A,(HL)
AND C
OR B
LD (HL),A
LD HL,curpghi
LD A,(HL)
AND C
OR B
LD (HL),A
ENDIF
RET
eoutFE
LD (_fe),A
;OUT (#FE),A
outFE
OUT (#FE),A
push af
push bc
push de
push hl
push ix
push iy
exx
push bc
push de
push hl
and 7
ld e,a
ex af,af' ;'
push af
OS_SETBORDER
pop af
ex af,af' ;'
pop hl
pop de
pop bc
exx
pop iy
pop ix
pop hl
pop de
pop bc
pop af
RET
EMUOUTDOS
LD A,C
CP #3F
jr Z,eod3F
CP #5F
jr Z,eod5F
CP #FF
jr Z,eodFF
POP AF
RET
eod3F
POP AF
LD (dos3F),A
RET
eod5F
POP AF
LD (dos5F),A
RET
eodFF
POP AF
LD (dosFF),A
RET
EMUIN
;BC=port
;return A=value
BIT 0,C
jr Z,einFE
LD A,(doson0)
OR A
jr Z,EMUINDOS
LD A,C
CP #DF
jr Z,einMOUSE
LD A,#FF
RET
einMOUSE
LD A,B
CP #FA
jr Z,einFADF
CP #FB
jr Z,einFBDF
CP #FF
jr Z,einFFDF
LD A,#FF
RET
;TODO from OS
einFADF
LD BC,#FADF
IN A,(C)
RET
einFBDF
LD BC,#FBDF
IN A,(C)
RET
einFFDF
LD BC,#FFDF
IN A,(C)
RET
einFE
;LD C,#FE
;IN A,(C)
push hl
ld hl,keymatrix
ld a,0xff
dup 8
rlc b
jr c,$+3
and (hl)
inc hl
edup
pop hl
and a
RET
EMUINDOS
LD A,C
CP #1F
jr Z,eid1F
CP #3F
jr Z,eid3F
CP #5F
jr Z,eid5F
CP #5F
jr Z,eidFF
LD A,#FF
RET
eidFF
LD A,#80 ;INTRQ=команда выполнена ok
RET
eid1F
LD A,#80 ;команда выполнена ok, диск вставлен
RET
eid3F
LD A,(dos3F)
RET
eid5F
LD A,(dos5F)
RET
keymatrix
ds 8,0xff
imitret
LD HL,(_SP)
ex de,hl
getHL
ex de,hl
LD (_SP),HL
ret
DOSER
;подпрограмма
LD A,(doson0)
OR A
jr NZ,DOSERny
LD A,D
CP #40
jr C,DOSDOS ;DOS -> DOS
;DOS -> неDOS
;выкл. стр. доса
LD A,-1
LD (doson0),A
LD A,(_fd)
JP eout7FFD
DOSDOS
;для SYS не перехватываем!
LD A,(_fd)
AND 16
RET Z
;TODO имитировать RET после неё
ld hl,imitret
push hl
;перехваты процедур доса
CP #3F
RET NZ
LD A,E
CP #D5 ;#3fd5
jr Z,DOSWR
CP #E5 ;#3fe5
jr Z,DOSRD
CP #BA ;#3fba
RET NZ
DOSRD
PUSH DE,IX,IY
LD IY,23610
EXX
PUSH HL
INC H
EXX
POP HL
LD C,5
LD A,(dos3F) ;trk
DEC A
ADD A,A
LD D,A
LD A,(dosFF)
BIT 4,A
jr Z,$+3
INC D
LD A,(dos5F) ;sec
DEC A
LD E,A
CALL DOSrdsec
POP IY,IX,DE
DOSWR
RET
DOSERny
LD A,D
CP #3D
RET NZ
;для 128 васика запрещено! иначе глючит калькулятор
LD A,(_fd)
AND 16
RET Z
;неDOS -> DOS
;имитировать RET после неё
ld hl,imitret
push hl
LD A,E
CP #13
jr Z,DOS3D13
DOSSWON
;вкл. стр. доса
;имитация RET не катит для точки #3D2F
XOR A
LD (doson0),A
LD A,(_fd)
JP eout7FFD
DOS3D13
if 1
exx
ld a,c
exx
cp 6
jr z,DOSWRSEC
cp 5
jr nz,DOSSWON ;(for other functions)
DOSRDSEC
DOSWRSEC
exx
D3D5S0
CALL DOSrdsec
call DOSnextsec
DJNZ D3D5S0
DOS3D13q
;write de to virtual 23796:
ld hl,23796
ld b,d
ld c,e
putmemBC
exx
ret
if 0
DOSWRSEC
exx
D3D6S0
CALL DOSrdsec
call DOSnextsec
DJNZ D3D6S0
jr DOS3D13
endif
DOSnextsec
inc h
inc e
bit 4,e
ret z
inc d
ld e,0
ret
DOSrdsec
;hl=addr
;d=track
;e=sector
;c=5(read)/6(write)
PUSH BC
PUSH de
PUSH HL
EXX
EXA
PUSH AF
PUSH BC,DE,HL
push ix,iy
EXA
EXX
push hl ;addr
ld a,e ;de=trsec
add a,a
add a,a
add a,a
add a,a
ld l,d ;track
ld h,0 ;0la=trsec*16
dup 4
add a,a
adc hl,hl
edup ;hl0=trsec*256
ld d,a;0
ld e,h
ld h,l
ld l,a;0
;dehl=shift
diskhandle=$+1
ld b,0
push bc ;c=5/6
OS_SEEKHANDLE
pop bc ;c=5/6, b=handle
pop hl ;addr
push bc
mem ;paging
pop bc
ex de,hl ;de=phys addr
ld hl,256
ld a,c
cp 5
jr z,DOSrdsec5
OS_WRITEHANDLE
jr DOSrdsec5ok
DOSrdsec5
OS_READHANDLE
DOSrdsec5ok
exx
EXA
pop iy,ix
pop hl,de,bc
pop af
EXA
EXX
pop hl,de,bc
ret
else
EXX
LD A,C
EXX
CP 1
jr Z,DOS3D131
CP 5
jr Z,DOS3D135
CP 6
jr Z,DOS3D136
JP DOSSWON
DOS3D136
DOS3D135
PUSH DE,IX,IY
LD IY,23610
EXX
PUSH BC,HL
LD (23796),DE
EXX
IM 1
POP HL,BC
D3D5S0
LD DE,(23796)
CALL DOSrdsec
DJNZ D3D5S0
IM 2
;POP
;EXX
POP IY,IX,DE
DOS3D131
DOSRET
POP AF
JP RETER
DOSrdsec
PUSH BC
PUSH HL
LD HL,D1SBUF
PUSH HL
LD B,1
EXX
EXA
PUSH AF
PUSH BC,DE,HL
EXA
EXX
CALL #3D13
EXX
EXA
POP HL,DE,BC
POP AF
EXA
EXX
POP DE
POP HL
D3D50 LD A,(DE)
putmem
INC HL
INC E
jr NZ,D3D50
POP BC
RET
endif
CLPG
CALL OUTA
LD HL,#C000
LD DE,#C001
LD B,#40
LD (HL),L
LDIR
RET
INCLUDE "z80cmd.asm"
align 256
INCLUDE "z80table.asm"
DISPLAY $
IF stats
align 256
comstats
DISPLAY "comstats=",$
DS #400
ENDIF
include "rst38.asm"
;ds 0x3f00-$
;ORG IMER
IMER
PUSH AF,HL
;здесь опрос клавиш эмулятора
call oldimer
push bc,de
exx
push bc
push de
push hl
push ix
push iy
ex af,af' ;'
push af
OS_GETKEYMATRIX ;out: bcdehlix = halfrows cs...space
ld (keymatrix),ix
ld (keymatrix+2),hl
ld (keymatrix+4),de
ld (keymatrix+6),bc
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
LD (iff2),A ;для NMI надо только iff1!
;перед эмуляцией INT завершаем тек.команду (перехват на EMULOOP)
IF margins==0
LD (keepemuchecker),IY
LD IY,IMINT
ELSE
LD HL,marg0
LD (HL),205
INC HL
LD (HL),IMINT&0xff
INC HL
LD (HL),IMINT/256
LD HL,marg1
LD (HL),205
INC HL
LD (HL),IMINT&0xff
INC HL
LD (HL),IMINT/256
LD HL,marg2
LD (HL),205
INC HL
LD (HL),IMINT&0xff
INC HL
LD (HL),IMINT/256
LD HL,marg3
LD (HL),205
INC HL
LD (HL),IMINT&0xff
INC HL
LD (HL),IMINT/256
ENDIF
POP HL,AF
RET ;di!
IMINT
IF margins==0
keepemuchecker=$+2
LD IY,0
ELSE
POP HL
DEC HL,HL,HL ;здесь мы должны быть
PUSH HL
LD HL,marg0
LD (HL),26 ;ld a,(de)
INC HL
LD (HL),28 ;inc e
INC HL
LD (HL),40 ;jz
LD HL,marg1
LD (HL),26 ;ld a,(de)
INC HL
LD (HL),28 ;inc e
INC HL
LD (HL),40 ;jz
LD HL,marg2
LD (HL),26 ;ld a,(de)
INC HL
LD (HL),28 ;inc e
INC HL
LD (HL),40 ;jz
LD HL,marg3
LD (HL),26 ;ld a,(de)
INC HL
LD (HL),28 ;inc e
INC HL
LD (HL),40 ;jz
ENDIF
LD (retfromim),DE ;для индикации времени обработки прерыв
LD A,(immode)
CP #18 ;IM2
LD HL,#38 ;new PC
jr NZ,IMERIM1
LD HL,(_I-1)
LD L,#FF ;состояние пассивной ШД
LD A,(HL)
INC HL
LD H,(HL)
ld L,A
JR IMERIM
GETIY
LD HL,(_IZ)
LD A,(oldprefix)
CP #DD
RET Z
PUSH IX
POP HL
RET
IMERIM1
IF skipIM1
PUSH HL
CALL GETIY
LD BC,23610
OR A
SBC HL,BC
POP HL
JR NZ,IMERIM
;вообще-то надо и SP проверить...
IF extpg5
PUSH DE
LD A,(curpg5)
CALL OUTA
LD DE,#5C00
LD HL,#DC00
LD BC,146
LDIR
ENDIF
push ix
PUSH IY
LD IY,23610
call L0038;basicrst38
LD A,-1
LD (iff1),A
LD (iff2),A
POP IY
pop ix
IF extpg5
LD HL,#5C00
LD DE,#DC00
LD BC,146
LDIR
POP DE
ENDIF
_LoopC ;RET уже был (адрес со стека снят)
ENDIF
IMERIM
IF showimtime
LD A,1
call outFE;OUT (-2),A
ENDIF
EI
CALCpc
EX de,hl
;DE=new PC
LD B,H
ld C,L ;BC=old PC
LD HL,(_SP)
DEC HL,HL
LD (_SP),HL
putmemBC
_LoopC_JP
end
savebin "z80.com",begin,end-begin
LABELSLIST "../../us/user.l"