Rev 1025 |
Rev 1031 |
Go to most recent revision |
Blame |
Compare with Previous |
Last modification |
View Log
| Download
| RSS feed
DEVICE ZXSPECTRUM1024
include "../_sdk/sys_h.asm"
;emul=в 0000
;основной набор регистров=в альтернативном наборе
;PC=в DE
;текущий индексный=в IX
;не текущий индексный=в _IZ
;SP=в _SP (todo в (SP)? но там сейчас jpiyer для выхода из DOSER. сделать в DOSER 2-байтный патч?)
STACK=0x4000
stats=0 ;статистика по опкодам
margins=1 ;1=хранить в de уже пересчитанный PC
MEM48C0=1 ;8000,c000 - всегда замапленные страницы ;4000 - страница ПЗУ или текущая 4000 (каждый раз включать)
extpg5=0 ;1=стр5 лежит в pg5,иначе в #4000(без перехвата экрана)
;экран надо строить редко, в scr2
skipIM1=1 ;1=вместо трассировки #38 вызываем ее (если IY=23610)
MACRO OUTPG
SETPGC000
ENDM
if margins
MACRO OUTPGCOM
SETPG4000
ENDM
endif
MACRO OUTPG4000
SETPG4000
ENDM
MACRO _Loop_
JP (IY) ;EMULOOP
ENDM
;если вместо стр.команд включили др.стр.
MACRO _LoopC
OUTcom
JP (IY)
ENDM
;если резко сменился PC (полный DE)
MACRO _LoopJP
CALCiypgcom
jp DOSER
ENDM
MACRO _LoopJP_NODOS
CALCiypgcom
JP (IY)
ENDM
;если эмулятор щёлкал страницу и резко сменился PC (полный DE)
MACRO _LoopC_JP
CALCiypgcom
jp DOSER
ENDM
MACRO _LoopC_JP_NODOS
CALCiypgcom
JP (IY)
ENDM
;если IN/OUT (могла измениться конфигурация памяти - но там внутри уже CALCpgcom)
MACRO _LoopSWI
;CALCpgcom
JP (IY)
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 margins
include "mem_marg.asm"
else
if MEM48C0
include "mem_48c0.asm"
else
include "mem_c000.asm"
endif
endif
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 ;color byte
;OS_CLS
OS_GETMAINPAGES ;out: d,e,h,l=pages in 0000,4000,8000,c000, c=flags, b=id
push hl
ld hl,temulpgs
ld a,d
ld (deadpg),a
ld (hl),d
ld d,h
ld e,l
inc de
ld bc,64-1
ldir
ld a,(user_scr0_high) ;ok
ld (curpg5),a
ld (temulpgs+5),a
SETPG4000
ld a,(user_scr1_high) ;ok
ld (temulpgs+7),a
;OS_GETMAINPAGES ;out: d,e,h,l=pages in 0000,4000,8000,c000, c=flags, b=id
pop hl
ld a,h
ld (curpg2),a
ld (temulpgs+2),a
ld a,l
ld (temulpgs+0),a
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
;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
call swapimer
;хотя бы одно прерывание, чтобы захватить матрицу клавиатуры
ld b,25
waitstart0
halt ;не YIELD, иначе наш обработчик не вызовется!
djnz waitstart0
;ld a,-1
;ld (doson0),a
xor a
ld (doson0),a
ld (_dffd),a
;ld a,0x10
ld (_fd),a
;LD A,(_fd)
CALL eout7FFD
if 0
LD HL,0
ld d,h
ld e,l
ld b,h
ld c,l
PUSH HL
POP AF
ld (immode),a
PUSH HL
POP ix
ld (_IZ),hl
ld (_AF),hl
ld (_BC),hl
ld (_DE),hl
ld (_HL),hl
EXX
EXA
endif
IF margins
LD HL,currom
LD (curquart),HL
LD A,(HL)
OUTPGCOM
ld de,0x4000 ;пересчитанный PC
else
LD DE,0x0000 ;=PC
endif
LD IY,EMUCHECKQ
;EMUDATABUS ;ШД0..2 на бордюр
;EMUADDRBUS ;ША8..10 ма бордюр
;EMUCHECKPOINT ;проверка адреса или условия
;проверка числа тактов до INT?
jpiyer
ld hl,jpiyer
push hl
jp (iy)
;oldpc
; dw 0
EMUCHECKQ
;ld a,(0x4000)
;or a
;jr z,$
;ld (oldpc),de
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=код команды, если надо ;но надо менять обработчики, они сейчас ждут код в A!
;или ld l,a:ld h,NN:ld h,(hl):jp (hl)
;или ld l,a:or 0xc0:ld h,a:jp (hl)
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)
OUT (-2),A
JP EMUCHECKQ
EMUADDRBUS
LD A,D
OUT (-2),A
JP EMUCHECKQ
EMUCHECKPOINT
retfromim=$+1
LD HL,0
XOR A
SBC HL,DE
JP NZ,EMUCHECKQ
LD A,(_fe)
OUT (-2),A
JP EMUCHECKQ
;OUTA
; PUSH BC
; OUTPG
; POP BC
; RET
EMUOUT
;BC=port, A=value
BIT 0,C
jp 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
BIT 5,B
jr z,eoutDFFD
LD BC,#FFFD
OUT (C),A
RET
eoutDFFD
ld (_dffd),a
ld a,(_fd)
eout7FFD
LD (_fd),A
LD C,A
AND #C7
and 7
ld l,a
ld a,(_dffd)
and 3 ;Profi 512K
add a,a
add a,a
add a,a
add a,l
ld l,a
ld h,temulpgs/256
ld a,(hl)
deadpg=$+1
cp 0
jr nz,eout7FFDOK
push bc
push de
push hl
exx
push bc
push de
push hl
push ix
push iy
exa
push af
OS_NEWPAGE ;мегабайт захватывать динамически постранично
pop af
exa
ld a,e
pop iy
pop ix
pop hl
pop de
pop bc
exx
pop hl
pop de
pop bc
ld (hl),a
eout7FFDOK
LD (curpghi),A
if MEM48C0
push bc
OUTPG
pop bc
endif
LD A,(doson0) ;DOS ports on ;TODO separate flag for DOS ROM select ;TODO RAM in 0000
OR A
jr Z,eo7FFDdos
BIT 4,C ;номер ПЗУ
ld b,DOSSTATE_FROM48
LD A,(pgrom48)
jr NZ,eo7FFDo
ld b,DOSSTATE_FROM128
LD A,(pgrom128)
JR eo7FFDo
eo7FFDdos
BIT 4,C ;номер ПЗУ
ld b,DOSSTATE_FROMDOS
LD A,(pgromDOS)
jr NZ,eo7FFDo
LD A,(pgromSYS)
;JR eo7FFDo
eo7FFDo
LD (currom),A
ld a,b
ld (DOSER_state),a
LD A,C
AND 8 ;номер экрана
LD (curscr),A
oldcurscr7ffd=$+1
cp 0
jr z,eo7FFDnoscr
ld (oldcurscr7ffd),a
;push bc
push de
;push hl
exx
push bc
push de
push hl
push ix
push iy
rrca
rrca
rrca
ld e,a
exa
push af
OS_SETSCREEN
pop af
exa
pop iy
pop ix
pop hl
pop de
pop bc
exx
;pop hl
pop de
;pop bc
eo7FFDnoscr
if MEM48C0
if margins
CALCpgcom
else
enable0000
ld a,0x3e;3a
ld (setrom),a
ld (getde0000ret),a
endif
endif
RET
eoutFE
LD (_fe),A
outFE
OUT (#FE),A
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 0xfd
jr z,einAY
CP #DF
jr Z,einMOUSE
CP #1F
jr Z,einKEMPSTON
LD A,#FF
RET
einAY
ld bc,0xfffd
in a,(c)
ret
einMOUSE
LD A,B
CP #FA
jr Z,einFADF
CP #FB
jr Z,einFBDF
CP #FF
jr Z,einFFDF
LD A,#FF
RET
einFADF
;LD BC,#FADF
;IN A,(C)
mousebuttons=$+1
ld a,0xff
RET
einFBDF
;LD BC,#FBDF
;IN A,(C)
mousex=$+1
ld a,0
RET
einFFDF
;LD BC,#FFDF
;IN A,(C)
mousey=$+1
ld a,0
RET
einKEMPSTON
;IN A,(#1f)
kempston=$+1
ld a,0
RET
einFE
;LD C,#FE
;IN A,(C)
;ld a,b
;or a
;jr z,$
push hl
ld hl,keymatrix
ld a,0xff
dup 8
rlc b
jr c,$+3
and (hl)
inc hl
edup
pop hl
and a
;LD C,#FE
;IN A,(C)
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
ld a,r
rla
and 0xc0 ;D6=DRQ, D7=INTRQ
RET
eid1F
;LD A,#80 ;команда выполнена ok, диск вставлен
ld a,r
fddstatemask=$+1
and 3
or 0x80
RET
eid3F
LD A,(dos3F) ;trk
RET
eid5F
LD A,(dos5F) ;sec
RET
keymatrix
ds 8,0xff
if 0
imitret
LD HL,(_SP)
getmemBC
LD (_SP),HL
ld d,b
ld e,c
_LoopC_JP
endif
DOSrdindex
LD A,E
cp #08
jr z,DOSsetheadwait
CP #b2 ;#3eb2
jr nz,jpiy;ret nz
;Адрес #3EB2. Проверка индексной области дорожки. Установите #5CD1 и поместите в B время перемещения головки дисковода. Выбирается верхняя сторона и при ошибке в #5D17 помещается #FF. В регистр H помещается номер текущей дорожки. Используется также с адреса: #3EE7 (обработка ошибки NO DISC).
ld a,(dos3F) ;trk
exx
ld h,a
exx
jp imitret
DOSsetheadwait
ld a,3
ld (fddstatemask),a ;костыль!!!
jp imitret
DOSER
;после каждой команды, меняющей PC ;выход по jp (iy)
;если мы не в досе, то проверяем, что D=#3D
;если мы в досе, то проверяем, что D<=#40
;если мы в 128K (TODO или в ОЗУ 0000), то ничего не делаем
DOSSTATE_FROM48=0x18 ;jr DOSERny
DOSSTATE_FROMDOS=0x3e ;ld a,N (skip jr)
DOSSTATE_FROM128=0xc9 ;ret
;LD A,(doson0)
;OR A
;jr NZ,DOSERny
DOSER_state=$
jr DOSERny
if margins
ld a,(curquart)
cp 3 ;0000?
jr z,DOSDOS ;DOS -> DOS
else
LD A,D
CP #40
jr C,DOSDOS ;DOS -> DOS
endif
;DOS -> неDOS
;выкл. стр. доса
LD A,-1
LD (doson0),A ;DOS ports off
ld a,DOSSTATE_FROM48
ld (DOSER_state),a
LD A,(_fd)
call eout7FFD
jpiy
jp (iy)
DOSDOS
;для SYS не перехватываем!
LD A,(_fd)
AND 16
jr z,jpiy;RET Z
ld a,d
;перехваты процедур доса
if margins
cp 0x3e+0x40
else
cp 0x3e
endif
jr z,DOSrdindex
if margins
cp 0x3f+0x40
else
cp 0x3f
endif
jr nz,jpiy;RET NZ ;не перехватываем
;имитировать RET после неё
LD A,E
CP #D5 ;#3fd5
jr Z,DOSRD
CP #E5 ;#3fe5
jr Z,DOSRD
CP #BA ;#3fba
jr z,DOSWR
jp (iy) ;RET NZ
DOSRD
xor a
ld (fddstatemask),a ;костыль!!! иначе читает через раз
PUSH DE,IX,IY
EXX
PUSH HL
INC H
EXX
POP HL
LD C,5
LD A,(dos3F) ;trk
ADD A,A
LD D,A
LD A,(dosFF)
BIT 4,A
jr nz,$+3
INC D
LD A,(dos5F) ;sec
DEC A
LD E,A
CALL DOSrdsec
POP IY,IX,DE
DOSWR
;TODO
jp imitret
DOSERny
;from 48/RAM
if margins
ld a,d
cp 0x3d+0x40
jr nz,jpiy;RET NZ
ld a,(curquart)
cp 3 ;0000?
jr nz,jpiy;RET NZ
else
LD A,D
CP #3D
jr nz,jpiy;RET NZ
endif
;для 128 васика запрещено! иначе глючит калькулятор
;LD A,(_fd)
;AND 16
;RET Z
;неDOS -> DOS
LD A,E
CP #13
jr Z,DOS3D13 ;если убрать, будет значительно медленнее
DOSSWON
;вкл. стр. доса
;имитация RET не катит для точки #3D2F
XOR A
LD (doson0),A ;DOS ports on
ld a,DOSSTATE_FROMDOS
ld (DOSER_state),a
LD A,(_fd)
call eout7FFD
jp (iy)
DOS3D13
exx
ld a,c
exx
cp 6
jr z,DOSWRSEC
cp 5
jr nz,DOSSWON ;(for other functions)
DOSRDSEC
DOSWRSEC
exx
D3D5S0
CALL DOSrdsec ;c=5(read)/6(write)
inc h
inc e
bit 4,e
jr z,$+5
inc d
ld e,0
DJNZ D3D5S0
;write de to virtual 23796:
ld hl,23796
ld b,d
ld c,e
putmemBC
exx
jp imitret ;имитировать 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 in file
diskhandle=$+1
ld b,0
push bc ;c=5/6
OS_SEEKHANDLE
pop bc ;c=5/6, b=handle
pop hl ;addr
bit 0,c
jr nz,DOSrdsec5
ld de,secbuf
push bc
push de
ld b,0
DOSwrseccopy0
push bc
push hl
getmem
ld (de),a
pop hl
pop bc
inc hl
inc de
djnz DOSwrseccopy0
pop de ;secbuf
pop bc ;b=handle
ld hl,256 ;de=phys addr ;hl=size
OS_WRITEHANDLE
jr DOSrdsec5ok
DOSrdsec5
push hl ;addr
ld de,secbuf
push de
ld hl,256 ;size
OS_READHANDLE
pop hl ;secbuf
pop de ;addr
ex de,hl ;de->hl
ld b,0
DOSrdseccopy0
push bc
push hl
ld a,(de)
putmem
pop hl
pop bc
inc hl
inc de
djnz DOSrdseccopy0
DOSrdsec5ok
exx
EXA
pop iy,ix
pop hl,de,bc
pop af
EXA
EXX
pop hl,de,bc
ret
INCLUDE "disasm.asm"
INCLUDE "z80cmd.asm"
align 256
INCLUDE "z80table.asm"
DISPLAY $
IF stats
align 256
comstats
DISPLAY "comstats=",$
DS #400
ENDIF
include "rst38.asm"
on_int
;jp IMER
;IMER
PUSH AF,HL
push bc,de
exx
push bc
push de
push hl
push ix
push iy
ex af,af' ;'
push af
ld a,(curscr)
oldcurscr=$+1
cp 0
jr z,IMERnoscr
ld (oldcurscr),a
rrca
rrca
rrca
ld e,a
OS_SETSCREEN
IMERnoscr
ld a,(_fe)
and 7
oldcurborder=$+1
cp 0
jr z,IMERnoborder
ld (oldcurborder),a
ld e,a
OS_SETBORDER
IMERnoborder
call oldimer
if 0
ld bc,0x7ffe
in a,(c)
ld lx,a ;lx=%???bnmS_
ld b,0xbf
in a,(c)
ld hx,a ;hx=%???hjklE
ld b,0xdf
in l,(c) ;l=%???yuiop
ld b,0xef
in h,(c) ;h=%???67890
ld b,0xf7
in e,(c) ;e=%???54321
ld b,0xfb
in d,(c) ;d=%???trewq
ld a,0xfd
in a,(0xfe);c=%???gfdsa
ld b,c;0xfe
in b,(c) ;b=%???vcxzC
ld c,a
else
OS_GETKEYMATRIX ;out: bcdehlix = halfrows cs...space
endif
ld (keymatrix),ix
ld (keymatrix+2),hl
ld (keymatrix+4),de
ld (keymatrix+6),bc
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), то отсутствует фокус.
jr nz,IMERnofocus
ld a,e
ld (mousex),a
ld a,d
ld (mousey),a
ld a,l
ld (mousebuttons),a
ld a,lx
ld (kempston),a
IMERnofocus
;TODO здесь опрос клавиш эмулятора
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)
LD (keepemuchecker),IY
LD IY,IMINT
POP HL,AF
RET ;di!
IMINT
keepemuchecker=$+2
LD IY,0
LD (retfromim),DE ;для индикации времени обработки прерыв
LD A,(immode)
CP #18 ;IM2
LD HL,#38 ;new PC
jr NZ,IMERIM1
LD HL,(_I-1)
LD L,#FF ;состояние пассивной ШД
getmemBC
ld h,b
ld l,c
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
if MEM48C0
call set4000
endif
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
;hl=new PC
EI
CALCpc ;de=old PC
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
if MEM48C0
setmem00004000forwrite
;NC, keep CY (keep A for rra:ld h,a)
;если 0000 (p) и включено ПЗУ, то должен ld h,secbuf/256
;иначе setmem00004000
ROMSTATE_ON=0xf2 ;jp p
ROMSTATE_OFF=0xda ;jp c
romstate=$
jp p,setmem00004000forwrite_skip
setmem00004000
jp m,set4000forwrite
set 6,h
setrom
if !margins
ld a,0xc9 ;/RET
ld (setrom),a
ld (getde0000ret),a
ld a,0x3e;3a
ld (set4000),a
ld (set4000forwrite),a
endif
ld a,(currom) ;0000
push bc
OUTPG4000
pop bc
ld a,h
sub 64
add a,a
ret
setmem00004000forwrite_skip
ld h,secbuf/256
ret
set4000forwrite
if !margins
ld a,0xc9 ;/RET
ld (set4000),a
ld (set4000forwrite),a
ld a,0x3e;3a
ld (setrom),a
ld (getde0000ret),a
endif
ld a,(curpg5) ;4000
push bc
OUTPG4000
pop bc
ld a,h
add a,a
ret
set4000
if !margins
ld a,0xc9 ;/RET
ld (set4000),a
ld (set4000forwrite),a
ld a,0x3e;3a
ld (setrom),a
ld (getde0000ret),a
endif
ld a,(curpg5) ;4000
push bc
OUTPG4000
pop bc
ld a,(de) ;for getde00004000
ret
getde0000l_getde00004000
call getde0000
ld l,a
inc de
ld a,d
add a,a ;check 3fff->4000
getde00004000
jp m,set4000
getde0000
if !margins
set 6,d
ld a,(de)
res 6,d ;fastest branch! no extra commands!
getde0000ret
ld a,0xc9 ;/RET
ld (setrom),a
ld (getde0000ret),a
ld a,0x3e;3a
ld (set4000),a
ld (set4000forwrite),a
endif
ld a,(currom) ;0000
OUTPG4000
set 6,d
ld a,(de)
res 6,d
ret
endif
if margins
next_incd
inc d
ret nz
ld d,0xc0
ld hl,(curquart)
inc l
res 2,l
ld (curquart),hl
ld a,(hl)
OUTPGCOM
ret
endif
align 256
temulpgs
ds 64 ;пока используем 8
pgrom48
db 0
pgrom128
db 0
pgromDOS
db 0
pgromSYS
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 ;с точки зрения эмулимой проги
_dffd db 0
_fe DB 0
dos3F DB 0
dos5F DB 0
dosFF DB 0
if margins
curquart
DW currom
align 256
endif
;реальные банки (лежат подряд для margins)
curpg5 DB 0 ;for 4000
curpg2 DB 0 ;for 8000
curpghi DB 0 ;for c000
currom DB 0 ;for 0000
curscr DB 0 ;0/8
;romon0 DB 0 ;#C0=ОЗУ, 0=ПЗУ в нижних 16k ;теперь в romstate
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
diskname
db "SYS.TRD",0
trom48
;DB "2006.ROM",0
;DB "1982.ROM",0
DB "48for128.rom",0
;DB "testatm.rom",0
trom128
DB "128tr.rom",0
;DB "testatm.rom",0
tromSYS
DB "GLUKPEN.ROM",0
;DB "testatm.rom",0
tromDOS
DB "DOS6_10E.ROM",0
;DB "testatm.rom",0
if 0
sysvars
incbin "goodsysv"
sz_sysvars=$-sysvars
endif
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
end
align 256 ;for setmem00004000forwrite
rrdbuf ;DB 0
secbuf
ds 256
display secbuf+256
savebin "z80.com",begin,end-begin
LABELSLIST "../../us/user.l"