home *** CD-ROM | disk | FTP | other *** search
- title 'GOCRCGEN - Cpm utility to download code to GCP 02/12/81'
- ;---------------------------------------------------------
- ;GOCRCGEN.COM is a special load program used to get a
- ; copy of the GCP code that resides on disk,
- ; Download it to the GCP boot for storage in RAM
- ; and then give it control. The first block
- ; on disk is a header block that contains the
- ; download commands to download, and then execute
- ; downloaded code. Format of this block is as follows:
- ;
- ; Modiified by D.C.Barrick 810206
- ; by D.A.STEELE 12 FEB 81
- ; Length byte of command (6)
- ; Download opcode (either 7 or 7*4)
- ; Download program id (1). This is not used but added for
- ; compatibility with downloaded code.
- ; Download program address (2 bytes) Specifies load address
- ; in the GCP.
- ; Download program length (2 bytes) Specifies length of
- ; program to be downloaded.
- ;
- ; Length count for execution command (usually 3)
- ; Execute command opcode (16 or 16*4)
- ; Execute program id (1)
- ; Execution address (2 bytes)
- ;
- ;
- ;
- ; The second and subsequent blocks
- ; are the memory image.
- ;
- ; The file is always saved as CRCGEN.COM
- ; and is assumed to be on the A: drive.
- ;
- ;---------------------------------------------------------
- cr equ 0dh
- lf equ 0ah
- @bdos equ 0005h
-
- page
- ;--------------------------------------------------------
- ; The following equates establish the linkage between
- ; the program in the TPA and the special GCP routines
- ; hidden in the BIOS
- ;--------------------------------------------------------
-
- msize equ 62 ; This should be set to system RAM size
- ; Note: This BIOS requires 2k more than the
- ; standard CP/M BIOS. Therefore the CCP/BDOS
- ; routines must be located 2k lower than normal.
- ; This is automactically accomplished by the
- ; MOVCPM.COM supplied with InterSystems
- ; CP/M package. For example:
- ; MOVCPM 64 * will create a CCP/BDOS
- ; which starts at DC00h instead of E400h.èbias equ (msize-22)*1024
- ccp equ 3400h+bias ; base of CCP
- bdos equ ccp+806h ; base address of BDOS (about 7k below the BIOS)
- bios equ ccp+1600h ; base address of BIOS (basic input/output system)
-
- gxo equ bios+51 ; routine for transparent send to the GCP (char in <C>).
- dmawrt equ bios+69 ; routine to do DMA write to GCP
- ; <BC> has length, <DE> has data address
-
- page
- aseg
- ORG 100H
- START:
- ; save CP/M's stack
-
- di
- lxi h,0
- dad sp
- shld OLD$STACK
- lxi sp, USER$STACK
- ei
-
- LXI D,FCB
- MVI C,0FH ;OPEN CODE
- CALL @bdos
- ANI 0FCH ;XXXX XX..
- JZ OPENOK
- ;----------------------------------
- ; The file CRCGEN.COM doesn't exist, Tell someone and
- ; then exit.
- ;----------------------------------
- lxi d,msg1
- mvi c,9
- call @bdos
- ;--------------------------------------
- ; return to CP/M
- ;--------------------------------------
- jmp return
- openok:
- ;---------------------------------------------------------
- ; Read in the header block
- ;-----------------------------------------------------------
- lxi d,header
- mvi c,1ah ;set dma address
- call @bdos
-
- lxi d,fcb
- mvi c,20 ;read in header
- call @bdos
- ani 0FCh ;ignore low two bits as error
- ora a
- jnz rderr
-
- ;-----------------------------------------------------------
- ; CRCGEN file has been opened and it's header block read intoè; memory. Send the program download command and then
- ; start the actual reads and DMA transfers.
- ;----------------------------------------------------------
-
- lxi h,header
- call send ;send to GCP
- shld execadd ;save execute command address
-
- lxi d,rdbuffer
- mvi c,1ah ;set DMA address for data
- call @bdos
- rdloop:
- lxi d,fcb
- mvi c,20 ;read a block
- call @bdos
- ani 0FCh ;ignore read type bits
- ora a
- jnz rderr ;go to write error msg
- ;-----------------------------------------------
- ; Drop the count by 128, if less than zero
- ; we must do a residual dma write, if new length is
- ; zero, we must send a full 128 and then stop
- ;-----------------------------------------------
- lhld addr4
- lxi d,128
- call sub16
- jc partial
-
- ;---------------------------------------------------
- ; Must have been 128 or greater so DMA 128 bytes
- ;---------------------------------------------------
- shld addr4
- lxi b,128 ;DMA length
- lxi d,rdbuffer ;address
- call dmawrt
-
- ;----------------------------------
- ; Now see if done. i.e. new length of zero
- ;-----------------------------------
- lhld addr4
- mov a,l
- ora h
- jz endit
-
- jmp rdloop ;more
- ;--------------------------------------
- ; error condition
- ; on write
- ;---------------------------------------
- rderr: lxi d,msg2
- mvi c,9
- call @bdos
- mvi c,0
- call @bdos
- ;----------------------------------------------è; All done except for the last short block
- ;-----------------------------------------------
- partial:
- lhld addr4 ;get the partial buffer count
- mov b,h
- mov c,l
- lxi d,rdbuffer
- call dmawrt
-
- ;------------------------------------------------
- ; close the file
- ;-------------------------------------------------
- endit:
- lxi d,fcb
- mvi c,10h ;close
- call @bdos
- ani 0fch
- jz endok
- ;-----------------------------------------
- ; didn't close successfully
- ;------------------------------------------
- lxi d,msg3
- mvi c,9
- call @bdos
- mvi c,0
- call @bdos
- jmp return
- ;------------------------------------------------
- ; all done successfully
- ;
- ; send the start execution code
- ;------------------------------------------------
- endok:
- lhld execadd ;restore execute command address & send
- call send
-
- ;------------------------------------------------
- ; wait a while for the GCP to start up
- ; then return to CP/M
- ;------------------------------------------------
- lxi h,1000h
- delay:
- dcx h
- mov a,h
- ora l
- jnz delay
- jmp return
- page
- ;---------------------------------------------
- ; Subtract 16 bit DE from 16 bit HL leaving
- ; result in HL
- ;---------------------------------------------
- sub16:
- mov a,l
- sub eè mov l,a
- mov a,h
- sbb d
- mov h,a
- ret
-
- ;-------------------------------------------------------
- ; SEND This is used to send a command sequence to the
- ; Skeleton GCP. The HL register must point to the
- ; command length byte. NOTE that the length byte
- ; doesn't include itself. On completeion
- ; <HL> should point to the next commands length byte.
- ;---------------------------------------------------------
- send:
- mov a,m ;get length byte
- inr a ;add one to get length that I must send.
- send2:
- push h
- push psw
- mov c,m ;get a byte
- call gxo ;and send
- pop psw
- pop h
- inx h ;step to next
- dcr a ;drop count
- rz ;return on all sent
- jmp send2 ;go send more
-
- ;-----------------------------------------------------------
- ; Restore CP/M's stack and return
- ;-----------------------------------------------------------
- return:
- di
- lhld old$stack
- sphl
- ei
- ret
-
- page
- ;------------------------------------------------------------
- ; The following is the header block. It is an image of the
- ; download and the execute command that will be sent to
- ; cause the rest of the code in the file to download
-
- ;------------------------------------------------------------
- header:
- ds 1 ;length of download command
- ds 1 ;download command opcode
- ds 1 ;dummy program id
- addr1: ds 2 ;start of image location
- addr4: ds 2 ;calculated length of image
-
-
- ds 1 ;length of execute command
- ds 1 ;execute commands opcodeè ds 1 ;dummy program id
- addr3: ds 2 ;execution start address
-
- ds 3 ;dummy area
- addr2: ds 2 ;hold area for stop address
-
- rdaddr: ds 2 ;write address hold
- execadd:ds 2 ;hold for executes command address
-
- rdbuffer: ds 128 ;download buffer
-
- msg1: db 'No CRCGEN.COM file on drive A.',cr,lf,'$'
- msg2: db 'GCP Read file failed',cr,lf,'$'
- msg3: db 'Close failed',cr,lf,'$'
-
- fcb: db 0,'CRCGEN COM'
- db 0,0,0,0,0,0,0,0
- db 0,0,0,0,0,0,0,0
- db 0,0,0,0,0,0,0,0
- db 0,0,0,0,0,0,0,0
- ds 80h ; user stack space
- user$stack equ $
-
- old$stack:
- ds 2 ; save location for CP/M's stack pointer
- end start
-