; PROGRAM: UTILPAT -- Utility Patch ; AUTHOR: Jay Sage ; DATE: November 30, 1988 ; This patch *may* allow BIOS-specific utilities to ; work under NZ-COM. ; The address below must be set to the first free byte ; after the utility's code. patchaddr equ 0000h ; The address below must be set to the address at which ; execution will continue after the patch code is ; executed. startaddr equ 0000h ; The following macro should be filled in with any opcodes ; that were at address 100H and following and had to be ; replaced by the jump to the patch code. If the utility ; began with a JP STARTADDR instruction, then leave this ; macro blank replaced macro ; put instructions here endm ; The macro below is used to enter the list of addresses ; at which LD HL,(0001) instructions appear that must be ; patched. Replace the symbol ADDR1 by the first such ; address and insert additional similar lines for any other ; addresses to be patched. ; addrlist macro dw addr1 ; Repeat for each address endm ldhl equ 21h ; Load-hl-direct opcode offset equ 5ah - 3 ; Offset from BIOS warm boot entry ; ..to the NZ-COM signature ; The following code will be patched in at address 100h to ; vector control to the patch code. org 100h jp patchaddr ; The actual patch code begins here. org patchaddr ; If NZ-COM is running, HL will now contain the ENV address. ; We will need this later, so we save it. ld (envaddr),hl ; Now we must find out if NZ-COM is running. This is done ; by looking for its signature "NZ-COM" at a specific offset ; from the virtual BIOS warm boot entry point. If this ; signature is not found, the patch can be skipped. ld hl,(0001) ; Get possible virtual ; ..BIOS address ld de,offset ; Offset to signature add hl,de ld de,signature ; Point to what the ; ..signature should be ld b,sigsize ; Length of signature sigloop: ld a,(de) cp (hl) ; Check character inc de ; Advance pointers inc hl jr nz,exitpatch ; Jump if not NZ-COM system djnz sigloop ; Loop through signature ; We get here if NZ-COM is running. Now we must make the ; necessary patches to the utility. First we must determine ; the address of the warm boot entry to the real BIOS. ; NZ-COM keeps the page address at offset 2 into the ENV. envaddr equ $ + 1 ld hl,$-$ ; Filled in by code above inc hl ; Advance to CBIOS page inc hl ld a,(hl) ; Get page of CBIOS ld (cbiospage),a ; Put it into code below ; Now we patch in the changes to the utility code. ld de,table ; Point to address table ld b,tablesize ; Addresses in table patchloop: ld a,(de) ; Low byte of address inc de ; Advance pointer ld l,a ; Put in low byte of HL ld a,(de) ; High byte of address inc de ; Advance pointer ld h,a ; Put in high byte of HL ld (hl),ldhl ; Patch in direct-load opcode inc hl ld (hl),03H ; Low warm boot address inc hl cbiospage equ $ + 1 ld (hl),0 ; Filled in by code above djnz patchloop ; Loop through address list exitpatch: ; Here we have to exit from the patch and resume execution ; of the original utility. First we execute instructions, if ; any, replaced by the patch intercept code. replaced ; Macro ; Then we jump to the utility code. jp startaddr ; The following is what the NZ-COM signature should look like. signature: db 'NZ-COM' sigsize equ $ - signature ; We put the table of addresses to patch here. table: addrlist ; Macro with address list tablesize equ ( $ - table ) / 2 end