ZXMMC+
IF1-ROM
Modification Details
As stated on the
software page, the rom switch provided by IF1 hardware has been
implemented in software by applying some changes to the original
IF1 rom and zx-spectrum internal rom.
The patched 48K-spectrum rom should be programmed on rom bank 4;
The patched IF1 rom should be programmed on rom bank 5.
These changes will replicate the behaviour of the original
hardware, which performs bank switch on the following address
match:
OPCODE FETCH
+0008: 48K --> IF1 (IF1 ROM
should be paged in)
OPCODE FETCH +0700: IF1 -->
48K (MAIN ROM should be paged in)
OPCODE FETCH +1708: 48K -->
IF1 (IF1 ROM should be paged in)
The 48K rom has been manually edited.
The IF1 ROM (Version 2), which requires more coding, has been
fully disassembled; the file "IF1-2ori.asm" (original), when
assembled, produces an exact copy of the IF1-2.ROM binary file.
All needed changes in the IF1 ROM are made in the file
IF1-2new.asm, which will make a ready-to-use binary file
to be programmed into BANK 5. The second half of this 16K rom (the
IF1 ROM is just 8K) is used as a placeholder
for additional code, needed for the ROM switching tasks.
The complete source code, tools and howto for all the patches can
be found here.
A working example showing a LLIST command redirected to RS-232 by
IF1 functionality and then displayed into an Hyperterminal window,
using IF1 syntax, is available here
Description of all the
changes:
IF1ROM
PAGE-IN on +0008 opcode fetch:
How it works on original hardware:
The IF1 ULA pages-in the IF1 ROM when an opcode fetch is executed
at address +0008, so code is executed from there.
How it works on ZXMMC+:
48k ROM was modified at address +0008 so that the bank 5 (IF1 ROM)
is paged-in (this takes 5 bytes)
IF1 ROM was modified at address +0008 so that program execution
keeps going on BANK CROSSING.
A few bytes are used above first 8K (spare area)
Original ZX-Spectrum ROM:
0008 2a5d5c ld
hl,(5c5dh) ; this opcode fetch triggers the IF1 ROM
PAGE-IN on original hardware
000b 225f5c ld
(5c5fh),hl ; from here on, code is never
executed when a IF1 is plugged-in
000e 1843
jr 0053h
Original IF1-V2 ROM
0008 2a5d5c ld
hl,(5c5dh) ; interestingly, this is the same
instruction as in the IF1 rom. perhaps the 16-bit operand's
000b e1
pop hl
; memory read would
otherwise be page-crossed... or the opcode fetch could become
unreliable...?
000c e5
push hl
000d c39a00 jp
009ah
Modified ZX-Spectrum ROM:
0008 f5
push af
0009 3e65
ld a,IF1ROMBANK ; IF1
SHADOW ROM Bank: lsb 5 = BANK 5
000b d37f
out (FASTPAGE),a ;
bank switch: next opcode fetch will take place from the IF1 ROM in
BANK 5
000d 00
nop
;
unused location: this is never fetched.
Modified IF1-V2 ROM
0008
00
nop
;
these 5 bytes are never fetched: MAIN ROM is still active
0009 00
nop
;
NOP was chosen in case the IF1 ROM's +0008 function is called from
within
000a 00
nop
;
this rom itself: it would work
000b 00 nop
000c 00 nop
000d c30020 jp
2000h
; jumps forward
to the spare, second half of this 16K rom bank
2000
f1
pop af
;
then execute the same code found at address +0008 of the IF1 ROM
2002
e5
push hl
2003 c39a00 jp
009ah
MAINROM
PAGE-IN on +0700 opcode fetch:
How it works on original hardware:
48K (main) ROM is paged-in when an opcode fetch is executed at
address +0700. The +0700 byte is fetched from IF1 ROM.
This byte is a $C9 (RET), so the system will switch to the main
rom AND jump to the address saved on the STACK at the same time.
How it works on ZXMMC+:
A single byte $C9 (RET) instruction at address +0700 was changed
to $C3 (absolute jump).
The next two bytes in IF1 ROM (which should NOT be changed as they
are part of another subroutine) will make up a jump to $20D7,
which luckily is in the second half (SPARE) ROM SPACE. Then, after
a further jump, a place is found so that right after the execution
of the OUT (which pages-in the 48K ROM) the first two bytes in the
48K rom are POP AF, RET. This is perfect as we pushed AF on stack
just before the OUT instruction which actually switched the bank.
Original IF1-V2 ROM
0700 c9
ret
; MAIN-ROM paging AND
jump to address saved on stack at same time (1 byte subroutine)
0701 d7
rst 10h
; other code (belonging to the 'EVALUATE
PARAMETERS' SUBROUTINE)
0702 2000 jr
nz,0704h
Modified IF1-V2 ROM
0700 c3d720 jp
20d7h ; NOTE: only A SINGLE BYTE at
+0700 needs to be changed from '$C9' to '$C3'
20d7 c3dc2d jp
2ddch
; further
jump to covenient place, to match a POP AF, RET sequence in the
MAIN ROM
2ddc
f5
push af
;
AF is saved
2ddd 3e64
ld a,MAINROMBANK ; lsb 4
= BANK 4
2ddf d37f
out (FASTPAGE),a
; BANK 4 is paged-in NOW: next opcode
fetch will take place from 48K ROM
... 48K ROM content on the next two bytes (no need for any
change):
2de1
f1
pop af
; AF is restored
2de2
c9
ret
; JP to address saved
on stack, as happens with the RET instruction at +0700 on original
hardware
IF1ROM
PAGE-IN on +1708 opcode fetch:
How it works on original hardware:
The IF1 ULA pages-in the IF1 ROM when an opcode fetch is executed
at address +1708, so code is executed from there.
This is in the middle of the CLOSE-2 subroutine, which begins at
address +1701 in the 48K ROM.
How it works on ZXMMC+:
The first 5 bytes of the CLOSE-2 routine at address +1701 in the
48K (MAIN) ROM are replaced by code which pages-in the IF1 ROM.
In the IF1 ROM, a single byte at address +1706 (spare area) is
changed from $FF to $C3 (absolute jump). Note that +1706 is
the first opcode fetch from IF1 ROM, after bank switch takes
place. The following two bytes (who are NOT modified in the IF1
ROM)
will lead to a JP to $23FF, which, again, is within the second
half of the rom bank (spare).
Here the program can perform the same way the original IF1/48K ROM
do, then jump back to +1708 (which holds the unmodified IF1 code).
Note that the +1708 location ($23) is left untouched and is used
twice: the first time as the MSB address for the absolute JUMP to
$23FF
and later as a INC HL instruction (as happens in the original IF1
ROM).
Original ZX-Spectrum ROM:
1701 e5
push hl
; CLOSE-2 subroutine
1702 2a4f5c ld
hl,(5c4fh)
1705 09
add hl,bc
1706 23 inc
hl
1707 23
inc hl
1708 23 inc
hl
;
IF1 ROM paged-in NOW
1709 4e
ld c,(hl)
170a eb ex
de,hl
170b 211617 ld hl,17
Original IF1-V2 ROM
1701 ff
; unused locations
1702 ff
1703 ff
1704 ff
1705 ff
1706 ff
1707 ff
1708 23
inc hl
;
again, same instruction as in the MAIN ROM.
1709 f7
rst 30h
170a cb3f srl a
170c d603 sub 03h
Modified ZX-Spectrum ROM:
1701 f5
push af
1702 3e65 ld
a,IF1ROMBANK ;
this should point to the IF1 SHADOW ROM Bank: lsb 5 = BANK 5
1704 d37f out
(FASTPAGE),a ; ZXMMC+
PAGE REGISTER: next opcode fetch will take place on the OTHER ROM
;
no changes on next bytes
Modified IF1-V2 ROM
1706 c3ff23 jp
23ffh
;
jump forward. NOTE: only byte at +1706 needs to be changed from
$FF to $C3
23ff
f1
pop af
2400 e5
push hl
2401 2a4f5c ld
hl,(5c4fh)
2404 09
add hl,bc
2405 23 inc
hl
2406 23 inc
hl
2407 c30817 jp 1708h
Home
Technical Description Hardware
Details Software QuickStart Schematic PCB
Contact the Author