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