        page    ,132
;
;                   IBM Confidential
;                   Copyright (C) IBM Corporation 1991-1992
;                   All Rights Reserved.
;
        title   RomDrive physical ROM access routine

;       This is an extended-memory capable version which uses the
;         ROM BIOS's Int15(ah=87h) block move function.
;       Note:  This module assumes low 16Meg mapping (286 space only)

;
;----------------------------------------------------------------------------
;
; M071 : Made ROMDRIVEBASE_LO equated to 0000 instead of 00 for more
;        readability
;
;----------------------------------------------------------------------------
;
;ROMCODE        SEGMENT byte public
;       assume  cs:ROMCODE
        .xlist
        include biosseg.inc
        include msgroup.inc
        .list
        assume  cs:bios_data

IFNDEF  FAKEROM

ROMDRIVEBASE_LO equ     0000h                   ; M071
ROMDRIVEBASE_HI equ     0ech

ELSE

ROMDRIVEBASE_LO equ     0
ROMDRIVEBASE_HI equ     0

ENDIF ; FAKEROM

        public  xfer_from_rom

;       Entry:
;              dx:bx  - 32 bit ROM offset of transfer block
;              es:di  - real mode address where it should go
;              cx     - count in bytes, guaranteed to have at least 2 zero lsbs
;                        note:  transfer length == 00 means 64K
;

;       EXIT:
;           If error detected
;               Carry Set
;                  al == error code 8 (sector not found)

gdts    dw      0,0,0,0         ; gdt 0 == dummy
        dw      0,0,0,0         ; gdt 1 == GDT seg (Int15 fills in)

        dw      0ffffh          ; gdt 2 limit = 65535
src_low dw      0               ; gdt 2 low 16 bits
src_hi  db      0
        db      93h,0,0         ; gdt 2 access rights & reserved

        dw      0ffffh          ; gdt 3 limit = 65535
dst_low dw      0               ; gdt 3 low 16 bits
dst_hi  db      0
        db      93h,0,0         ; gdt 3 access rights & reserved

        dw      0,0,0,0         ; gdt 4 == ROM BIOS CODE (Int15 fills in)
        dw      0,0,0,0         ; gdt 5 == stack (Int15 fills in)

rombase_low     dw      ROMDRIVEBASE_LO ; point to full ROM address
rombase_high    dw      ROMDRIVEBASE_HI ; as linear address

xfer_from_rom:
        add     bx,rombase_low  ; add in ROM base linear address
        adc     dx,rombase_high

IFDEF   FAKEROM

;       ****  For debug purposes, we'll also add in the offset to
;               the phony ROM image we load as part of us.  When
;               physical ROM hardware becomes available, the following
;               can be deleted.

        add     bx,offset rom_image
        adc     dx,0
        mov     ax,cs
        rol     ax,1
        rol     ax,1
        rol     ax,1
        rol     ax,1
        push    ax
        and     ax,0fff0h
        add     ax,bx
        mov     src_low,ax              ; save low 16 bits of source
        pop     ax
        adc     al,dl
        and     al,0fh          ; limit to low meg for simulation
        mov     src_hi,al

;       *this is the end of the debug simulation code*

ELSE
        mov     src_low, bx
        mov     src_hi, dl

ENDIF ; FAKEROM

;       Now calculate and store the destination address

        mov     ax,es
        rol     ax,1
        rol     ax,1
        rol     ax,1
        rol     ax,1
        push    ax
        and     ax,0fff0h
        add     ax,di
        mov     dst_low,ax
        pop     ax
        adc     al,0
        and     al,0fh
        mov     dst_hi,al

        push    es
        push    si
        mov     si,offset gdts
        push    cs
        pop     es
        shr     cx,1                    ; convert count to words
        jnz     not_64k
        or      ch,80h                  ; force 64k to be 32K words, not zero
not_64k:
        mov     ah,87h
        int     15h
        pop     si
        pop     es
        mov     al,0
        jnc     no_disk_error
        mov     al,8                    ; all errors are type 8
no_disk_error:
        ret

IFDEF   FAKEROM
rom_image:
        include rom8k.inc
ENDIF ; FAKEROM

bios_data       ENDS
        end
