Vision2 Fix Patch

32KB Eprom Constraint

Vision2 was sold as a 32KB EPROM. As explained in the Developer Notes, cards smaller than 1MB are addressable at repeating intervals within that Slot's address space. This allows OZ to easily scan the top bank of a card, without needing to know its size.

By default, Vision2 cannot run from other card sizes because its DORs presume it will occupy the last two banks, but its bank binding code presumes it will occupy the first two banks. Both conditions will only hold true for a 32KB card.

Crash on New OZ Versions

Vision2 will crash when launched on OZ versions later than 4.0, which makes it a pretty dangerous thing to have on a card. Accidentally launching it could lose work in other applications.

Earlier Patch

RomCombiner includes patches to lift the restrictive card limitations for both Vision2 (full version) and for Vision/L (reduced feature version).

Consider the Z88 bank layout:

Banks &00 - &3F are internal Slot 0 (lower half ROM, upper half RAM) Banks &40 - &7F are wired to Slot 1 (usually RAM for Expanded mode in old OZ) Banks &80 - &BF are wired to Slot 2 Banks &C0 - &FF are wired to Slot 3 (usually EPROM, only Slot with 12V)

The patch amends the following byte values in the application's own bank binding code:

Original

Patched

Impact

Original

Patched

Impact

C0

FE

Slot 3, changes 1st bank to penultimate bank

C1

FF

Slot 3, changes 2nd bank to last bank

80

BE

Slot 2, changes 1st bank to penultimate bank

81

BF

Slot 2, changes 2nd bank to last bank

Vision is limited to running in Slots 2 or 3 only, which is understandable considering early OZ versions needed a RAM card in Slot 1 specifically, for an Expanded machine. The patch bundled with RomCombiner does not ease that limitation, nor does it allow Vision to run from any other banks than 63 and 62 - which does rather get in the way of making a compilation ROM on a flashcard.

A Better Solution

Reading through this section of Developer Notes, this part jumped out at me:

If your applications requires access to other banks in your card then you can use the bank switching call, OS_Mpb, to bind them in. However, your card could be placed in any of the three slots so you need to determine where your card is. This can simply be done by using OS_Mgb while running ROM'ed code and then using bank offsets relative to this value.

I could simply re-write this part of the code by disassembling it, and convert the bank binding to be relative to the running bank. OS_Mgb needs the segment this is bound to, information which is stated in the Application DOR.

My patch makes the following improvements:

Original Code, Annotated Disassembly

; Address $C039, or offset $0039 in VIS206.62 .bind_banks_slot3 XOR A ; AF A = 0 LD BC, $CA01 ; 01 01 CA OZ OS_Mpb ; E7 5D Bind 1st bank in slot 3 (B), to segment 1 (C), assumes 32K Eprom XOR A ; AF A = 0 LD BC, $CB02 ; 01 02 CB OZ OS_Mpb ; E7 5D Bind 2nd bank in slot 3 (B), to segment 2 (C), assumes 32K Eprom .rom_check_slot3 LD A, ($400B) ; 3A 0B 40 Read byte $0B in VIS206.62 from segment 1 (which starts at $4000) CP '_' ; FE 5F Compare with '_' JR NZ, bind_banks_slot2 ; 20 0A If no match, relative jump to try slot 2 LD A, ($4012) ; 3A 12 40 Read byte $12 in VIS206.62 from segment 1 CP ' ' ; FE 20 Compare with ' ' JR NZ, bind_banks_slot2 ; 20 03 If no match, relative jump to try slot 2 JP continue ; C3 73 40 Checks passed, continue execution .bind_banks_slot2 XOR A ; AF A = 0 LD BC, $8A01 ; 01 01 8A OZ OS_Mpb ; E7 5D Bind 1st bank in slot 2 (B), to segment 1 (C), assumes 32K Eprom XOR A ; AF A = 0 LD BC, $8B02 ; 01 02 8B OZ OS_Mpb ; E7 5D Bind 2nd bank in slot 2 (B), to segment 2 (C), assumes 32K Eprom .rom_check_slot2 LD A, ($400B) ; 3A 0B 40 Read byte $0B in VIS206.62 from segment 1 (which starts at $4000) CP '_' ; FE 5F Compare with '_' JR NZ, bind_banks_slot3 ; 20 D0 If no match, relative jump to try slot 3 again (endless loop) LD A, ($4012) ; 3A 12 40 Read byte $12 in VIS206.62 from segment 1 CP ' ' ; FE 20 Compare with ' ' JR NZ, bind_banks_slot3 ; 20 C9 If no match, relative jump to try slot 3 again (endless loop) JP continue ; C3 73 40 Checks passed, continue execution .continue CALL $49FC ; CD FC 49

Replacement Code

; Address $C039, or offset $0039 in VIS206.62 .bind_banks_relative LD C, $03 ; OE 03 Application DOR states we are running in segment 3 OZ OS_Mgb ; E7 5A Get bank bound to segment 3, stored in B LD A, B ; 78 Store it in A for later LD C, $01 ; 0E 01 OZ OS_Mpb ; E7 5D Re-bind this bank to segment 1 (from original code) LD C, $02 ; 0E 02 LD B, A ; 47 Retrieve stored bank INC B ; 04 Increment it so as to target the 2nd application bank VIS206.63 OZ OS_Mpb ; E7 5D Bind the 2nd bank to segment 2 .rom_check LD A, ($400B) ; 3A 0B 40 Read byte $0B in VIS206.62 from segment 1 (which starts at $4000) CP '_' ; FE 5F Compare with '_' JR NZ, badbank ; 20 07 If no match, relative jump to bad bank error LD A, ($4012) ; 3A 12 40 Read byte $12 in VIS206.62 from segment 1 CP ' ' ; FE 20 Compare with ' ' JR Z, check_os_ver ; 28 04 If match, relative jump to check OS version .bad_bank LD A, RC_Bank ; 3E 34 Set error code for 'Bad Bank' fatal error OZ OS_Bye ; E7 21 Exit application .check_os_ver LD A, FA_PTR ; 3E 01 LD DE, $0000 ; 11 00 00 LD IX, $FFFF ; DD 21 FF FF OZ OS_Frm ; E7 48 Return OZ revision number in (C) LD A, C ; 79 CP $05 ; FE 05 OZ 2.x - 3.x will return $03, OZ 4.0 returns $04 JP C, original_continue ; DA 73 40 Continue in segment 1 if OZ =< 4.0 LD A, RC_Quit ; 3E 67 Set error code for 'Request application to quit' fatal error OZ OS_Bye ; E7 21 Exit application to prevent crash .spare_bytes NOP ; 00 NOP ; 00 NOP ; 00 NOP ; 00 .original_continue CALL $49FC ; CD FC 49

Download Patch

This patch is published in the IPS format, popular for ROM patches.

web analytics