;*DDK*************************************************************************/
;
; COPYRIGHT    Copyright (C) 1995 IBM Corporation
;
;    The following IBM OS/2 WARP source code is provided to you solely for
;    the purpose of assisting you in your development of OS/2 WARP device
;    drivers. You may use this code in accordance with the IBM License
;    Agreement provided in the IBM Device Driver Source Kit for OS/2. This
;    Copyright statement may not be removed.;
;*****************************************************************************/
;/*****************************************************************************
;*
;* SOURCE FILE NAME = DMC.ASM
;*
;* DESCRIPTIVE NAME = Download micro code
;*
;*
;* VERSION      V2.0
;*
;* DATE
;*
;* DESCRIPTION
;*
;* FUNCTIONS    download_mc,    ShowProgress,   readrecord,     DoDosRead.
;*
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*   03/23/93              60689  Do retry if record send fails. Usually fails
;*				  when sending last byte of last record.
;*				  Probable cause is ucode generating line noise
;*				  after sending final ACK byte while doing
;*				  internal processing.
;*****************************************************************************/

ucode_stru      STRUC                           ;uCode file record layout
uc_size         DB      ?
uc_addr_hi      DB      ?
uc_addr_lo      DB      ?
uc_type         DB      ?
uc_code_lvl     DW      ?
uc_filesize     DW      ?
uc_crc          DW      ?
uc_spare        DW      ?
uc_name         DB      8 dup(?)
ucode_stru      ENDS


uc_ptr          EQU     word ptr ss:[si]


DSEG            SEGMENT

parm_lvl        db      '??',0

dld_pcnt        DB      CR, "00"
dld_pcnt_size   equ     $-dld_pcnt


;*
;* string to clear download message
;* the message itself must be less than 80 chars in length for this to work
;*
dld_all         db      CR
                DB      "                                        "
                DB      "                                       "
dld_crlf        db      CR

dld_end         EQU     $

DSEG            ENDS


                EXTRN   DOSREAD:FAR
                EXTRN   DOSOPEN:FAR
                EXTRN   DOSCLOSE:FAR


public  download_mc, dodosread, readrecord, showprogress


;/***************************************************************************
;*
;* FUNCTION NAME = download_mc
;*
;* DESCRIPTION   =
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

PROCEDURE       download_mc     near

PARAMETER       test_only       word            ;1 => check code level only
PARAMETER       ucode_lvl       word            ; from prescott
PARAMETER       name_ptr        dword           ; micro code file name

VARIABLE        handle          word
VARIABLE        action          word
VARIABLE        bytecount       word
VARIABLE        filecount       word
VARIABLE        filesize        word
VARIABLE        returncode      word
VARIABLE        inputbuffer     nbyte 255+5     ;max bytes for download+cmd
VARIABLE        retrycount      word

openmode        EQU             02020H          ;Deny Write/Read Only

        BEGINPROC


$VarCount = 0   ;*
                ;* *** fiddle to remove the need for FREEVAR ***
                ;*

                pusha
                cld

;*
;* Open the file
;*
                push    word ptr name_ptr.xseg          ;far ptr
                push    word ptr name_ptr.xoff          ;  to FileName
                lea     di, handle
                push    ss                              ;far ptr
                push    di                              ;  to FileHandle
                lea     si, action
                push    ss                              ;far ptr
                push    si                              ;  to ActionTaken
                push    0                               ;FileSize
                push    0                               ;  (ULONG)
                push    0                               ;FileAttribute (USHORT)
                push    1                               ;OpenFlag (open file)
                push    openmode                        ;OpenMode
                push    0                               ;reserved
                push    0                               ;  (ULONG)
                call    DOSOPEN                         ; 
                mov     returncode, ERR_DD_MCOPEN       ; 
                or      ax, ax                          ; 
                jz      @F                              ; OK
                jmp     dld_error1                      ;$$ DOS open error
@@:
;*
;* Read the first record
;*
                mov     di, handle                      ; 
                lea     si, inputbuffer                 ; 
                call    readrecord                      ; 
                mov     returncode, ERR_DD_MCREAD       ; 
                mov     filecount, cx                   ;$$ Read error
                jc      dld_error                       ; 
                mov     ax, ucode_lvl                   ;code level from Prescott
                cmp     ax, uc_ptr.uc_code_lvl          ;  "    "     "  file
                mov     returncode, ERR_DD_MCLEVEL      ; 
                jne     dld_error                       ;$$ Code Level
                shl     ax, 4                           ;make uCode Level
                shr     al, 4                           ;  printable
                or      ax, 3030H                       ; 
                xchg    al, ah                          ; 

                ;*
                ;* %%% fill in level
                ;*
                mov     word ptr parm_lvl, ax           ; save ascii level

                mov     ax, test_only                   ; 
                or      ax, ax                          ;non-zero => only test
                jnz     dld_exit                        ;           code level

                mov     ax, uc_ptr.uc_filesize          ;file size (bytes)
                cwd
                mov     cx, 100
                div     cx
                mov     filesize, ax                    ; 

                ;*
                ;* %%% @ start
                ;*
                mov     gpm_parms.p1, offset parm_lvl
                push    INF_DD_DMC
                push    1
                call    getputmsg

;*
;* Download the file.
;*
dld_next:
                call    readrecord
                mov     returncode, ERR_DD_MCREAD       ; 
                jc      dld_error                       ;$$ Read error

                mov     bytecount, cx
                add     filecount, cx
		mov	retrycount, 40			;          
dld_retry:
		dec	retrycount			;          
		jz	dld_error			;          

                lea     ax, inputbuffer
                push    PIO_DMC
                push    ss
                push    ax
                call    prescott_io
                mov     returncode, ERR_DD_MCABIOS      ; 
                jc      dld_retry			;          

                cmp     bytecount, 5                    ; test for last record
                jne     dld_next                        ; jif more to come

dld_exit:
                mov     returncode, 0

dld_error:
                push    handle
                call    DOSCLOSE

dld_error1:
                popa
                mov     ax, returncode

;*
;* *** see $VarCount above ***
;* FREEVAR        handle
;* FREEVAR        action
;* FREEVAR        bytecount
;* FREEVAR        filecount
;* FREEVAR        filesize
;* FREEVAR        returncode
;*
ENDPROC         download_mc


;/***************************************************************************
;*
;* FUNCTION NAME = ShowProgress
;*
;* DESCRIPTION   =
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

ShowProgress    PROC    near

;*
;*** do not use enter here as stack variables used from previus procedure ***
;*

                pusha
                mov     ax, filecount
                mov     bx, filesize
                cwd
                div     bx
                cmp     ax, 100D
                jl      sp_1                    ; < 100%
;*
;* %%% @ end
;*
                mov     ax, offset DSEG:dld_all
                mov     cx, dld_end - dld_all
                call    pstr                    ;print 'done' string
                jmp     short sp_exit

sp_1:           aam
                or      ax, 3030H
                xchg    al, ah
                mov     word ptr dld_pcnt+1, ax ;!!!

;*
;* %%% on going
;*
                mov     ax, offset DSEG:dld_pcnt
;*              mov     cx, dld_hdr - dld_pcnt  ;
                mov     cx, dld_pcnt_size
                call    pstr                    ;print 'progress' string

sp_exit:        popa

                ret

ShowProgress    ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = readrecord
;*
;* DESCRIPTION   =
;*
;*
;* INPUT         = DI has file handle
;*                 SS:SI points to input buffer
;*
;* OUTPUT        = CX has total byte count
;*                    (5 if last sequence to send ie. 0 code bytes).
;*                 Registers preserved.
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = Carry set if error.
;*
;**************************************************************************/

PROCEDURE       readrecord      near

        BEGINPROC

                push    es
                push    bx
                push    si
                mov     ax, 1                           ; num bytes to read
                call    DoDosread                       ; get byte count
                jc      rdrec_exit                      ; 
                lods    byte ptr ss:0                   ;code length
                xor     ah, ah                          ; 
                add     ax, 4                           ;+ header & crc
                push    ax                              ; save count
                call    DoDosRead                       ;read the rest
                pop     cx                              ; restore count
                jc      rdrec_exit                      ; jif read error
                add     cx, 1                           ;total byte count
                xor     ah, ah                          ;clear for checksum
                push    cx
                dec     si                              ; go back to len
rd_chk:
                lods    byte ptr ss:0
                add     ah, al                          ;calc checksum
                loop    rd_chk
                pop     cx
                or      ah, ah                          ;should be zero
                jz      rdrec_exit                      ;exit CY clear
                stc                                     ;bad checksum
rdrec_exit:
                pop     si
                pop     bx
                pop     es


ENDPROC         readrecord


;/***************************************************************************
;*
;* FUNCTION NAME = DoDosRead
;*
;* DESCRIPTION   =
;*
;*
;* INPUT         = AX has number of bytes to read.
;*
;* OUTPUT        = Registers preserved.
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = Carry set if error reading or requested no of bytes
;*                 not read.
;*
;**************************************************************************/

PROCEDURE       DoDosRead       near

VARIABLE        bytesread       word

        BEGINPROC

                pusha

                push    ax                              ;bytes to read

                push    di                              ;FileHandle

                push    ss                              ; far ptr
                push    si                              ;  to input buffer

                push    ax                              ; bytes to be read

                lea     bx, bytesread                   ; 
                push    ss                              ;far ptr
                push    bx                              ;  to BytesRead

                call    DOSREAD                         ;read length byte
                pop     cx                              ;bytes requested
                or      ax, ax
                jnz     ddr_error
                cmp     cx, bytesread
                jne     ddr_error
                clc
                jmp     short ddr_exit
ddr_error:      stc
ddr_exit:       popa


FREEVAR         bytesread

ENDPROC         DoDosRead

;*
;* end
;*
