Files
Digital-Research-Source-Code/MPM OPERATING SYSTEMS/MPM I/MPM I SOURCE/06/genhex.asm
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

1 line
6.0 KiB
NASM
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

TITLE 'GENERATE HEX FILE FROM COM FILE 1/80'
; HEX DUMP PROGRAM, READS AN INPUT FILE AND PRODUCES A HEX FILE
;
; COPYRIGHT (C), DIGITAL RESEARCH, 1976, 1977, 1978, 1979, 1980
; BOX 579 PACIFIC GROVE, CALIFORNIA
;
;
; Revised:
; 19 Jan 80 by Thomas Rolander
;
ORG 100H
LXI SP,STKTOP
JMP MAIN
DB ' COPYRIGHT (C) 1980, DIGITAL RESEARCH '
BOOT EQU 0000H ;REBOOT POINT
BDOS EQU 0005H ;DOS ENTRY POINT
CONS EQU 1 ;READ CONSOLE
TYPEF EQU 2 ;TYPE FUNCTION
PRNTF EQU 9 ;PRINT BUFFER
OPENF EQU 15 ;FILE OPEN
CLOSF EQU 16 ;FILE CLOSE
DELF EQU 19 ;FILE DELETE
READF EQU 20 ;READ FUNCTION
WRITF EQU 21 ;WRITE RECORD
MAKEF EQU 22 ;MAKE FILE
DMAF EQU 26 ;SET DMA ADDRESS
;
FCB EQU 5CH ;FILE CONTROL BLOCK ADDRESS
BUFF EQU 80H ;INPUT DISK BUFFER ADDRESS
CR EQU 0DH
LF EQU 0AH
EOF EQU 1AH ;END OF FILE (CTL-Z)
;
; SET UP STACK
; STACK AREA
STACK: DS 64
STKTOP EQU $
;
; SUBROUTINES
;
;
GETBASE:
; READ THE OFFSET FROM THE SECOND PARAMETER
LXI H,FCB+17
LXI D,0
MVI B,8 ;MAX 8 DIGITS
GET0: MOV A,M
CPI ' '
JZ ENDGET
SUI '0'
CPI 10
JC GET1
; MUST BE HEX A-F
ADI ('0'-'A'+10) AND 0FFH
CPI 16
JNC BADGET
GET1: ;NEXT DIGIT IS IN A
XCHG
DAD H ;*2
DAD H ;*4
DAD H ;*8
DAD H ;*16
ADD L
MOV L,A
XCHG
INX H ;TO NEXT POSITION
DCR B
JNZ GET0
;
ENDGET:
XCHG
SHLD OFFSET
RET
;
BADGET:
LXI D,GETMSG
CALL PRINT
JMP BOOT
;
GETMSG:
DB CR,LF,'BAD HEX DIGIT IN BASE$'
;
PRINT: ;PRINT A BUFFER
MVI C,PRNTF
CALL BDOS
RET
;
PCHAR: ;SEND CHAR TO OUTPUT FILE
PUSH H
PUSH D
LXI H,OBP ;BUFFER POINTER
PUSH H ;SAVE FOR LATER
MOV E,M ;LO BYTE
MVI D,0
LXI H,BUFF
DAD D ;BUFF(OBP) IN H,L
MOV M,A ;STORE CHARACTER TO BUFFER
POP H ;RECALL OBP ADDRESS
INR M ;OBP=OBP+1
MOV A,M ;PAST END OF BUFFER?
CPI 128
JC EPCHAR
; WRITE THE BUFFER TO THE DISK FILE
MVI M,0 ;CLEARS OBP
PUSH B ;SAVE ENVIRONMENT
MVI C,WRITF
LXI D,FCB
CALL BDOS
ORA A ;ERROR?
JNZ BADPR
; NO ERROR, RETURN TO CALLER
POP B
EPCHAR: POP D
POP H
RET
;
BADPR: ;BAD WRITE
MVI C,CLOSF
LXI D,FCB
CALL BDOS ;TRY TO CLOSE THE FILE
LXI D,PRMSG
CALL PRINT
JMP BOOT
PRMSG: DB CR,LF,'DISK IS FULL$'
;
CRLF:
MVI A,CR
CALL PCHAR
MVI A,LF
CALL PCHAR
RET
;
;
PNIB: ;PRINT NIBBLE IN REG A
ANI 0FH ;LOW 4 BITS
CPI 10
JNC P10
; LESS THAN OR EQUAL TO 9
ADI '0'
JMP PRN
;
; GREATER OR EQUAL TO 10
P10: ADI 'A' - 10
PRN: CALL PCHAR
RET
;
MAIN: ; READ AND PROCESS SUCCESSIVE BUFFERS
CALL GETBASE ;GET BASE ADDRESS FOR DUMP
CALL SETUP ;SET UP INPUT FILE
; LOAD COM FILE TO MEMORY
LXI D,IBUFF
LOAD: ;READ DISK RECORD TO MEMORY
PUSH D ;SAVE DMA ADDRESS
MVI C,DMAF
CALL BDOS ;DMA SET
LXI D,FCB
MVI C,READF
CALL BDOS
POP D
ORA A
JNZ FINIS
LXI H,128
DAD D
XCHG
JMP LOAD ;FOR ANOTHER RECORD
;
FINIS:
DCR A ;EOF=1
JZ BUILDHEX
LXI D,RERR
CALL PRINT ;BAD DISK READ
JMP BOOT
;
BUILDHEX:
;BUILD HEX FILE FROM IBUFF THROUGH EBUFF
PUSH D
CALL SETHEX ;SET UP HEX FILE
POP D
DCX D ;LAST ADDRESS
LXI H,IBUFF ;D,E HOLDS HIGH ADDRESS, H,L HOLDS LOW ADDRESS
W0: MOV A,L ;GET LOW/NEXT ADDRESS
ADI 16 ;COMPUTE NEXT ADDRESS
MOV C,A ;SAVE TEMP IN B,C
MOV A,H
ACI 0
MOV B,A ;LOW ADDRESS+16 IN B,C
MOV A,E ;COMPARE HIGH ADDRESS
SUB C
MOV C,A ;SAVE DIFFERENCE
MOV A,D
SBB B
JC W1 ;'CAUSE LESS THAN 16
; OTHERWISE 16 BYTE RECORD
MVI A,16
JMP W2
;
W1: ;SHORT RECORD
MOV A,C ;-DIFF
ADI 17 ;MAKE IT POSITIVE
W2: ;CHECK FOR LAST RECORD
ORA A
JZ HDONE ;IF LAST
; OTHERWISE WRITE RECORD
PUSH D ;SAVE HIGH ADDRESS
MOV E,A ;SAVE LENGTH
MVI D,0 ;CLEAR CS
CALL CRLF ;WRITE CRLF
MVI A,':'
CALL PCHAR
MOV A,E ;LENGTH
CALL WRC ;WRITE CHARACTER
; APPLY OFFSET TO BASE ADDRESS
PUSH H
PUSH D
XCHG ;ABSOLUTE ADDRESS TO D,E
LXI H,-IBUFF
DAD D ;ABSOLUTE-IBUFF TO H,L
XCHG
LHLD OFFSET
DAD D ;ABSOLUTE-IBUFF+OFFSET
POP D
MOV A,H ;HO ADDRESS
CALL WRC
MOV A,L ;LO ADDRESS
CALL WRC
POP H ;ABSOLUTE ADDRESS
XRA A
CALL WRC ;RECORD TYPE
;
; WRITE RECORD
W3: MOV A,M
INX H
CALL WRC
DCR E
JNZ W3 ;FOR MORE
;
XRA A ;COMPUTE CHECKSUM
SUB D
CALL WRC
POP D ;RESTORE HIGH ADDR
JMP W0
;
WRC: ;WRITE CHAR WITH CHECK SUM IN D
PUSH PSW
RRC
RRC
RRC
RRC
ANI 0FH
CALL PNIB
POP PSW
PUSH PSW
ANI 0FH
CALL PNIB
POP PSW
ADD D
MOV D,A
RET
;
HDONE:
; FINISH BUFFER OUTPUT
CALL CRLF
MVI A,':'
CALL PCHAR
MVI B,8
ZLOOP: ;SEND 8 ZEROES TO OUTPUT
XRA A
CALL WRC
DCR B
JNZ ZLOOP
;
CALL CRLF
;
; FILL OUTPUT WITH END OF FILE CHARACTERS
FILLE: LDA OBP
ORA A
JZ EFILL ;WRITE 'TIL ZERO POINTER
MVI A,EOF
CALL PCHAR
JMP FILLE
; CLEARED, NOW CLOSE THE FILE
EFILL: MVI C,CLOSF
LXI D,FCB
CALL BDOS
CPI 255
JZ BADCLOSE
LXI D,ENDMSG
CALL PRINT
JMP BOOT
ENDMSG: DB CR,LF,'HEX FILE WRITTEN$'
;
BADCLOSE:
; CANNOT CLOSE THE FILE
LXI D,CLMSG
CALL PRINT
JMP BOOT
CLMSG: DB CR,LF,'CANNOT CLOSE FILE, CHECK WRITE PROTECT$'
;
; FILE CONTROL BLOCK DEFINITIONS
FCBDN EQU FCB+0 ;DISK NAME
FCBFN EQU FCB+1 ;FILE NAME
FCBFT EQU FCB+9 ;DISK FILE TYPE (3 CHARACTERS)
FCBRL EQU FCB+12 ;FILE'S CURRENT REEL NUMBER
FCBRC EQU FCB+15 ;FILE'S RECORD COUNT (0 TO 128)
FCBCR EQU FCB+32 ;CURRENT (NEXT) RECORD NUMBER (0 TO 127)
FCBLN EQU FCB+33 ;FCB LENGTH
;
;
FILLTYPE:
; SET THE TYPE FIELD FOR THE CURRENT FCB TO VALUE AT D,E
LXI H,FCBFT
MVI B,3
FILL0: LDAX D
INX D
MOV M,A
INX H
DCR B
JNZ FILL0
mvi m,0 ;*** Bug fix: zeroes the extent
RET
;
SETUP: ;SET UP FILE
LXI D,COMTYPE
CALL FILLTYPE
; OPEN THE FILE FOR INPUT
LXI D,FCB
MVI C,OPENF
CALL BDOS
; CHECK FOR ERRORS
CPI 255
JNZ OPNOK
LXI D,OPERR
CALL PRINT
JMP BOOT
OPERR: DB CR,LF,'NO INPUT FILE PRESENT$'
COMTYPE:
DB 'COM'
;
SETHEX:
; SET UP HEX FILE
XRA A
STA OBP ;OUTPUT POINTER SET TO BEGINNING
LXI D,BUFF
MVI C,DMAF ;RESET DMA ADDRESS
CALL BDOS
;
LXI D,HEXTYPE
CALL FILLTYPE ;SET TO .HEX
LXI D,FCB
PUSH D
MVI C,DELF ;DELETE OLD COPIES
CALL BDOS
POP D
MVI C,MAKEF ;MAKE A NEW ONE
CALL BDOS
CPI 255
JNZ OPNOK
;
; CANNOT CREATE THE FILE
LXI D,NOSPACE
CALL PRINT
JMP BOOT
NOSPACE:
DB CR,LF,'NO DIRECTORY SPACE$'
HEXTYPE:
DB 'HEX'
;
OPNOK: ;OPEN IS OK.
XRA A
STA FCBCR
RET
;
RERR: DB CR,LF,'DISK READ ERROR$'
;
OBP DS 1 ;OUTPUT BUFFER POINTER
OFFSET DS 2 ;DISPLACEMENT TO ADD IN HEX TAPE
IBUFF EQU ($ AND 0FF00H)+100H
END