DEVICE ZXSPECTRUM1024
include "../_sdk/sys_h.asm"
bigmem=1
atm=1
p3dos=0
USE_STDIO=0
STACK=0x4000
BANKN_TERMINATOR=0xff
macro SELMEM
ld b,tpgs/256
ld c,a
ld a,(bc)
;or a
;jr z,$
SETPGC000
endm
org PROGSTART
begin
ld sp,STACK
if USE_STDIO
call initstdio
else
OS_HIDEFROMPARENT
ld e,3+0x80 ;6912 + keep gfx pages
OS_SETGFX ;e=0:EGA, e=2:MC, e=3:6912, e=6:text ;+SET FOCUS ;e=-1: disable gfx (out: e=old gfxmode)
endif
if 1
OS_GETMAINPAGES
push hl
;dehl=номера страниц в 0000,4000,8000,c000
ld hl,tpgs
ld b,64;32
getpgs0
push bc
push hl
OS_NEWPAGE
;ld a,e
;SETPGC000
;push de
;ld hl,0xc000
;ld de,0xc001
;ld bc,0x3fff
;ld (hl),l
;ldir
;pop de
pop hl
ld (hl),e
inc hl
pop bc
djnz getpgs0
LD A,pg1
CALL selmem
ld a,5 ;z-machine version
ld (0xc000),a
pop hl
ld a,l ;как было
SETPGC000
endif
;ld de,path
;OS_CHDIR
ld hl,COMMANDLINE ;command line
;command line = "zxzvm <file>"
call skipword
ld a,(hl)
or a
jr z,nofilename
call skipspaces
ld de,tfilename
call getword
;call untr_load
nofilename
ld hl,tfilename
ld de,0x705C
copyfilename0
ld a,(hl)
ldi
or a
jr nz,copyfilename0
dec de
dec a ;0xff
ld (de),a
inc de
ld a,'$' ;на всякий случай
ld (de),a
call main
ld hl,0
QUIT
path
db "zxzvm",0
align 256
tpgs
ds 256
tfilename
db "zxzvm/heroes.z5",0
ds tfilename+DIRMAXFILENAME64-$
getword
;hl=string
;de=wordbuf
;out: hl=terminator/space addr
getword0
ld a,(hl)
or a
jr z,getwordq
sub ' '
jr z,getwordq
ldi
jp getword0
getwordq
;xor a
ld (de),a
ret
skipword
;hl=string
;out: hl=terminator/space addr
skipword0
ld a,(hl)
or a
ret z
sub ' '
ret z
inc hl
jp skipword0
skipspaces
;hl=string
;out: hl=after last space
ld a,(hl)
cp ' '
ret nz
inc hl
jr skipspaces
if USE_STDIO
include "../_sdk/stdio.asm"
endif
ds #4000-$
IF atm
MAXMEM EQU #0E ;ATM-Turbo 2+ = #E0000
;BANKIO EQU #FFF7
PGBUF=6;#7F^6
pg1=1;#7F^8 ;header
pg3=3;#7F^3
pg6=6;#7F^6 ;buf
;pg7=#7F^7 ;scr
ELSE
MAXMEM EQU #07 ;Пентагон 512 = #70000
;BANKIO EQU #7FFD
PGBUF=#1E
pg1=1
pg3=3
pg6=6
;pg7=7
ENDIF
;USED EQU #38 ;число которое будет накладываться по AND
;и т.о. гасить биты
;отвечающие за страницы и не изменять другие
;GASIM EQU #C7 ;если поступила в A не
;только информация о номере (физическом)
;страницы, то лишнюю информацию надо
;уничтожить. Уничтожаем с помощью AND GASIM
TABLE1 EQU #9E ;верхняя часть адреса
;где располагается таблица для перекл.
;нижних 64K
TABLE2 EQU #9F ;верхняя часть адреса
;где располагается таблица для переключения памяти >64K
INCLUDE "in_zxzvm.asm" ;header с EQU #4000+3*N
ONERR EQU #5B3A ;Memory paging subroutine used in reporting
;errors
BANKM EQU #5B5C ;Memory paging latch
OLDSP EQU #5B6A ;Saved stack pointer used while BASIC is
;calling +3DOS
SYNRET EQU #5B6C ;Return address for ONERR
ERRNO EQU #5C3A ;Spectrum BASIC error number
BORDCR EQU #5C48 ;Border colour
ATTR_P EQU #5C8D ;Current screen colours set by BASIC
RAMTOP EQU #5CB2 ;Top of BASIC's memory (bottom of ZXZVM)
PRAMT EQU #5CB4 ;Top of physical memory
;Graphics characters used by the 64-column printing system
GTLC EQU 142 ;Top left corner
GTRC EQU 130 ;Top right corner
GBLC EQU 133 ;Bottom left corner
GBRC EQU 134 ;Bottom right corner
GTL EQU 129 ;Top line
GBL EQU 135 ;Bottom line
GLL EQU 131 ;Left side
GRL EQU 132 ;Right side
GLJ EQU 136 ;Left side /internal line junction
GRJ EQU 137 ;Right side/internal line junction
GIL EQU 138 ;Internal line
;Cursor keys
LA EQU 8 ;<-
RA EQU 9 ;->
UA EQU 11 ;^
DA EQU 10 ;DOWN ARROW
CR EQU #0D
LF EQU #0A
JP init1 ;Initialise, load story file
JP exit1 ;Deinitialise
JP cls1 ;Clear screen
JP peek1 ;Read byte from Z-machine memory
JP poke1 ;Write byte to Z-machine memory
JP peek64 ;Read byte from low 64k
JP peekw ;Read word from Z-machine memory
JP ipeekw ;Read word with auto increment
JP fdos1 ;CP/M-like I/O functions
JP ihdr1 ;Initialise the header
JP tmem1 ;Get top of available host memory
JP eraw1 ;Erase window
JP zchr1 ;Output a ZSCII letter in HL.
JP swnd1 ;Split window
JP swnd2 ;Select window
JP styl1 ;SET text style
JP scur1 ;SET cursor position
JP LINEINP ;Line input
JP RCHAR ;Read character
JP scol1 ;SET colours
JP sfnt1 ;SET font
JP rndi1 ;Get randomish number (eg,the computer's clock)
JP getx1 ;Get cursor X position
JP gety1 ;Get cursor Y position
JP strm1 ;Open or close stream in A
JP eral1 ;Erase to EOL
JP snd1 ;MAKE a sound
JP rst1 ;Restart
JP GNAME ;Get filename
JP p3opn ;Open file
JP p3clse ;Close file
JP p3read ;Read bytes
JP p3write ;Write bytes
JP p3rmem ;Read z-machine memory
JP p3wmem ;Write z-machine memory
JP p3vrfy ;Verify the game file
;<< v0.02
JP bfit1 ;Check if word in buffer will fit on screen.
RET
NOP
NOP ;Relinquish the CPU, or rather don't.
JP yes_i_live
LD A,VMVER ;Return version
RET
RET ;Update the screen. Not necessary.
NOP
NOP
;>> v0.02
oldHL_
DW 0
;;;
init1
LD (story),DE
IF atm
;LD A,#18
;LD BC,#7FFD
;OUT (C),A
;CALL ATMON
LD HL,TABLE1*256
LD A,8;#7F^8 ;FIXME
MKTAB10 LD (HL),A
inc a;DEC A
INC L
jr NZ,MKTAB10
LD HL,TABLE2*256
LD A,8;#7F^8
MKTAB20 LD (HL),A
add a,4;SUB 4
INC L
jr NZ,MKTAB20
ELSE
CALL vers
ENDIF
;EXX
;LD (oldHL_),HL
;EXX
JR init2
;ld de,0100h
;0201 => +3 with Amstrad ROMs
;0100 => Sinclair 128
;and a
;sbc hl,de
;jr z,init2
;ld hl,reqp3
;xor a
;ret
init2
CALL ZXCLS ;Clear the shadow screen
ld e,1
OS_SETSCREEN
LD A,1
LD (cfont),A ;SET current font
IF atm
LD A,pg6
ELSE
LD A,(BANKM)
AND USED ;Switch to bank 6 at the same time...
OR #0E ;Activate the shadow screen
;DI
ENDIF
LD (BANKM),A
call selmem
;LD BC,BANKIO
;OUT (C),A
;EI
CALL dosinit ;!
;Initialise +3DOS
RET NC
LD DE,signon
CALL PRINT ;Sign on
;ld de,copyright
;call PRINT
LD HL,(story)
pslp
LD E,(HL)
INC E ;Print story name (FF-terminated)
JR Z,pslend
DEC E
CALL OPCHAR
INC HL
JR pslp
;pslend ld de,sign1 ;Second part of sign-on message
;call PRINT
pslend
LD HL,(story)
CALL st_open ;!
;Load the story file
RET NC
CALL ZXCLS
LD A,pg6
CALL selmem
SCF
RET
;Restart
rst1
LD HL,#10 ;Flags 2 is preserved through a restart
CALL ZXPK64
LD B,A
INC HL
CALL ZXPK64
LD C,A
PUSH BC
LD DE,rest_
CALL PRINT
CALL st_reload
POP BC
RET NC
LD HL,#10
LD A,B ;Restore Flags 2
CALL ZXPOKE
INC HL
LD A,C
CALL ZXPOKE
CALL ZXCLS
LD A,1
LD (cfont),A
SCF
RET
;;;
exit1
PUSH AF
PUSH HL
if 0
EXX
LD HL,(oldHL_)
EXX
endif
CALL st_close
CALL dosunit ;Undo anything we did to +3DOS
if 1
POP HL
POP AF
RET C ;IF Carry was set, return (zmexit)
;ld hl,(ERRNO)
;ld h,0
pop hl ;error=return addr
QUIT
else
DI ;Switch back to the conventional screen
LD A,(BANKM)
AND #F0
DI
LD (BANKM),A
LD BC,BANKIO
OUT (C),A
EI
POP HL
POP AF
RET C ;IF Carry was set, return
EX DE,HL
LD A,(ERRNO) ;Error number has been set elsewhere.
INC A ;Don't try to guess it.
JP NZ,ZXERR
LD A,(DE) ;1st byte of return string could be an
;ASCII error number
CP "0"
JP C,ZXERR
CP "9"+1
JR C,setnum
CP "A"
JP C,ZXERR
CP "Z"+1
JP NC,ZXERR
;setlet
SUB 7
setnum
SUB "1"
LD (ERRNO),A
JP ZXERR
endif
;;;
cls1
;LD A,pg7
CALL selmemscr
LD HL,#C000 ;Clear the screen bitmap
LD D,H
LD E,L
INC DE
LD BC,#17FF
LD (HL),L
LDIR
INC HL
INC DE
JR clattr1
;Clear colours only
clattr
;LD A,pg7
CALL selmemscr
LD HL,#D800
LD D,H
LD E,L
INC DE
clattr1
LD BC,#2FF
LD A,7;(ATTR_P)
LD (HL),A
LDIR
LD A,0;(BORDCR)
RRCA
RRCA
RRCA
AND 7
OUT (254),A
RET
;;;
HL_ DB #00,#00 ;Дабы не мучаться со стеком (записывается в getbyte)
TEMP DB #00 ; Надо для исп. команды RRD
;;;
IF bigmem == 0
getbyte ;128K
LD A,(BANKM) ;Запоминаем банку
LD (TEMPBANKA),A ;для последующего (в конце)
;к ней возврата
LD (HL_),HL
PUSH BC
LD B,#06 ;Переключение на буфер
LD A,(BANKM) ;(страница 6)
AND USED
OR B
LD BC,BANKIO
OUT (C),A
LD A,E ;склеиваем правую поло-
LD B,H ;винку E и левую H
LD HL,TEMP ;подробнее смотри в
LD (HL),B ;tr-dos+.zsm
RRD
LD A,(HL)
AND #FC ;гасим два бита 0-ой 1-й
LD H,A
LD A,(BUFMEM)
SUB H ;не содержится ли требуемый адрес
;уже в буфере? Если нет, то вызов процедуры st_peek
LD HL,(HL_)
CALL NZ,st_peek
;Вызов процедуры загрузки 16K
;буфера содержащего запрашиваемый адрес
LD A,#C0 ;Ложим байт в A из нуж-
OR H ;ной страницы по нужно-
LD H,A ;му адресу
LD A,(HL)
LD L,A
LD A,(TEMPBANKA) ;Переключаемся
LD BC,BANKIO ;обратно банку
OUT (C),A ;бывшую до getbyte
LD A,L
POP BC
LD HL,(HL_)
SCF
EI
RET
peek1 ;128K
DI
LD A,E
;First 64k? IF not, access file on disc
AND A
JR NZ,getbyte
peek64 ;128K
DI
PUSH BC
LD (HL_),HL
LD A,(BANKM)
LD (TEMPBANKA),A
AND USED ;Only change the memory banking settings
LD C,A
LD A,H
RLCA
RLCA
AND 3 ;A = Z-machine bank, 0-3
LD L,A
LD H,TABLE1
LD A,(HL)
OR C
LD BC,BANKIO
OUT (C),A
LD HL,(HL_)
LD A,#C0
OR H
LD H,A ;HL |= #C000
LD A,(HL)
LD L,A
LD A,(TEMPBANKA)
LD BC,BANKIO
OUT (C),A
LD A,L
POP BC
LD HL,(HL_)
SCF
EI
RET
ENDIF ;128K
IF bigmem
peek1
DI ;FIXME
LD A,E
IF atm == 0
;First 64k? IF not, access file on disc
AND A
JR Z,peek64nDI
CP MAXMEM ;addr>=#70000?
JR NC,BANKA6
ENDIF
EXX
LD L,A
EXX
;LD A,(BANKM) ;Запоминаем банку
;LD (TEMPBANKA),A ;для последующего (в конце)
;к ней возврата
;LD (HL_),HL
;PUSH BC
;LD A,E
;CP MAXMEM ;Пентагон 512 может
;содержать в памяти адреса от #00000 до #6ffff
;JR NC,BANKA6
LD A,H
EXX
RLCA
RLCA
AND %00000011
LD H,TABLE2
;LD L,E
IF atm
XOR (HL)
ELSE
OR (HL)
ENDIF
;Получаем банку, которую нужно включить
;LD B,A ;Включаем банку
;LD A,(BANKM) ;расширенной
;AND USED ;памяти
;OR B
;LD BC,BANKIO
;OUT (C),A
SELMEM
EXX
;LD HL,(HL_)
CONT
PUSH HL
LD A,#C0 ;Ложим байт в A из нуж-
OR H ;ной страницы по нужно-
LD H,A ;му адресу
;LD A,(HL)
;LD L,A
LD L,(HL)
;LD A,(TEMPBANKA) ;Переключаемся
LD A,(BANKM)
EXX
;LD BC,BANKIO ;обратно банку
;OUT (C),A ;бывшую до getbyte
SELMEM
EXX
LD A,L
;POP BC
;LD HL,(HL_)
POP HL
SCF
EI
RET
IF atm == 0
BANKA6
;Переключение на буфер-страницу
PUSH HL
;LD B,#06
;LD A,(BANKM)
;AND USED
;OR B
LD A,PGBUF
EXX
;LD BC,BANKIO
;OUT (C),A
SELMEM
EXX
;LD A,E
;LD B,H
LD A,H
LD HL,TEMP
;LD (HL),B
LD (HL),A
LD A,E
RRD
LD A,(HL)
AND #FC ;гасим два бита 0-ой 1-й
LD H,A
LD A,(BUFMEM)
SUB H ;не содержится ли требуемый адрес
;уже в буфере? Если нет, то вызов процедуры st_peek
;LD HL,(HL_)
POP HL
CALL NZ,st_peek
;Вызов процедуры загрузки 16K
;буфера содержащего запрашиваемый адрес
JP CONT
ENDIF
peek64
DI
peek64nDI ;
;PUSH BC
;LD (HL_),HL
;LD A,(BANKM)
;LD (TEMPBANKA),A
;AND USED ;Only change the memory banking settings
;LD C,A
LD A,H
RLCA
RLCA
AND 3 ;A = Z-machine bank, 0-3
EXX
LD L,A
LD H,TABLE1
LD A,(HL)
;OR C
;LD BC,BANKIO
;OUT (C),A
SELMEM
EXX
;LD HL,(HL_)
JP CONT
ENDIF
;
btrace
CALL PUSHA
OUT (254),A
yil11
CALL CON6
OR A
JR Z,yil11
JP POPA
;
slowpw
CALL peek1
DI
LD B,A
INC HL
LD A,H
OR L
JR NZ,slowp1
INC E
slowp1
CALL peek1
DI
INC HL
LD C,A
LD A,H
OR L
JR NZ,slowp2
INC E
slowp2
;POP AF
EX AF,AF' ;'
SCF
EI
RET
;
peekw
PUSH HL
PUSH DE
CALL ipeekw
POP DE
POP HL
RET
;
ipeekw
DI
;PUSH AF
EX AF,AF' ;'
LD A,E
OR A ;Is the word in RAM?
JR NZ,slowpw
LD A,L
;CP #FF
INC A ;Is there a chance the word might go across 2 pgs?
JR Z,slowpw
;Read a word from the low 64k
;we know it does not extend over a page boundary
PUSH HL
;PUSH DE
;LD A,(BANKM)
;LD (TEMPBANKA),A
;AND USED ;Only change the memory banking settings
;LD C,A
LD A,H
RLCA
RLCA
AND 3 ;A = Z-machine bank, 0-3
;PUSH HL
EXX
LD L,A
LD H,TABLE1
LD A,(HL)
;OR C
;LD BC,BANKIO
;OUT (C),A
SELMEM
;POP HL
EXX
LD A,#C0
OR H
LD H,A ;HL |= #C000
;LD D,(HL)
LD B,(HL)
INC HL
;LD E,(HL)
LD C,(HL)
;LD L,A
;LD A,(TEMPBANKA)
LD A,(BANKM)
EXX
;LD BC,BANKIO
;OUT (C),A
SELMEM
EXX
;LD A,L
;LD B,D
;LD C,E
;POP DE
POP HL
INC HL
INC HL
LD A,H ;<< v1.03 Check for rollover at FFFE ->>10000
OR L
;JR NZ,fpw1
JR Z,fpwinc
EX AF,AF' ;'
SCF
EI
RET
fpwinc
INC E
fpw1
;>> v1.03
;POP AF
EX AF,AF' ;'
SCF
EI
RET
;;;
poke1
DI
PUSH HL
;PUSH DE
;PUSH BC
;LD D,A
EX AF,AF' ;'
;LD A,(BANKM)
;LD (TEMPBANKA),A
;AND USED
;LD C,A
LD A,H
RLCA
RLCA
AND 3
;PUSH HL
EXX
LD L,A
LD H,TABLE1
LD A,(HL)
;OR C
;LD BC,BANKIO
;OUT (C),A
SELMEM
;POP HL
EXX
LD A,#C0
OR H
LD H,A ;HL|=#C000
;LD (HL),D
EX AF,AF' ;'
LD (HL),A
;LD L,A
;LD A,(TEMPBANKA)
LD A,(BANKM)
EXX
;LD BC,BANKIO
;OUT (C),A
SELMEM
EXX
;LD A,L
;POP BC
;POP DE
POP HL
SCF
EI
RET
;;;
;SET screen colours
;Since this I/O model does not support colour (Spectrum colour
;clash means the lines of text don't match the colours) this is
;disabled pro tem. What it would normally do is set colours for
;the whole screen...
scol1
SCF
RET
;Colour map. ibm2zx[ibm_col] = zx_col
ibm2zx
DEFB 0,2,4,6,1,3,5,7
zx2ibm
DEFB 0,4,1,6,2,3,5,7
def_fg
DEFB 0 ;Default FG
def_bg
DEFB 0 ;Default BG
;;;
;<< v0.02
;Work out whether a word will fit on the line. Since the +3 uses
;a fixed-pitch font, we don't need to bother with what the text
;actually says, only with its length. B=no. of letters and C=no.
;of spaces.Return 0 to print everything,1 to print letters only,
;2 to print carriage return and then everything.
bfit1
DI
CALL getx1 ;H = amount of space on the line
LD D,0 ;D = value to return.
LD A,C
ADD A,B ;A = total chars in line
CP H
LD A,D
RET C ;The whole lot will fit.
;See if the word will fit.
INC D
LD A,B
CP H
LD A,D
RET C ;Letters only will fit
INC A ;Nothing will fit, return 2.
SCF
RET
;>> v0.02
;;;
;Get X position in L, chars left in H, total screen width in A
getx1
LD HL,(uwx) ;<< v0.04 use UWX/LWX, not XPOS.
LD A,(cwin)
OR A
JR Z,getx2
LD HL,(lwx)
getx2
LD A,64 ;>> v0.04
SUB L
LD H,A
LD A,64
SCF
RET
;Get Y position in L
gety1
LD HL,(uwx)
LD A,(cwin)
OR A
JR Z,gety2
LD HL,(lwx)
gety2
LD L,H
LD H,0
SCF
RET
;;;
eral1
DI
LD HL,(XPOS)
PUSH HL
LD A,(HVF)
PUSH AF
LD A,(ulf)
PUSH AF
XOR A
LD (HVF),A
LD HL,(uwx)
LD A,(cwin)
OR A
JR Z,eral2
LD HL,(lwx)
eral2
LD (XPOS),HL
LD A,63
SUB L
JR Z,eral9
LD B,A
eral3
LD E," "
CALL OPCHAR
DJNZ eral3
eral9
POP AF
LD (ulf),A
POP AF
LD (HVF),A
POP HL
LD (XPOS),HL
SCF
EI
RET
;;;
;SET font.
;The Spectrum uses only one font, but it serves as no.1
;or no. 4
sfnt1
CP 1 ;Font is not valid
JR Z,sfnt2
CP 3
JR Z,sfnt2
CP 4
JR Z,sfnt2
XOR A
RET
sfnt2
LD HL,(cfont) ;Font is valid
LD (cfont),A
LD A,L
RET
cfont
DEFB 0
;;;
;SET output stream
strm1
CP 2 ;Open a transcript
JP Z,ts_open
CP #FE ;Close a transcript
JP Z,ts_close
SCF
RET
;;;
;A Spectrum clone of CP/M's BDOS functions dealing with console
;I/O
;These functions are mainly intended for diagnostic code
fdos1
LD A,C
CP 1
JR Z,ichr1
CP 2
JR Z,opc1
CP 6
JR Z,dcio1
CP 9
JR Z,print1
LD A,C
LD DE,badfun
CALL sphex2 ;Write function number into error message
LD HL,unimpl
XOR A
RET
ichr1
CALL CON6 ;1. Input character with echo
OR A
JR Z,ichr1
LD E,A
opc1
CALL OPCHAR ;2. Output character
SCF
RET
dcio1
LD A,E ;6. Direct console input/output
CP #FD
JR C,opc1
JR Z,ichr2 ;6/FD: Input character, no echo
CP #FE
JR Z,pkbd1 ;6/FE: Poll keyboard,return 1 if char waiting
CALL CON6
SCF ;6/FF: Poll keyboard, return char if char waiting
RET
pkbd1
CALL CON6 ;6/FE
OR A
SCF
RET Z
LD A,1
RET
ichr2
CALL CON6 ;6.FD
OR A
JR Z,ichr2
SCF
RET
print1
LD A,1
LD (WRAP),A
print2
LD A,(DE)
CP "$"
JR Z,endpr
LD L,A
LD H,0
PUSH DE
CP #0A
CALL NZ,out1
POP DE
INC DE
JR print2
;call print ;9. Print $-terminated string
endpr
XOR A
LD (WRAP),A
SCF
RET
;;;
ihdr1
;The header is at 1:C000. So page it in and access it directly.
LD A,pg1
CALL selmem
LD A,(#C000) ;Z-machine version
LD (zver),A
LD DE,zvbuf
LD L,A
LD H,0 ;CREATE the "invalid version" error
CALL spdec3
EX DE,HL
DEC HL
SET 7,(HL) ;Fatal error, so set bit 7 of last char
LD HL,zvbad
LD A,(zver)
CP 3 ;<< v0.04 allow v3 games
JR Z,okver ;<< v0.04
CP 4 ;<< v1.10 allow v4 games
JR Z,okver ;>> v1.10
CP 8
JR Z,okver
CP 5
JR NZ,ihdr8
;Version is acceptable
;nb: the Z-machine is big-endian, but the Spectrum is
;little-endian. So the LSB of a word will be in H.
okver
CP 4 ;v3 flags or v4 flags?
LD HL,(#C001) ;Flags 1
LD A,L
JR NC,v4flag
AND #9F ;Reset bits 5,6
JR cflag
v4flag
AND #B8 ;Reset bits 0,1,2,5
OR #98 ;SET bits 7,3 & 4
cflag
LD L,A
LD (#C001),HL
LD HL,(#C010) ;Flags 2
LD A,H
AND #43 ;No pictures, no mouse, no UNDO, no sound
LD H,A
RES 0,L ;"Menus" bit
LD (#C010),HL
LD HL,scrset5
LD DE,#C020
LD BC,8
LDIR
LD A,(ATTR_P)
PUSH AF
AND 7 ;Current ink
LD HL,zx2ibm
CALL xlat
LD A,(HL)
LD (#C02D),A
LD (def_fg),A
POP AF
RRCA
RRCA
RRCA ;Current paper
AND 7
LD HL,zx2ibm
CALL xlat
LD (#C02C),A
LD (def_bg),A
SCF
DEFB #0E ;LD C, which will swallow the AND A
ihdr8
AND A
ihdr9
PUSH AF
LD A,pg6
CALL selmem
POP AF
RET
;Screen settings for a v5 game
scrset5
DEFB 32,64,1,0,0,192,4,6 ;32x64 chars 192x256 pels
;Translate A -> HL[A]
xlat
PUSH HL
xlat1
OR A
JR Z,xlat2
INC HL
DEC A
JR xlat1
xlat2
LD A,(HL)
POP HL
RET
;;;
tmem1
LD HL,#BFFF ;Top of memory. The top16k is a
RET ;disk cache; we may have to shrink this.
;;;
rndi1
;LD DE,(FRAMES)
push af
push bc
push hl
OS_GETTIMER ;dehl
ex de,hl
pop hl
pop bc
pop af
RET
;;;
eraw1
CP #FF ;Erase screen?
JR Z,erall
CP #FE
JP Z,cls1
OR A
JR Z,erabot
DEC A
JR Z,eratop
erawi
LD HL,badera
XOR A
RET
eratop
;LD A,pg7 ;<< v1.02
;CALL selmem ;>> v1.02
CALL selmemscr
LD A,(lwtop)
LD C,A
LD B,0
JR erablk
erabot
;LD A,pg7 ;<< v1.02
;CALL selmem ;>> v1.02
CALL selmemscr
LD A,(lwtop)
LD B,A
LD C,32
JR erablk
erall
CALL ZXCLS
LD A,pg6
CALL selmem
LD A,31
LD (scrls),A
XOR A
LD (lwtop),A
LD (lwx),A
LD (lwy),A
LD (uwx),A
LD (uwy),A
LD A,1
LD (cwin),A
LD A,(zver)
CP 5
JR NC,erall1
LD A,31
LD (lwy),A
erall1
SCF
RET
erablk
CALL ZAPLN
INC B
LD A,B
CP C
JR C,erablk
LD A,pg6 ;<< v1.02
CALL selmem ;>> v1.02
SCF
RET
;;;
scrls
DEFB 31 ;Number of scrolls to [MORE] prompt
lwtop
DEFB 0 ;Top line of lower window
lwx
DEFB 0 ;Lower window X,Y
lwy
DEFB 0
uwx
DEFB 0 ;Upper window X,Y
uwy
DEFB 0
cwin
DEFB 1 ;1 = lower
;;;
zchr1
DI
CP 1
JR Z,out1
CP 2
JP Z,ts_char ;Output to transcript
SCF
EI
RET
out1
LD A,L ;Output to stream 1 (screen)
CP #0D
JR NZ,zchr2
LD A,(cwin)
OR A
JR Z,ulf
JR llf
zchr2
DI
LD A,(cwin)
OR A
LD DE,(uwx)
JR Z,pchr1
LD DE,(lwx)
pchr1
CALL PRINAT
LD E,L
CALL OPCHAR
LD A,(cwin)
OR A
JR Z,stepcu
LD A,(lwx)
INC A
LD (lwx),A
CP 64
RET C
llf
XOR A
LD (lwx),A
LD A,(lwy)
INC A
LD (lwy),A
PUSH AF
LD A,(scrls)
OR A
CALL Z,MORE
DEC A
LD (scrls),A
POP AF
CP 32
RET C
LD A,31
LD (lwy),A
LD A,(lwtop)
CALL SCRL_N
SCF
EI
RET
stepcu
DI
LD A,(uwx)
INC A
LD (uwx),A
CP 64
RET C
ulf
XOR A
LD (uwx),A
LD A,(uwy)
INC A ; <<v0.03>> LWTOP check removed
;it was causing trouble in the Curses help menu
LD (uwy),A
SCF
EI
RET
;;;
;Split_window...
swnd1
LD (lwtop),A
LD B,A
CALL RES_MORE
LD A,(lwy) ;Ensure lower window y >= lwtop
CP B
JR NC,swnd1a
LD A,B
LD (lwy),A
swnd1a
LD A,(uwy)
CP B
RET C ;Ensure upper window y < lwtop
LD HL,0
LD (uwx),HL
SCF
RET
;;;
;Set_window...
swnd2
AND 1
XOR 1 ;set_window opcode uses 0 to mean lower window
LD (cwin),A
SCF
RET NZ
LD HL,0
LD (uwx),HL
SCF
RET
;;;
;Set_text_style
styl1
LD C,A
AND 1 ;Reverse video?
LD (HVF),A
LD A,C
AND 4 ;Italic?
LD (ITF),A
SCF
RET
;;;
;set_cursor_position
scur1
DI
BIT 7,C ;Negative => set cursor on/off
JR NZ,cursw
DEC B
DEC C ;0-based
LD A,C
CP 64
JR C,scur1a
LD C,63
scur1a
LD A,(cwin)
OR A
JR Z,scur2
LD A,(lwtop)
ADD A,B
CP 32
JR C,scur1b
LD A,31
scur1b
LD B,A
LD A,31 ;Reset the scroll counter
SUB B
LD (scrls),A
LD (lwx),BC
SCF
EI
RET
scur2
LD A,B ; << v0.02 Don't bother to check if
CP 32 ;this takes the cursor outside
JR C,scur2b ;the upper window.
LD B,31
scur2b
LD (uwx),BC ; >> v0.02
SCF
EI
RET
cursw
CP #FF
CALL Z,CUROFF
CALL NZ,CURON
SCF
EI
RET
;;;
snd1
LD E,7 ;Beep!
CALL OPCHAR
SCF
RET
;;;
;Select memory bank in A
selmem
;DI
PUSH AF
PUSH BC
if 1
SELMEM
else
IF atm == 0
AND GASIM
LD B,A
LD A,(BANKM)
AND USED
;Only change the bits we want to
OR B
ENDIF
LD BC,BANKIO
OUT (C),A
endif
POP BC
POP AF
;EI
RET
selmemscr
push bc
ld a,(user_scr1_high)
SETPGC000
pop bc
ret
;;;
TEMPBANKA DB pg6;#00 ;Временное хранение
;информации о банке и режимах
;;;
;Messages
badera
;DEFB "A Bad ERASE_WINDO"
DB "BEW"
DEFB "W"+#80
unimpl
;DEFB "A No ZXFDOS function "
DB "NZF "
badfun
DEFB "00"
DEFB "h"+#80
zvbad
;DEFB "A Story format "
DB "SF "
zvbuf
DEFB "000"
reqp3
;DEFB "A Spectrum +3 require'
DB "SR"
DEFB "d"+#80
signon
INCLUDE "in_ver.asm"
DEFB CR,LF,"$"
;defb CR,LF,' +3 Copyright 1998-9 by John Elliott','$'
;defb CR,LF,'TR-DOS version by CATAHUCTb|, 2001'
;defb CR,LF,LF
;defb 'Story file: $'
;sign1: defb CR,LF,'The story is loading...',CR,LF,'$'
rest_
DEFB CR,LF,"ZXZVM is restarting...",CR,LF,"$"
;;;
;Numeric data
story
DEFW tfilename;0 ;Address of story filename
zver
DEFB 0 ;Z-machine version no.
;;;
;Банки для загрузки (BANKN_TERMINATOR;#02 - нет банки для такого адреса, конец списка)
BankN
IF bigmem
IF atm
_=8;#7F^8
DUP 56
DB _
_=_+1;-1
EDUP
;#E0000
ELSE
DB #01,#03,#04,#00
DB #40,#41,#42,#43,#44,#45,#46,#47
DB #80,#81,#82,#83,#84,#85,#86,#87
DB #C0,#C1,#C2,#C3,#C4,#C5,#C6,#C7
;#70000
ENDIF
ELSE ;~bigmem
DB #01,#03,#04,#00
;#10000
ENDIF
DB BANKN_TERMINATOR;#02
;;;
;Other source files
;INCLUDE "zxp3dos2.asm" ;+3DOS specific functions
p3vrfy
SCF
RET
INCLUDE "trdos.asm" ;TR-DOS специфические функции
;INCLUDE "zxvers.asm" ;Get Spectrum version
INCLUDE "zxchime.asm" ;Sound a chime on the 8912 chip
;INCLUDE "zxerr.asm" ;Return a BASIC error
INCLUDE "zx64_1.asm" ;64-column printing
INCLUDE "in_wrhex.asm" ;Render numbers into hex or dec
IF 0;atm
ATMON
LD BC,#BD77
LD A,%10101011 ;6912,turbo
;LD A,%10101110 ;text,turbo
CALL OUT_DOS
LD A,#03 ;48K
LD BC,#3FF7
OUT (C),A
RET
ATMOFF
LD A,#83 ;48K/DOS
LD BC,#3FF7
OUT (C),A
LD BC,#FF77
LD A,%10101011 ;6912,turbo
OUT (C),A
RET
OUT_DOS
LD HL,#2A53
PUSH HL
JP #3D2F
ENDIF
;ENT
ds 0x7000-$
main
incbin "vm.bin"
end
;GO
;RET
savebin "zxzvm.com",begin,end-begin
LABELSLIST "../../us/user.l",1