Adventurer #06: Обмен опытом: Руководство по созданию дисковых версий для ZX Spectrum

                (C) RAY
(C) Music PHANTOM LORD/ACCEPT CORP.
╔───────────────────────────────────────╗
│ ──── HOW TO MAKE A DISK VERSION ──── │
╚───────────────────────────────────────╝

You are undoubtedly familiar with the situation: when loading a certain program (whether a game or a system utility), you receive the message "Disked by ...", and then, when trying to load something, you see a blinking border. What words will be said about that very "disketizer", I hope you can guess. In general, I believe this: it is only acceptable to write in the loader that the program has been disked when a COMPLETE DISK version has been made. If only a disk loader is slapped on, it is better to write nothing or note that the program is not fully disked. However, the latter option may not satisfy many, so I will share some information with you on how to create a full disk version of the program.

So, you have a certain code block in which you need to change the loading/unloading of some data from tape to disk. First, let's look at the loading address of the block. Usually, the stack is set one unit lower than this address. (WARNING: make sure that after launching, the program does not change its position in memory, in particular, does not move below this address!) Usually, the minimum address is 24500. If the block has such an address or higher - everything is okay, there is a 90% chance that there will be no problems with adapting it for disk. If not - the situation is a bit more complicated and we will consider it later (this article discusses diskization using standard TR-DOS methods).

Before searching for entry points in the tape loading/writing procedures, it is useful to scan the entire memory for free space not occupied by the program. As practice has shown, there is always a byte of 150..200 free space in any program (possibly in chunks of 45 bytes). And this will be more than enough for our purposes. If not - you can use the space occupied by the BASIC loader.

Now let's start looking for entry points. There can also be two options here:
1) the program uses its own loading/writing procedures;
2) the program uses procedures from ROM.

In the first case, finding entry points is harder, but then you won't need to find free space in the program, as the new subroutines will fit in the place of the old ones. In the second case, you can try to find calls to ROM.

I recommend first finding the entry point in SAVE, as it is easier to determine the parameters of the block being unloaded (starting address /usually in register IX/ and length /register DE/). Here are some entry points for tape subroutines in ROM, extracted from various programs:

mnemonic bytes to search
─────────────────────────────────────────
SAVE: CALL 1218 CD C2 04
CALL 1222 CD C6 04

LOAD: CALL 1366 CD 56 05
CALL 2050 CD 02 08
CALL 1378 CD 62 05
CALL 1889 CD 61 07
─────────────────────────────────────────
Additionally, there are exotic methods:
CALL #0605
where SAVE or LOAD is determined
by cell 23688 = 0 - SAVE
1 - LOAD

An even more interesting method:
SAVE: CALL 2416,
where
IX - the first 17 bytes - header,
then data;
length is set as follows:

LD DE, length
LD (IX+11),D
LD (IX+12),E.

If you suspect that the program uses its own tape handling procedures, you can do the following. Since such procedures are usually based on ROM ones, look for the following sequence:

code mnemonic
──────────────────
08 EX AF,AF'
13 INC DE
DD 2B DEC IX
F3 DI

This is a piece from a procedure located in ROM at address 1222 (#04C6). If you find something similar, it means this is the beginning (almost) of the tape writing subroutine. All that remains is to find where it is called and determine the parameters of the block being unloaded.

If none of the above helps - try searching for messages that the program outputs when working with tape. Usually, these messages are located near the corresponding procedures.

So, we've found everything. Replace the call addresses of the found subroutines with those given below. However, there is one more point: there may be three unloading options (for loading - similarly):

1) to the same file;
2) to the same location on the disk or "to itself";
3) to different files (most preferred).

In the first case, the file name is fixed. In the second, it is not needed at all. In the third, it needs to be somehow entered (this is usually found in adventure games).

Let's consider these cases...

1. To one File:
───────────────
SAVE
CALL SET_NAME ; preparing sys.
; variables
LD C,10 ; searching for file
CALL 15635
LD A,C
BIT 7,C
JR NZ,SAV_BL ; it does not exist

LD DE,(23878) ; found it, rewrite
LD BC,#nn06
LD HL,address
CALL 15635
RET

SAV_BL ; creating new
LD HL,address
LD DE,size
LD C,11
CALL 15635
RET

where address - the starting address of the
block being unloaded;
size - its size in bytes;
nn = its size in sectors.

LOAD
CALL SET_NAME ; preparing sys.
; variables
LD C,10 ; searching for file
CALL 15635
LD A,C
BIT 7,C
JR Z,LD_1
; Message "file not found" or...
RET

LD_1 ; loading...
LD A,C
LD C,8
CALL 15635
XOR A
LD (23801),A
LD (23824),A
LD C,14
CALL 15635
RET
; Subroutine for setting sys. variables
SET_NAME
LD HL,NAME ; transferring
LD DE,23773 ; file name
LD BC,8
LDIR
LD A,"C" ; file type can be
LD (23781),A ; any, except
; "#","D","B"
LD A,9 ; searching for file
LD (23814),A ; by 9 characters
RET

NAME DEFM "filename"

2. To the same place ("to itself"):
───────────────────────────────────
SAVE
LD HL,address
LD DE,(T_S)
LD BC,#nn06
CALL 15635
RET
LOAD
LD HL,address
LD DE,(T_S)
LD BC,#nn05
CALL 15635
RET
T_S DEFW #SSTT ; track and sector,
; where to write/read

3. To different files:
──────────────────
The case is similar to 1, only the procedure
SET_NAME needs to be replaced with INP_NAME.

* If you are diskizing an adventure, it is better to find the input string procedure in the program and use it for entering the file name. How this can be used is shown below. Otherwise, you will have to write it yourself.

NAME EQU ; address where the string is read
INPUT EQU ; address of the string reading
; procedure
FROM EQU ; parameter "address"
LEN EQU ; parameter "length" (BYTES)

INP_NAME
LD HL,NAME ; clearing the name
LD DE,NAME+1 ; of the file
LD BC,7
LD (HL),#20
LDIR

CALL INPUT ; see *

LD A,"C" ; file type can be
LD (23781),A ; any, except
; "#","D","B"

LD A,9 ; searching for file
LD (23814),A ; by 9 characters

LD HL,NAME
LD B,8
CHECK LD A,(HL)
CP NN ; end marker
JR NZ,NEXTS ; strings code NN
LD A,#20 ; replace with
LD (HL),A ; space
NEXTS INC HL
DJNZ CHECK
LD HL,NAME
LD DE,23773
LD BC,8
LDIR
RET


And finally, I want to share a little subroutine that allows you to change the disk drive:

call: LD D,n ; n - drive number
CALL CNG_D ; 0-A, 1-B, 2-C
....

CNG_D DI
LD A,#C9 ; disable error
LD (#5CC2),A ; handling
; (see ADV #5)

LD (IY+0),#FF ; reset
XOR A ; all codes
LD (23824),A ; errors

LD A,D ; set
LD (23833),A ; system parameters
LD (23798),A ; TRDOS

LD C,1 ; selection
CALL #3D13 ; disk drive

LD C,#18 ; setup for
CALL #3D13 ; disk
EI
RET

P.S. If you do not set up the disk, then when changing the disk drive, it may happen that it will only read the zero track.

P.P.S. The procedures presented in ADV #5 and this issue are not ideal, although they are quite functional. If someone knows how to do better (or even better - a driver with direct programming of the disk controller and error handling, for example, like this: standard call, and upon completion of work in register A the error code), then we will gladly publish their achievements. Go for it, keyboard virtuosos!

I will allow myself to conclude here. If something is unclear - write.

─────────────────────────
We continue the series of articles dedicated to disk loaders. The floor is to our correspondent.

(C) Nicolas Viper

"The lazier a person is, the
more any of his actions
resembles a feat."

Folk wisdom

The delay is quite long, but who finds it easy these days? Get your brains out of the jars with solutions, wipe them off if they are dusty, and delve in.

First of all, it should be noted that the statement that DOS cannot help us in the validation of reading (hereinafter: VVR) turned out to be INCORRECT. Only, in turn, we must help it.

Take a look at the listing:

ORG 40000
DI ;Installation:
LD HL,#FD00 ;-Pre
LD A,H ; par
LD DE,#FD01 ; am
LD BC,256 ; eters
LD (HL),#FE
LDIR
LD I,A
IM 2
CALL MUSRUN ;-Music
EI
LD DE,#0100 ;-From where,
LD HL,16384 ; to where and
LD B,27 ; how much we will
CALL LOADER ; load
JP MUSRUN ; Music off + RET

*************** LOADING *****************

LOADER
LD IX,#2F65 ;Unwinding
CALL DOS
L1
PUSH DE
PUSH BC
LD A,D
OR A
RRA
LD C,A
LD A,#3C
JR NC,L2
LD A,#2C
L2
LD IX,#2F4D ;Put the skull on
CALL DOS ;the road
POP BC
POP DE

PUSH HL
PUSH DE
PUSH BC

CALL LOA_COM
POP BC
POP DE
POP HL
;Recount:
INC H ;- addresses
LD A,E ;- sec
INC A ; on
AND 15 ; the
LD E,A
JR NZ,L5 ;- roads
INC D
L5
DJNZ L1 ;New sector

DI ;Exit
IM 1
EI
RET

This part has not changed since the first coming. And now the most important:

LOA_COM
LD C,#5F ;Recount the number
LD A,E ;of the sector to send
INC A ;into the register
LD IX,#2A53 ;of the disk controller
CALL GODOS
TRY1
PUSH HL ;On the stack
PUSH DE
TRYMET
XOR A ;No errors
LD (ERRFLG+1),A ;(for now :)
LD B,A ;B=0
LD C,#1F ;Command
LD A,#80 ;"read
LD IX,#2A53 ; sector"
CALL DOS
LD C,#7F ;Reading sector
LD IX,#3FE5
CALL GODOS
POP DE ;Took from the stack
POP HL

ERRFLG
LD A,0 ;Check for
OR A ;errors during
JR NZ,TRY1 ;reading. (more
LD D,1 ;detailed description
LD IX,#2F2F ;below)
JP GODOS

DOS
HALT
GODOS
PUSH IX
JP #3D2F
IMCOM ;Caught an interrupt
LD (STACK),SP ;
PUSH IX
PUSH HL ;Here too, in
PUSH DE ;two words
PUSH AF ;you can't describe
PUSH BC ;Look for details
CALL MUSIC ;below.
LD HL,(STACK)
LD E,(HL)
INC HL

LD D,(HL)
LD A,D
CP #40
JR NC,RETOS
CP #3F
JR NZ,PA_CNT
POP BC
PUSH BC
LD A,B
LD (ERRFLG+1),A
PA_CNT
LD HL,0-#2F3A
OR A
ADC HL,DE
JR Z,RTBR
LD A,#C3
POPALL
LD (CHANGE),A
POP BC
POP AF
POP DE
POP HL
POP IX
EI

CHANGE
JP #3D2F
RETOS
LD A,#C9
JR POPALL

RTBR
LD SP,(STACK)
POP AF
EI
JP TRYMET

STACK DW 0

ORG #C000
INSERT "MUSIC"

ORG #FEFE
JP IMCOM

MUSRUN EQU #C000
MUSIC EQU #C006

At address #2F2F in TR-DOS:

#2F2F IN A,(#1F)
AND #7F
RET Z
DEC D
PUSH HL
PUSH DE
JR NZ,#2EXX ;It doesn't matter where
HALT ;) Catching!

Briefly:

Regarding IMCOM: the task of this procedure is to check when an interrupt has occurred. Possible options:
- in RAM. Then we don't care - we play music and return.
- in ROM (we assume this is DOS!!! In theory, we don't fall into SOS). Then there are also options:
- Caught from address #2F3A - this means that we caught HALT (see above), which, in turn, indicates that

during reading, one of the "standard" errors occurred - data loss, checksum mismatch, etc.
- ...from address #3FXX (XX - any value) - again, in theory, we can only intercept the sector reading procedure there. This means that, unfortunately, we are in an undefined state - we need to finish the procedure, but due to the delay in playing the melody, etc., we missed the time and reading will have to be repeated.

In case of an error, we place a non-zero value at address (ERRFLG + 1) - this indicates that it is necessary to reread the sector (see from the label ERRFLG).

Everything else is not that complicated and has been described earlier. Write if something is wrong, to the editor or email me:

nicky@univ.uniyar.ac.ru

Although, judging by previous publications, you, dear readers, still did not pay any attention to this procedure - there were plenty of glitches in it, and no one wrote: "...because of your #@$&$-ing program, I ruined my favorite disk!"

(C) Kotov A.V. (CAV Inc.)

Contents of the publication: Adventurer #06

  • Presentation
    This is an introduction novel for the game Return to Home 4, featuring space battles and a narrative about pilot Raifus navigating challenges in a military context.
  • Presentation
    The article presents K.KAV software's new game 'DEATH WORLDS: TORISTAG INVADERS RETURN TO HOME 5', a real-time strategy continuation of 'RTHЧ'. Players will battle against competitors on resource-rich planets while managing technology and military forces. The game's projected release is between late spring and summer of 1997.
  • System Software Updates for ZX Spectrum - Котов А.В.
    The article reviews various software updates and utilities for ZX Spectrum, highlighting their features, usability, and performance. It provides insight into programming tools, disk management, and database applications. The tone blends critique and personal experience to inform readers about the latest developments in Spectrum software.
  • Overview of ZX Spectrum Software
    The article provides a comprehensive overview of new software for ZX Spectrum, highlighting various games, their features, and recommendations for players.
  • Interface
    Discussion of the ZX Spectrum's interface issues and user frustrations with compatibility and modern enhancements. The author critiques the push for users to modify their machines for non-standard features and expresses dissatisfaction with current trends. Reflection on the future of the ZX Spectrum and the need for a more vibrant community involvement.
  • Interface
    The article discusses feedback from readers regarding games and programming tools for ZX Spectrum. It includes cheat codes for a game, opinions on assemblers, and insights into user preferences for computing. Various reader inquiries about games and software are also addressed.
  • Interface
    The article discusses issues surrounding the OVER FILE GROUP, a game developer known for mail-order sales, and the impact on user trust in software distribution. It also raises the question of whether to transition the magazine to 128K ONLY, seeking reader feedback. The piece reflects on the importance of user support for maintaining a trusted gaming community.
  • Interface
    The article discusses recent news in the ZX Spectrum community, including game development updates, personal news about developers, and local happenings in the Rybinsk and Yaroslavl areas.
  • Presentation
    The article presents new software releases by SURDAKAR GROUP, including a demo of ROAD FIGHTER and updates on FONT EDITOR and RAY DISK MONITOR.
  • Promotion of Adventure Games
    The article provides a detailed analysis of the adventure games 'APOLLO' and 'ЧУЖОЙ', evaluating their gameplay, challenges, and shortcomings in design.
  • Ottyag
    Discussion of computer slang and its impact on modern language, highlighting humorous interactions among users.
  • Оттяг
    The article presents a humorous collection of absurd lists, including reasons for dinosaur extinction, alternative names for Robinson Crusoe's Friday, and more.
  • Ottyag
    The article presents a test for aspiring demo makers, assessing their skills and commitment to demo creation on the ZX Spectrum. It evaluates their approaches to music, graphics, effects, and their overall engagement with the demo scene. Results determine their standing from novice to expert in the demoscene community.
  • What Not to Say or Do When Drunk
    The article provides humorous advice on what to avoid saying or doing when drunk, based on personal anecdotes. It emphasizes the consequences of poor decisions and offers cautionary tips. The content is lighthearted and reflects on typical drunken behaviors and their repercussions.
  • Friendship Quiz
    The article presents a humorous quiz about friendship, evaluating how friends would react in various social scenarios, culminating in a scoring system to assess the depth of one’s friendships.
  • Ottag
    Статья представляет собой сборник китайских пословиц с юмористическим подтекстом, отражающих различные аспекты жизни и отношений. Она сочетает в себе элементы сатиры и легкого фольклора, используя ироничные наблюдения о человеческом поведении. Текст включает в себя аллюзии на сексуальность, настольные игры и религиозные вопросы.
  • Оттяг
    Статья представляет собой пародийное евангелие, где события жизни Иисуса Христа изображаются в неформальном и юмористическом ключе.
  • Experience Sharing
    The article provides a detailed guide on creating a complete disk version of a program for ZX Spectrum, including code examples and practical advice.
  • Experience Exchange
    The article provides a comparative analysis of the PC and Amiga platforms, highlighting their respective advantages and disadvantages based on personal experience.
  • Experience Exchange
    The article discusses the existence and behavior of computer viruses on the ZX Spectrum, particularly the BASIC file infecting virus known as 'Drunken Djinn', first seen in the game Last Battle.
  • Code Protection Methods
    The article discusses various methods of software code protection, detailing techniques like inversion masking, obfuscation, P-code, cryptographic algorithms, and the use of ISR. Each method is evaluated for effectiveness and application, particularly within the ZX Spectrum environment. The author invites further information and collaboration on information security methods.
  • Anniversary
    The article celebrates the sixth issue of 'ADVENTURER,' marking one year since the founding of the AURYN group. It reflects on the past year for the Speccy community, including the emergence of new programs and the first demomakers' gathering in the CIS. The author expresses hope for the future of Speccy and encourages readers to support and promote the platform.
  • Anniversary
    Article celebrates the 15th anniversary of the Spectrum, reflecting on its enduring legacy and recent developments in hardware and software.
  • Novella
    The article narrates a novella centered on a covert mission involving a programmer named Gerald O'Brien, who is hired by a drug lord called Swede to infiltrate a rival's computer network, leading to a thrilling sequence of espionage and violence.
  • Contest
    The article discusses a contest related to ZX Spectrum, showcasing submissions and participants' creativity.
  • Advertisement
    The article is an advertisement section in Adventurer #06, inviting hackers, programmers, artists, and musicians to contribute to the ZX Spectrum community. It outlines collaboration opportunities, offers specific requirements for software submissions, and includes contact information for advertising and game distribution. Additionally, it promotes a range of ZX Spectrum software and services available across various cities.