home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / disasm / dasmz80.arc / DASMZ80.ASM < prev    next >
Assembly Source File  |  1986-07-22  |  34KB  |  1,181 lines

  1.     .XALL
  2.     PAGE    ,132
  3.     TITLE DASMZ80 - 21 OCT 1985
  4.  
  5. ; ****************************************************************
  6. ; **                                **
  7. ; **              MS-DOS Z80 DISASSEMBLER            **
  8. ; **                                **
  9. ; **............................................................**
  10. ; **                                **
  11. ; **         DASMZ80 DISASSEMBLES Z80 INTEL HEX FILES.        **
  12. ; **                                **
  13. ; ****************************************************************
  14.  
  15. ; ..... MODULE CONNECTION POINTS .....
  16.  
  17.     EXTRN    MNEM_STRINGS:NEAR
  18.     EXTRN    BYTES:NEAR
  19.     EXTRN    CB_STRINGS:NEAR
  20.     EXTRN    CB_BYTES:NEAR
  21.     EXTRN    DD1_STRINGS:NEAR
  22.     EXTRN    DD1_BYTES:NEAR
  23.     EXTRN    DD2_STRINGS:NEAR
  24.     EXTRN    DD2_BYTES:NEAR
  25.     EXTRN    ED_STRINGS:NEAR
  26.     EXTRN    ED_BYTES:NEAR
  27.     EXTRN    FD1_STRINGS:NEAR
  28.     EXTRN    FD1_BYTES:NEAR
  29.     EXTRN    FD2_STRINGS:NEAR
  30.     EXTRN    FD2_BYTES:NEAR
  31.  
  32. ; ..... MACROS .....
  33.  
  34. DISKRD    MACRO    NUMBYTE        ; READ SPECIFIED NUMBER OF BYTES FROM DISK
  35.     LOCAL    OK        ; OK IS A LOCAL SYMBOL
  36.     MOV    AH,READ        ; LOAD READ COMMAND
  37.     MOV    BX,RDHAND    ; LOAD READ FILE HANDLE
  38.     MOV    CX,NUMBYTE    ; LOAD NUMBER OF CHARACTERS TO BE READ
  39.     MOV    DX,OFFSET DSKBUF; POINT TO DISK BUFFER
  40.     INT    DOSFUNC        ; READ FROM INPUT FILE - ERROR?
  41.     JNC    OK        ; NO - DONE
  42.  
  43.     JMP    DSKERR        ; YES - DISPLAY ERROR
  44.  
  45. OK:
  46.     ENDM            ;
  47.  
  48. DISKWR    MACRO    NUMBYTE        ; WRITE SPECIFIED NUMBER OF BYTES TO DISK
  49.     LOCAL    OK        ; OK IS A LOCAL SYMBOL
  50.     MOV    AH,WRITE     ; LOAD WRITE COMMAND
  51.     MOV    BX,WRHAND    ; LOAD WRITE FILE HANDLE
  52.     MOV    CX,NUMBYTE    ; LOAD NUMBER OF CHARACTERS TO WRITE
  53.     MOV    DX,OFFSET DSKBUF; POINT TO DISK BUFFER
  54.     INT    DOSFUNC        ; WRITE TO OUTPUT - ERROR?
  55.     JNC    OK        ; NO - DONE
  56.  
  57.     JMP    DSKERR        ; YES - DISPLAY ERROR
  58.  
  59. OK:
  60.     ENDM            ;
  61.  
  62.  
  63. ; ..... DOS COMMANDS .....
  64.  
  65. DOSFUNC EQU    21H        ; DOS FUNCTION INTERRUPT
  66. PR_STR    EQU    09H        ; DOS FUNCTION PRINT STRING COMMAND
  67. CREATE    EQU    3CH        ; CREATE FILE COMMAND
  68. OPEN    EQU    3DH        ; OPEN FILE COMMAND
  69. CLOSE    EQU    3EH        ; CLOSE FILE COMMAND
  70. READ    EQU    3FH        ; READ FILE COMMAND
  71. WRITE    EQU    40H        ; WRITE FILE COMMAND
  72. RDACC    EQU    0        ; READ FILE ACCESS CODE
  73. WRACC    EQU    1        ; WRITE FILE ACCESS CODE
  74. WRATT    EQU    0        ; WRITE FILE ATTRIBUTE CODE
  75.  
  76.  
  77. ; ..... CONSTANTS .....
  78.  
  79. MEMLEN    EQU    2000H        ; LENGTH OF MEMORY BUFFER
  80. MAXLEN    EQU    80        ; MAXIMUM FILE NAME LENGTH
  81. CR    EQU    0DH        ; ASCII <CR>
  82. LF    EQU    0AH        ; ASCII LINE FEED
  83. RS    EQU    1EH        ; ASCII RECORD SEPARATOR
  84. TAB    EQU    09H        ; ASCII TAB
  85. DATIND    EQU    00H        ; HEX FILE DATA RECORD INDICATOR
  86. EOFIND    EQU    01H        ; HEX FILE END OF FILE INDICATOR
  87.  
  88.  
  89. STACK    SEGMENT STACK        ; STACK SEGMENT
  90.     DW    1024 DUP (?)    ; 1024 LEVELS OF STACK
  91. STACK    ENDS
  92.  
  93. DATA    SEGMENT PUBLIC        ; DATA SEGMENT
  94.  
  95. ; ****************************************************************
  96. ; **                                **
  97. ; **            MISCELLANEOUS STRINGS            **
  98. ; **                                **
  99. ; ****************************************************************
  100.  
  101. MSGORG    DB    ';',CR,LF,TAB,'ORG',TAB,'0'
  102. LENORG    EQU    $-MSGORG
  103.  
  104. MSGEND    DB    ';',CR,LF,TAB,'END',CR,LF
  105. LENEND    EQU    $-MSGEND
  106.  
  107.  
  108. ; ****************************************************************
  109. ; **                                **
  110. ; **              ERROR STRINGS             **
  111. ; **                                **
  112. ; ****************************************************************
  113.  
  114. MBCOM    DB    CR,LF,'COMMAND LINE ERROR',CR,LF,LF,'$'
  115.  
  116. MBHEX    DB    CR,LF,'BAD HEX DATA',CR,LF,LF,'$'
  117.  
  118. MDISK0    DB    CR,LF,'ERROR 0 - DISK FULL',CR,LF,LF,'$'
  119.  
  120. MDISK1    DB    CR,LF,'ERROR 1 - INVALID FUNCTION',CR,LF,LF,'$'
  121.  
  122. MDISK2    DB    CR,LF,'ERROR 2 - FILE NOT FOUND',CR,LF,LF,'$'
  123.  
  124. MDISK3    DB    CR,LF,'ERROR 3 - PATH NOT FOUND',CR,LF,LF,'$'
  125.  
  126. MDISK4    DB    CR,LF,'ERROR 4 - TOO MANY OPEN FILES',CR,LF,LF,'$'
  127.  
  128. MDISK5    DB    CR,LF,'ERROR 5 - ACCESS DENIED',CR,LF,LF,'$'
  129.  
  130. MDISK6    DB    CR,LF,'ERROR 6 - INVALID FILE HANDLE',CR,LF,LF,'$'
  131.  
  132. MUKNOW    DB    CR,LF,'UNKNOWN DISK ERROR',CR,LF,LF,'$'
  133.  
  134.  
  135. ; ****************************************************************
  136. ; **                                **
  137. ; **            PROGRESS MESSAGE STRINGS            **
  138. ; **                                **
  139. ; ****************************************************************
  140.  
  141. MRCOM    DB    CR,LF,'READING COMMAND LINE',CR,LF,'$'
  142.  
  143. MOPENR    DB    'OPENING READ FILE',CR,LF,'$'
  144.  
  145. MCHEX    DB    'CONVERTING HEX FILE',CR,LF,'$'
  146.  
  147. MOPENW    DB    'CLOSING READ AND OPENING WRITE FILE',CR,LF,'$'
  148.  
  149. MDSM    DB    'DISASSEMBLING CONVERTED DATA',CR,LF,'$'
  150.  
  151. MCLOSW    DB    'CLOSING WRITE FILE',CR,LF,'$'
  152.  
  153. MEXIT    DB    'EXITING TO DOS',CR,LF,LF,'$'
  154.  
  155.  
  156. ; ****************************************************************
  157. ; **                                **
  158. ; **            MEMORY ASSIGNMENTS            **
  159. ; **                                **
  160. ; ****************************************************************
  161.  
  162. DSKBUF    DB    80 DUP (?)    ; DISK I/O BUFFER
  163.  
  164. DSKCNT    DW    (?)        ; DISK BUFFER COUNTER
  165.  
  166. RDFILE    DB    MAXLEN+1 DUP (0); INPUT FILE NAME BUFFER
  167.  
  168. WRFILE    DB    MAXLEN+1 DUP (0); OUTPUT FILE NAME BUFFER
  169.  
  170. RDHAND    DW    (?)        ; READ FILE HANDLE
  171.  
  172. WRHAND    DW    (?)        ; WRITE FILE HANDLE
  173.  
  174. CHKACC    DB    (?)        ; CHECKSUM ACCUMULATOR
  175.  
  176. DSKPTR    DW    (?)        ; DISK BUFFER POINTER
  177.  
  178. MEMPTR    DW    (?)        ; MEMORY POINTER
  179.  
  180. MEMCNT    DW    (?)        ; MEMORY COUNTER
  181.  
  182. NUMREC    DW    (?)        ; NUMBER OF RECORDS IN CURRENT LINE
  183.  
  184. RECNUM    DW    (?)        ; NUMBER OF BYTES FOR NUMREC RECORDS
  185.  
  186. CURADD    DW    (?)        ; CURRENT ADDRESS
  187.  
  188. B_TAB    DW    (?)        ; POINTER TO BYTE TABLE
  189.  
  190. FCHCNT    DB    (?)        ; NUMBER OF FETCHES FOR CURRENT INSTRUCTION
  191.  
  192.     DB    (0)        ; DUMMY START OF MEMBUF
  193. MEMBUF    DB    MEMLEN DUP (0)    ; MEMORY BUFFER
  194.  
  195. DATA    ENDS
  196.  
  197.  
  198. CODE    SEGMENT            ; CODE SEGMENT
  199.     ASSUME    CS:CODE,DS:DATA,ES:DATA,SS:STACK
  200.  
  201. ; ****************************************************************
  202. ; **                                **
  203. ; **              MAIN PROGRAM                **
  204. ; **                                **
  205. ; ****************************************************************
  206.  
  207. DASMZ80 PROC    FAR        ;
  208.  
  209.     PUSH    DS        ;
  210.     MOV    AX,0        ;
  211.     PUSH    AX        ; SET UP FOR A FAR RETURN TO DOS
  212.  
  213.     MOV    AX,DATA        ;
  214.     MOV    DS,AX        ; SET UP DATA SEGMENT REGISTER
  215.  
  216.     MOV    DX,OFFSET MRCOM ; POINT TO READING COMMAND LINE MESSAGE
  217.     CALL    MSGCO        ; WRITE MESSAGE TO STANDARD OUTPUT
  218.     CALL    RCMD        ; READ COMMAND LINE
  219.  
  220.     MOV    DX,OFFSET MOPENR; POINT TO OPENING INPUT FILE MESSAGE
  221.     CALL    MSGCO        ; WRITE MESSAGE TO STANDARD OUTPUT
  222.     CALL    OPENRD        ; OPEN INPUT FILE FOR READ
  223.  
  224.     MOV    DX,OFFSET MCHEX ; POINT TO CONVERTING HEX FILE MESSAGE
  225.     CALL    MSGCO        ; WRITE MESSAGE TO STANDARD OUTPUT
  226.     CALL    CHEX        ; CONVERT INPUT FILE
  227.  
  228.     MOV    DX,OFFSET MOPENW; POINT TO OPENING OUTPUT FILE MESSAGE
  229.     CALL    MSGCO        ; WRITE MESSAGE TO STANDARD OUTPUT
  230.     CALL    OPENWR        ; OPEN OUTPUT FILE FOR WRITE
  231.  
  232.     MOV    DX,OFFSET MDSM    ; POINT TO DISASSEMBLING MESSAGE
  233.     CALL    MSGCO        ; WRITE MESSAGE TO STANDARD OUTPUT
  234.     CALL    DSM        ; DISASSEMBLE FILE
  235.  
  236.     MOV    DX,OFFSET MCLOSW; POINT TO CLOSING WRITE FILE MESSAGE
  237.     CALL    MSGCO        ; WRITE MESSAGE TO STANDARD OUTPUT
  238.     CALL    CLOSWR        ; DISASSEMBLE FILE
  239.  
  240.     MOV    DX,OFFSET MEXIT ; POINT TO EXITING MESSAGE
  241.     CALL    MSGCO        ; WRITE MESSAGE TO STANDARD OUTPUT
  242.     RET            ; RETURN TO DOS
  243.  
  244. DASMZ80 ENDP            ;
  245.  
  246.  
  247. ; ****************************************************************
  248. ; **                                **
  249. ; **            READ COMMAND LINE            **
  250. ; **                                **
  251. ; ****************************************************************
  252.  
  253. RCMD    PROC    NEAR        ;
  254.  
  255.     MOV    BX,80H        ; POINT TO NUMBER OF RECEIVED CHARACTERS
  256.     MOV    CH,ES:[BX]    ; LOAD NUMBER OF RECEIVED CHARACTERS
  257.     OR    CH,CH        ; ZERO CHARACTERS?
  258.     JZ    RCMD25        ; YES - DISPLAY ERROR
  259.  
  260.     INC    BX        ; NO - POINT TO CHARACTERS
  261.     MOV    DI,OFFSET RDFILE; POINT TO INPUT FILE NAME BUFFER
  262.     MOV    CL,MAXLEN    ; LOAD MAXIMUM FILE NAME LENGTH
  263.  
  264.     MOV    AL,ES:[BX]    ; READ NEXT CHARACTER
  265.     INC    BX        ; ADVANCE POINTER
  266.     DEC    CH        ; RETARD CHARACTER COUNTER - END?
  267.     JZ    RCMD25        ; YES - DISPLAY ERROR
  268.  
  269.     CMP    AL,' '        ; NO - SPACE?
  270.     JNZ    RCMD25        ; NO - DISPLAY ERROR
  271.  
  272. RCMD05:
  273.     MOV    AL,ES:[BX]    ; YES - READ NEXT CHARACTER
  274.     MOV    [DI],AL        ; WRITE TO INPUT FILE NAME BUFFER
  275.     CMP    AL,' '        ; SPACE?
  276.     JZ    RCMD10        ; YES - LOAD OUTPUT FILE NAME
  277.  
  278.     INC    BX        ; NO -
  279.     INC    DI        ;    - ADVANCE POINTERS
  280.     DEC    CH        ; RETARD CHARACTER COUNTER - END?
  281.     JZ    RCMD25        ; YES - DISPLAY ERROR
  282.  
  283.     DEC    CL        ; NO - RETARD FILE NAME COUNTER - TOO LONG?
  284.     JZ    RCMD25        ; YES - DISPLAY ERROR
  285.  
  286.     JMP    RCMD05        ; NO - CONTINUE
  287.  
  288. RCMD10:
  289.     INC    BX        ; ADVANCE COMMAND LINE POINTER
  290.     DEC    CH        ; DECREMENT CHARACTER COUNTER - END?
  291.     JZ    RCMD25        ; YES - DISPLAY ERROR
  292.  
  293.     MOV    DI,OFFSET WRFILE; NO - POINT TO OUTPUT FILE NAME BUFFER
  294.     MOV    CL,MAXLEN    ; LOAD MAXIMUM FILE NAME LENGTH
  295.  
  296. RCMD20:
  297.     MOV    AL,ES:[BX]    ; READ NEXT CHARACTER
  298.     CMP    AL,' '        ; SPACE?
  299.     JZ    RCMD25        ; YES - DISPLAY ERROR
  300.  
  301.     MOV    [DI],AL        ; NO - WRITE TO OUTPUT FILE NAME BUFFER
  302.     INC    BX        ;
  303.     INC    DI        ; ADVANCE POINTERS
  304.     DEC    CH        ; RETARD COUNTER - LAST CHARACTER?
  305.     JZ    RCMD30        ; YES - DONE
  306.  
  307.     DEC    CL        ; NO - RETARD COUNTER - FILE NAME TOO LONG?
  308.     JZ    RCMD25        ; YES - DISPLAY ERROR
  309.  
  310.     JMP    RCMD20        ; NO - CONTINUE
  311.  
  312. RCMD25:
  313.     MOV    DX,OFFSET MBCOM ; POINT TO BAD COMMAND LINE MESSAGE
  314.     JMP    MISERR        ; DISPLAY ERROR MESSAGE AND EXIT TO DOS
  315.  
  316. RCMD30:
  317.     RET            ;
  318.  
  319. RCMD    ENDP            ;
  320.  
  321. ; ****************************************************************
  322. ; **                                **
  323. ; **            OPEN INPUT FILE FOR READ            **
  324. ; **                                **
  325. ; ****************************************************************
  326.  
  327. OPENRD    PROC    NEAR        ;
  328.  
  329.     MOV    AH,OPEN        ; LOAD OPEN FILE COMMAND
  330.     MOV    AL,RDACC     ; LOAD READ ACCESS CODE
  331.     MOV    DX,OFFSET RDFILE; POINT TO INPUT FILE NAME
  332.     INT    DOSFUNC        ; OPEN INPUT FILE - ERROR?
  333.     JNC    OPRD05        ; NO - STORE READ FILE HANDLE
  334.  
  335.     JMP    DSKERR        ; YES - DISPLAY ERROR
  336.  
  337. OPRD05:
  338.     MOV    RDHAND,AX    ; NO - STORE READ FILE HANDLE
  339.     RET            ; DONE
  340.  
  341. OPENRD    ENDP            ;
  342.  
  343.  
  344. ; ****************************************************************
  345. ; **                                **
  346. ; **            CONVERT INPUT FILE            **
  347. ; **                                **
  348. ; ****************************************************************
  349.  
  350. CHEX    PROC    NEAR        ;
  351.  
  352. CHEX10:
  353.     DISKRD    1        ; READ ONE BYTE FROM DISK FILE - ERROR?
  354.  
  355.     CMP    AX,01        ; NO - 1 CHARACTER?
  356.     JZ    CHEX11        ; YES - TEST FOR RECORD MARK
  357.  
  358.     JMP    CHEX25        ; NO - DISPLAY ERROR
  359.  
  360. CHEX11:
  361.     MOV    BX,OFFSET DSKBUF; POINT TO DISK BUFFER
  362.     MOV    AL,[BX]        ; LOAD RECEIVED CHARACTER
  363.     CMP    AL,':'        ; RECORD MARK?
  364.     JNZ    CHEX10        ; NO - TRY AGAIN
  365.  
  366.     DISKRD    8        ; YES - READ EIGHT BYTES FROM DISK FILE - ERROR?
  367.  
  368.     MOV    CHKACC,0     ; NO - INITIALIZE CHECKSUM ACCUMULATOR
  369.     CMP    AX,08        ; RECEIVE 8 CHARACTERS?
  370.     JZ    CHEX12        ; YES - CONVERT NUMBER OF BYTES IN RECORD
  371.  
  372.     JMP    CHEX25        ; NO - DISPLAY ERROR
  373.  
  374. CHEX12:
  375.     MOV    BX,OFFSET DSKBUF; POINT TO DISK BUFFER
  376.     CALL    PACK        ; CONVERT NUMBER OF BYTES IN RECORD
  377.     MOV    AH,0        ;
  378.     MOV    NUMREC,AX    ; STORE
  379.     CALL    PACK        ; CONVERT HIGH START ADDRESS
  380.     MOV    DH,AL        ; STORE
  381.     CALL    PACK        ; CONVERT LOW START ADDRESS
  382.     MOV    DL,AL        ; STORE
  383.     CALL    PACK        ; CONVERT RECORD INDICATOR
  384.     CMP    AL,DATIND    ; DATA INDICATOR?
  385.     JNZ    CHEX20        ; NO - TEST FOR END OF FILE INDICATOR
  386.  
  387.     MOV    BX,OFFSET MEMBUF; YES - POINT TO MEMBUF
  388.     ADD    BX,DX        ; COMPUTE MEMBUF ADDRESS FOR THIS RECORD
  389.     MOV    MEMPTR,BX    ; STORE
  390.     MOV    AX,NUMREC    ; LOAD NUMBER OF RECORDS
  391.     ADD    AX,AX        ; COMPUTE NUMBER OF DATA CHARACTERS
  392.     ADD    AX,4        ; ADD CHECKSUM AND TERMINATOR CHARACTER COUNT
  393.     MOV    RECNUM,AX    ; STORE
  394.     DISKRD    RECNUM        ; YES - READ RECNUM BYTES FROM DISK FILE - ERROR?
  395.  
  396.     MOV    BX,OFFSET DSKBUF; NO - POINT TO DISK BUFFER
  397.     MOV    DSKPTR,BX    ; INITITIALIZE DISK BUFFER POINTER
  398.     CMP    RECNUM,CX    ; RECEIVED CORRECT NUMBER OF CHARACTERS?
  399.     JZ    CHEX14        ; YES - CONVERT RECORD
  400.  
  401.     JMP    CHEX25        ; NO - DISPLAY ERROR
  402.  
  403. CHEX14:
  404.     MOV    CX,NUMREC    ; LOAD COUNTER
  405.     JCXZ    CHEX21        ; ZERO BYTES? - YES - LOAD AND TEST
  406.                 ;    CHECKSUM AND TERMINATOR
  407.  
  408. CHEX15:
  409.     MOV    BX,DSKPTR    ; NO - LOAD DISK BUFFER POINTER
  410.     CALL    PACK        ; CONVERT DATA
  411.     MOV    DSKPTR,BX    ; STORE DISK BUFFER POINTER
  412.     MOV    BX,MEMPTR    ; LOAD MEMORY BUFFER POINTER
  413.     MOV    [BX],AL        ; STORE DATA
  414.     INC    MEMPTR        ; ADVANCE MEMORY BUFFER POINTER
  415.     DEC    CX        ; RETARD COUNTER - DONE?
  416.     JNZ    CHEX15        ; NO - CONTINUE
  417.  
  418.     MOV    BX,DSKPTR    ; YES - LOAD DISK BUFFER POINTER
  419.     CALL    PACK        ; CONVERT CHECKSUM
  420.     MOV    CL,AL        ; STORE CHECKSUM
  421.     MOV    AL,CHKACC    ; LOAD CHECKSUM ACCUMULATOR
  422.     SUB    AL,CL        ; ADJUST CHECKSUM
  423.     NOT    AL        ;
  424.     INC    AL        ; COMPUTE 2'S COMPLEMENT OF CHECKSUM
  425.     CMP    AL,CL        ; CHECKSUMS MATCH?
  426.     JNZ    CHEX25        ; NO - DISPLAY ERROR
  427.  
  428.     CMP    BYTE PTR[BX],CR ; YES - TERMINATED WITH <CR>?
  429.     JNZ    CHEX25        ; NO - DISPLAY ERROR
  430.  
  431.     INC    BX        ; YES - POINT TO LINE FEED
  432.     CMP    BYTE PTR[BX],LF ; LINE FEED?
  433.     JNZ    CHEX25        ; NO - DISPLAY ERROR
  434.  
  435.     JMP    CHEX10        ; YES - CONTINUE
  436.  
  437. CHEX20:
  438.     CMP    AL,EOFIND    ; END OF FILE INDICATOR?
  439.     JNZ    CHEX25        ; NO - DISPLAY ERROR
  440.  
  441.     DISKRD    4        ; YES - READ 4 BYTES FROM DISK FILE - ERROR?
  442.     CMP    AX,4        ; NO - 4 CHARACTERS?
  443.     JNZ    CHEX25        ; NO - DISPLAY ERROR
  444.  
  445. CHEX21:
  446.     MOV    BX,OFFSET DSKBUF; YES - POINT TO DISK BUFFER
  447.     CALL    PACK        ; CONVERT CHECKSUM
  448.     MOV    CL,AL        ; STORE CHECKSUM
  449.     MOV    AL,CHKACC    ; LOAD CHECKSUM ACCUMULATOR
  450.     SUB    AL,CL        ; ADJUST CHECKSUM
  451.     NOT    AL        ;
  452.     INC    AL        ; COMPUTE 2'S COMPLEMENT OF CHECKSUM
  453.     CMP    AL,CL        ; CHECKSUMS MATCH?
  454.     JNZ    CHEX25        ; NO - DISPLAY ERROR
  455.  
  456.     CMP    BYTE PTR[BX],CR ; YES - TERMINATED WITH <CR>?
  457.     JNZ    CHEX25        ; NO - DISPLAY ERROR
  458.  
  459.     INC    BX        ; YES - POINT TO LINE FEED
  460.     CMP    BYTE PTR[BX],LF ; LINE FEED?
  461.     JNZ    CHEX25        ; NO - DISPLAY ERROR
  462.  
  463.     RET            ; YES - DONE
  464.  
  465. CHEX25:
  466.     MOV    DX,OFFSET MBHEX ; POINT TO BAD HEX DATA MESSAGE
  467.     JMP    MISERR        ; DISPLAY ERROR MESSAGE AND EXIT TO DOS
  468.  
  469. CHEX    ENDP            ;
  470.  
  471.  
  472. ; ****************************************************************
  473. ; **                                **
  474. ; **            OPEN OUTPUT FILE FOR WRITE            **
  475. ; **                                **
  476. ; ****************************************************************
  477.  
  478. OPENWR    PROC    NEAR        ;
  479.  
  480.     MOV    AH,CLOSE     ; LOAD CLOSE FILE COMMAND
  481.     MOV    BX,RDHAND    ; LOAD INPUT FILE HANDLE
  482.     INT    DOSFUNC        ; CLOSE THE INPUT FILE - ERROR?
  483.     JNC    OPWR05        ; NO - OPEN WRITE FILE
  484.  
  485.     JMP    DSKERR        ; YES - DISPLAY ERROR
  486.  
  487. OPWR05:
  488.     MOV    AH,CREATE    ; LOAD CREATE FILE COMMAND
  489.     MOV    CX,WRATT     ; LOAD WRITE FILE ATTRIBUTE
  490.     MOV    DX,OFFSET WRFILE; POINT TO OUTPUT FILE NAME
  491.     INT    DOSFUNC        ; OPEN OUTPUT FILE - ERROR?
  492.     JNC    OPWR10        ; NO - STORE WRITE FILE HANDLE
  493.  
  494.     JMP    DSKERR        ; YES - DISPLAY ERROR
  495.  
  496. OPWR10:
  497.     MOV    WRHAND,AX    ; STORE WRITE FILE HANDLE
  498.     RET            ; DONE
  499.  
  500. OPENWR    ENDP            ;
  501.  
  502.  
  503. ; ****************************************************************
  504. ; **                                **
  505. ; **            DISASSEMBLE MEMORY BUFFER            **
  506. ; **                                **
  507. ; ****************************************************************
  508.  
  509. DSM    PROC    NEAR        ;
  510.  
  511.     MOV    BX,OFFSET MEMBUF-1; POINT TO MEMORY BUFFER
  512.     MOV    MEMPTR,BX    ; INITIALIZE MEMORY POINTER
  513.     MOV    BX,MEMLEN+2    ; LOAD NUMBER OF BYTES TO DISSASEMBLE
  514.     MOV    MEMCNT,BX    ; STORE
  515.  
  516. DSM05:
  517.     MOV    FCHCNT,1     ; INITIALIZE FETCH COUNTER
  518.     MOV    DSKPTR,OFFSET DSKBUF ; INITIALIZE DISK BUFFER POINTER
  519.     MOV    DSKCNT,0     ; CLEAR DISK BUFFER COUNTER
  520.     DEC    MEMCNT        ; RETARD MEMORY BUFFER COUNTER - END OF FILE?
  521.     JZ    DSM10        ; YES - WRITE "END" TO OUTPUT FILE
  522.  
  523.     MOV    BX,MEMPTR    ; NO - LOAD MEMORY BUFFER POINTER
  524.     MOV    AL,[BX]        ; LOAD NEXT OPCODE
  525.     OR    AL,AL        ; ZERO?
  526.     JNZ    DSM20        ; NO - FIND IT'S MNEMONIC
  527.  
  528. DSM10:
  529.     DEC    MEMCNT        ; YES - END OF FILE?
  530.     JNZ    DSM15        ; NO - POINT TO NEXT BYTE
  531.  
  532.     JMP    DSM175        ; YES - WRITE "END" TO DISK
  533.  
  534. DSM15:
  535.     INC    BX        ; POINT TO NEXT BYTE
  536.     MOV    AL,[BX]        ; LOAD IT
  537.     OR    AL,AL        ; ZERO?
  538.     JZ    DSM10        ; YES - CONTINUE
  539.  
  540.     MOV    MEMPTR,BX    ; NO - STORE MEMORY BUFFER POINTER
  541.     CALL    ORGWR        ; WRITE ORG LINE TO DISK
  542.     JMP    DSM05        ; CONTINUE
  543.  
  544. DSM20:
  545.     MOV    DX,BX        ; LOAD CURRENT MEMORY BUFFER LOCATION
  546.     SUB    DX,OFFSET MEMBUF; COMPUTE CURRENT ADDRESS
  547.     MOV    CURADD,DX    ; STORE
  548.     MOV    BX,MEMPTR    ; LOAD MEMORY BUFFER POINTER
  549.     MOV    CH,0        ;
  550.     MOV    CL,[BX]        ; LOAD OPCODE
  551.     PUSH    CX        ; SAVE OP-CODE
  552.     MOV    B_TAB,OFFSET BYTES ; NO - POINT TO INSTRUCTION BYTE TABLE
  553.     CALL    OPBYTE        ; COMPUTE NUMBER OF BYTES FOR THIS OPCODE
  554.     MOV    AL,CL        ; LOAD NUMBER OF BYTES
  555.     SUB    AL,05H        ; LESS THAN 5 BYTES?
  556.     MOV    BX,OFFSET MNEM_STRINGS    ; (POINT TO FIRST MNEMONIC TABLE)
  557.     JNC    DSM25        ; NO - TEST FOR LAST BYTE
  558.  
  559.     JMP    DSM55        ; YES - LOAD OP-CODE AND SEARCH FOR MNEMONIC
  560.  
  561. DSM25:
  562.     DEC    MEMCNT        ; NO - RETARD MEMORY COUNTER - LAST BYTE?
  563.     JNZ    DSM30        ; NO - ADVANCE FETCH COUNTER
  564.  
  565.     JMP    DSM175        ; YES - WRITE "END" TO OUTPUT FILE
  566.  
  567. DSM30:
  568.     DEC    MEMCNT        ; RETARD MEMORY BUFFER COUNTER - END OF FILE?
  569.     JNZ    DSM35        ; NO - ADVANCE FETCH COUNTER
  570.  
  571.     JMP    DSM175        ; YES - WRITE "END" TO OUTPUT FILE
  572.  
  573. DSM35:
  574.     INC    FCHCNT        ; ADVANCE FETCH COUNTER
  575.     INC    MEMPTR        ; ADVANCE MEMORY BUFFER POINTER
  576.     MOV    BX,MEMPTR    ; LOAD MEMORY BUFFER POINTER
  577.     POP    CX        ; RESTORE OLD OP-CODE
  578.     MOV    CL,[BX]        ; LOAD NEW OP-CODE
  579.     PUSH    CX        ; SAVE NEW OP-CODE
  580.     MOV    B_TAB,OFFSET CB_BYTES ; POINT TO CB BYTE TABLE
  581.     MOV    BX,OFFSET CB_STRINGS ; POINT TO CB MNEMONIC TABLE
  582.     OR    AL,AL        ; 5 BYTES?
  583.     JZ    DSM55        ; YES - LOAD OP-CODE AND SEARCH FOR MNEMONIC
  584.  
  585.     DEC    AL        ; NO - 6 BYTES?
  586.     MOV    B_TAB,OFFSET DD1_BYTES ; (POINT TO DD1 BYTE TABLE)
  587.     MOV    BX,OFFSET DD1_STRINGS ; (POINT TO DD1 MNEMONIC TABLE)
  588.     JZ    DSM55        ; YES - LOAD OP-CODE AND SEARCH FOR MNEMONIC
  589.  
  590.     DEC    AL        ; NO - 7 BYTES?
  591.     MOV    B_TAB,OFFSET ED_BYTES ; (POINT TO ED BYTE TABLE)
  592.     MOV    BX,OFFSET ED_STRINGS ; (POINT TO ED MNEMONIC TABLE)
  593.     JZ    DSM55        ; YES - LOAD OP-CODE AND SEARCH FOR MNEMONIC
  594.  
  595.     MOV    B_TAB,OFFSET FD1_BYTES ; POINT TO FD1 BYTE TABLE
  596.     MOV    BX,OFFSET FD1_STRINGS ; POINT TO FD1 MNEMONIC TABLE
  597.     JMP    DSM55        ; LOAD OP-CODE AND SEARCH FOR MNEMONIC
  598.  
  599. DSM40:
  600.     MOV    DSKPTR,OFFSET DSKBUF ; INITIALIZE DISK BUFFER POINTER
  601.     MOV    DSKCNT,0     ; CLEAR DISK BUFFER COUNTER
  602.     DEC    MEMCNT        ; RETARD MEMORY COUNTER - LAST BYTE?
  603.     JNZ    DSM45        ; NO - RETARD AGAIN
  604.  
  605.     JMP    DSM175        ; YES - WRITE "END" TO OUTPUT FILE
  606.  
  607. DSM45:
  608.     DEC    MEMCNT        ; RETARD MEMORY COUNTER - LAST BYTE?
  609.     JNZ    DSM50        ; NO - ADVANCE FETCH COUNTER
  610.  
  611.     JMP    DSM175        ; YES - WRITE "END" TO OUTPUT FILE
  612.  
  613. DSM50:
  614.     INC    FCHCNT        ; ADVANCE FETCH COUNTER
  615.     INC    MEMPTR        ; ADVANCE MEMORY BUFFER POINTER
  616.     MOV    BX,MEMPTR    ; LOAD MEMORY BUFFER POINTER
  617.     MOV    CL,[BX]        ; LOAD OP-CODE
  618.     PUSH    CX        ; SAVE OP-CODE
  619.     MOV    B_TAB,OFFSET DD2_BYTES ; POINT TO DD2 BYTE TABLE
  620.     MOV    BX,OFFSET DD2_STRINGS ; POINT TO DD2 MNEMONIC TABLE
  621.     CMP    AL,9        ; 9 BYTES?
  622.     JZ    DSM55        ; YES - LOAD OP-CODE AND SEARCH FOR MNEMONIC
  623.  
  624.     MOV    B_TAB,OFFSET FD2_BYTES ; NO - POINT TO FD2 BYTE TABLE
  625.     MOV    BX,OFFSET FD2_STRINGS ; POINT TO FD2 MNEMONIC TABLE
  626.  
  627. DSM55:
  628.     POP    CX        ; LOAD OPCODE
  629.     INC    CX        ; ADJUST
  630.  
  631. DSM60:
  632.     DEC    CX        ; RETARD OPCODE - DONE?
  633.     JZ    DSM70        ; YES - WRITE TAB TO DISK BUFFER
  634.  
  635. DSM65:
  636.     MOV    AL,[BX]        ; NO - LOAD NEXT CHARACTER
  637.     INC    BX        ; ADVANCE MNEMONIC TABLE POINTER
  638.     CMP    AL,RS        ; RS?
  639.     JZ    DSM60        ; YES - RETARD OPCODE AND TEST FOR DONE
  640.  
  641.     JMP    DSM65        ; NO - TEST NEXT CHARACTER FOR RS
  642.  
  643. DSM70:
  644.     PUSH    BX        ; SAVE MNEMONIC POINTER
  645.     MOV    BX,DSKPTR    ; LOAD DISK BUFFER POINTER
  646.     MOV    BYTE PTR[BX],TAB; WRITE TAB TO DISK BUFFER
  647.     INC    BX        ; ADVANCE DISK BUFFER POINTER
  648.     INC    DSKCNT        ; ADVANCE DISK BUFFER COUNTER
  649.     MOV    DI,BX        ;
  650.     POP    BX        ; RESTORE MNEMONIC POINTER
  651.  
  652. DSM75:
  653.     MOV    AL,[BX]        ; LOAD MNEMONIC CHARACTER
  654.     CMP    AL,RS        ; RS?
  655.     JZ    DSM80        ; YES - STORE DISK BUFFER POINTER
  656.  
  657.     MOV    [DI],AL        ; NO - WRITE CHARACTER TO DISK BUFFER
  658.     INC    DI        ; ADVANCE DISK BUFFER POINTER
  659.     INC    BX        ; ADVANCE MNEMONIC POINTER
  660.     INC    DSKCNT        ; ADVANCE DISK BUFFER COUNTER
  661.     JMP    DSM75        ; TEST NEXT CHARACTER FOR RS
  662.  
  663. DSM80:
  664.     XCHG    BX,DI        ; LOAD DISK BUFFER POINTER IN BX
  665.     MOV    DSKPTR,BX    ; STORE DISK BUFFER POINTER
  666.     MOV    BX,MEMPTR    ; LOAD MEMORY BUFFER POINTER
  667.     MOV    CH,0        ;
  668.     MOV    CL,[BX]        ; LOAD OP-CODE
  669.     INC    BX        ; ADVANCE MEMORY BUFFER POINTER
  670.     MOV    MEMPTR,BX    ; STORE
  671.     CALL    OPBYTE        ; COMPUTE NUMBER OF BYTES FOR THIS OPCODE
  672.     MOV    AL,CL        ; LOAD NUMBER OF BYTES
  673.     CMP    AL,4        ; LESS THAN 4 BYTES?
  674.     JC    DSM85        ; YES - TEST FOR ZERO BYTES
  675.  
  676.     JMP    DSM40        ; NO - EXECUTE THIRD FETCH
  677.  
  678. DSM85:
  679.     OR    AL,AL        ; ZERO BYTES?
  680.     JNZ    DSM90        ; NO - TEST FOR ONE BYTE
  681.  
  682.     MOV    BX,MEMPTR    ; YES - LOAD MEMORY BUFFER POINTER
  683.     DEC    BX        ; ADJUST
  684.     MOV    AL,[BX]        ; LOAD "OP-CODE"
  685.     MOV    BX,DSKPTR    ; LOAD DISK BUFFER POINTER
  686.     CALL    FINDZ        ; FIND LEADING ZERO IN DISK BUFFER
  687.     CALL    EXPAND        ; WRITE "OP-CODE" TO DISK BUFFER
  688.     JMP    DSM145        ; WRITE "TAB,;,CR,LF" TO OUTPUT FILE
  689.  
  690. DSM90:
  691.     DEC    AL        ; ONE BYTE?
  692.     JNZ    DSM95        ; NO - TEST FOR TWO BYTES
  693.  
  694.     JMP    DSM145        ; YES - WRITE "TAB,;,CR,LF" TO OUTPUT FILE
  695.  
  696. DSM95:
  697.     DEC    AL        ; TWO BYTES?
  698.     JNZ    DSM115        ; NO - JUMP TO THREE BYTE HANDLER
  699.  
  700.     MOV    BX,MEMPTR    ; YES - LOAD MEMORY BUFFER POINTER
  701.     DEC    BX        ;
  702.     DEC    BX        ; POINT TO POSSIBLE DISPLACEMENT
  703.     CMP    FCHCNT,3     ; 3 FETCH INSTRUCTION?
  704.     JE    DSM110        ; YES - LOAD IMMEDIATE DATA
  705.  
  706.     INC    BX        ; NO - POINT TO OP-CODE
  707.     MOV    AL,[BX]        ; LOAD OPCODE
  708.     AND    AL,11000111B    ; POSSIBLE RELATIVE JUMP?
  709.     JNZ    DSM100        ; NO - LOAD IMMEDIATE DATA
  710.  
  711.     MOV    AL,[BX]        ; YES - LOAD OP-CODE
  712.     AND    AL,00110000B    ; RELATIVE JUMP?
  713.     JZ    DSM100        ; NO - LOAD IMMEDIATE DATA
  714.  
  715.     INC    BX        ; YES - POINT TO RELATIVE OFFSET
  716.     MOV    AL,[BX]        ; LOAD RELATIVE OFFSET
  717.     CBW            ; SIGN EXTEND RELATIVE OFFSET
  718.     MOV    DX,CURADD    ; LOAD CURRENT ADDRESS
  719.     ADD    DX,2        ; ADJUST
  720.     ADD    DX,AX        ; COMPUTE TARGET ADDRESS
  721.     PUSH    DX        ; STORE LOW TARGET ADDRESS
  722.     MOV    AL,DH        ; LOAD HIGH TARGET ADDRESS
  723.     INC    MEMPTR        ; ADVANCE MEMORY POINTER
  724.     DEC    MEMCNT        ; RETARD MEMORY COUNTER
  725.     JMP    DSM135        ; WRITE TARGET ADDRESS TO DISK BUFFER
  726.  
  727. DSM100:
  728.     DEC    MEMCNT        ; NO - RETARD MEMORY BUFFER COUNTER - LAST BYTE?
  729.     JNZ    DSM105        ; NO - WRITE ADDRESS TO DISK BUFFER
  730.  
  731.     JMP    DSM175        ; YES - WRITE "END" TO OUTPUT FILE
  732.  
  733. DSM105:
  734.     MOV    BX,MEMPTR    ; LOAD MEMORY BUFFER POINTER
  735.     INC    MEMPTR        ; ADVANCE MEMORY BUFFER POINTER
  736.  
  737. DSM110:
  738.     MOV    AL,[BX]        ; LOAD IMMEDIATE DATA
  739.     MOV    BX,DSKPTR    ; LOAD DISK BUFFER POINTER
  740.     CALL    FINDZ        ; FIND LEADING ZERO IN DISK BUFFER
  741.     CALL    EXPAND        ; CONVERT DATA TO ASCII IN DISK BUFFER
  742.     JMP    DSM145        ; WRITE INSTRUCTION ADDRESS TO DISK BUFFER
  743.  
  744. DSM115:
  745.     CMP    FCHCNT,2     ; 2 FETCH INSTRUCTION?
  746.     JNE    DSM120        ; NO - HANDLE APPROPRIATELY
  747.  
  748.     MOV    BX,MEMPTR    ; YES - LOAD MEMORY BUFFER POINTER
  749.     DEC    BX        ; POINT TO OP-CODE
  750.     MOV    AL,[BX]        ; LOAD OPCODE
  751.     CMP    AL,36H        ; OP-CODE 36?
  752.     JE    DSM140        ; YES - HANDLE APPROPRIATELY
  753.  
  754. DSM120:
  755.     MOV    BX,MEMCNT    ; NO - LOAD MEMORY BUFFER COUNTER
  756.     DEC    BX        ; RETARD MEMORY BUFFER COUNTER - LAST BYTE?
  757.     JNZ    DSM125        ; NO - RETARD AGAIN
  758.  
  759.     JMP    DSM175        ; YES - WRITE "END" TO OUTPUT FILE
  760.  
  761. DSM125:
  762.     DEC    BX        ; RETARD MEMORY BUFFER COUNTER - LAST BYTE?
  763.     MOV    MEMCNT,BX    ; (STORE)
  764.     JNZ    DSM130        ; NO - WRITE ADDRESS TO DISK BUFFER
  765.  
  766.     JMP    DSM175        ; YES - WRITE "END" TO OUTPUT FILE
  767.  
  768. DSM130:
  769.     MOV    BX,MEMPTR    ; LOAD MEMORY BUFFER POINTER
  770.     MOV    AL,[BX]        ; LOAD LOW ADDRESS
  771.     PUSH    AX        ; STORE
  772.     INC    BX        ; ADVANCE MEMORY BUFFER POINTER
  773.     MOV    AL,[BX]        ; LOAD HIGH ADDRESS
  774.     INC    BX        ; ADVANCE MEMORY BUFFER POINTER
  775.     MOV    MEMPTR,BX    ; STORE
  776.  
  777. DSM135:
  778.     MOV    BX,DSKPTR    ; LOAD DISK BUFFER POINTER
  779.     CALL    FINDZ        ; FIND LEADING ZERO IN DISK BUFFER
  780.     CALL    EXPAND        ; CONVERT HIGH ADDRESS TO ASCII IN DISK BUFFER
  781.     POP    AX        ; RESTORE LOW ADDRESS
  782.     CALL    EXPAND        ; CONVERT LOW ADDRESS TO ASCII IN DISK BUFFER
  783.     JMP    DSM145        ; WRITE INSTRUCTION ADDRESS TO DISK BUFFER
  784.  
  785. DSM140:
  786.     MOV    BX,MEMPTR    ; LOAD MEMORY BUFFER POINTER
  787.     INC    MEMPTR        ; ADVANCE MEMORY BUFFER POINTER
  788.     MOV    AL,[BX]        ; LOAD DISPLACEMENT
  789.     MOV    BX,DSKPTR    ; LOAD DISK BUFFER POINTER
  790.     CALL    FINDZ        ; FIND IMMEDIATE DATA LEADING ZERO
  791.     PUSH    BX        ; SAVE IMMEDIATE DATA LEADING ZERO POINTER
  792.     DEC    BX        ; ADJUST LEADING ZERO POINTER
  793.     CALL    FINDZ        ; FIND DISPLACEMENT LEADING ZERO
  794.     CALL    EXPAND        ; WRITE DISPLACEMENT TO DISK BUFFER
  795.     MOV    BX,MEMPTR    ; LOAD MEMORY BUFFER POINTER
  796.     INC    MEMPTR        ; ADVANCE MEMORY BUFFER POINTER
  797.     MOV    AL,[BX]        ; LOAD IMMEDIATE DATA
  798.     POP    BX        ; LOAD IMMEDIATE DATA LEADING ZERO POINTER
  799.     CALL    EXPAND        ; WRITE IMMEDIATE DATA TO DISK BUFFER
  800.  
  801. DSM145:
  802.     MOV    CX,DSKCNT    ; LOAD DISK BUFFER COUNTER
  803.     MOV    BX,OFFSET DSKBUF; POINT TO DISK BUFFER
  804.  
  805. DSM150:
  806.     MOV    CH,0        ; CLEAR CHARACTER COUNTER
  807.  
  808. DSM155:
  809.     MOV    AL,[BX]        ; LOAD NEXT CHARACTER
  810.     INC    BX        ; ADVANCE DISK BUFFER POINTER
  811.     INC    CH        ; ADVANCE CHARACTER COUNTER
  812.     DEC    CL        ; LAST CHARACTER?
  813.     JZ    DSM160        ; YES - DECIDE WHETHER ONE OR TWO TABS
  814.  
  815.     CMP    AL,TAB        ; NO - TAB?
  816.     JZ    DSM150        ; YES - CLEAR CHARACTER COUNTER
  817.  
  818.     JMP    DSM155        ; NO - TEST NEXT CHARACTER
  819.  
  820. DSM160:
  821.     MOV    BX,DSKPTR    ; LOAD DISK BUFFER POINTER
  822.     MOV    AL,8        ;
  823.     CMP    AL,CH        ; LESS THAN EIGHT CHARACTERS SINCE LAST TAB?
  824.     JBE    DSM165        ; NO - WRITE ONE TAB TO DISK BUFFER
  825.  
  826.     MOV    BYTE PTR[BX],TAB; WRITE TAB TO DISK BUFFER
  827.     INC    BX        ; ADVANCE DISK BUFFER POINTER
  828.     INC    DSKCNT        ; ADVANCE DISK BUFFER COUNTER
  829.  
  830. DSM165:
  831.     MOV    BYTE PTR[BX],TAB; WRITE TAB TO DISK BUFFER
  832.     INC    BX        ; ADVANCE DISK BUFFER POINTER
  833.     MOV    BYTE PTR[BX],';'; WRITE ";" TO DISK BUFFER
  834.     INC    BX        ; ADVANCE DISK BUFFER POINTER
  835.     MOV    BYTE PTR[BX],' '; WRITE " " TO DISK BUFFER
  836.     INC    BX        ; ADVANCE DISK BUFFER POINTER
  837.     MOV    DX,CURADD    ; LOAD CURRENT ADDRESS
  838.     MOV    AL,DH        ; LOAD HIGH ADDRESS
  839.     CALL    EXPAND        ; WRITE TO DISK BUFFER
  840.     MOV    AL,DL        ; LOAD LOW ADDRESS
  841.     CALL    EXPAND        ; WRITE TO DISK BUFFER
  842.     MOV    BYTE PTR[BX],CR ; WRITE <CR> TO DISK BUFFER
  843.     INC    BX        ; ADVANCE DISK BUFFER POINTER
  844.     MOV    BYTE PTR[BX],LF ; WRITE LINE FEED TO DISK BUFFER
  845.     ADD    DSKCNT,9     ; ADD TAB AND TERMINATOR COUNT
  846.     DISKWR    DSKCNT        ; WRITE TO DISK FILE - ERROR?
  847.  
  848.     CMP    AX,DSKCNT    ; NO - ALL BYTES WRITTEN?
  849.     JZ    DSM170        ; YES - CONTINUE
  850.  
  851.     MOV    AX,0        ; NO - LOAD ERROR NUMBER
  852.     JMP    DSKERR        ; DISPLAY ERROR
  853.  
  854. DSM170:
  855.     JMP    DSM05        ; CONTINUE
  856.  
  857. DSM175:
  858.     MOV    BX,OFFSET MSGEND; POINT TO "END" STRING
  859.     MOV    DI,OFFSET DSKBUF; POINT TO DISK BUFFER
  860.     MOV    CX,LENEND    ; LOAD MESSAGE LENGTH
  861.  
  862. DSM180:
  863.     MOV    AL,[BX]        ; LOAD FROM STRING
  864.     MOV    [DI],AL        ; WRITE TO DISK BUFFER
  865.     INC    BX        ; ADVANCE STRING POINTER
  866.     INC    DI        ; ADVANCE DISK BUFFER POINTER
  867.     DEC    CX        ; RETARD COUNTER - DONE?
  868.     JNZ    DSM180        ; NO - CONTINUE
  869.  
  870.     DISKWR    LENEND        ; YES - WRITE TO DISK - ERROR?
  871.  
  872.     CMP    AX,LENEND    ; NO - ALL BYTES WRITTEN?
  873.     JZ    DSM185        ; YES - DONE
  874.  
  875.     MOV    AX,0        ; NO - LOAD ERROR NUMBER
  876.     JMP    DSKERR        ; NO - DISPLAY ERROR
  877.  
  878. DSM185:
  879.     RET            ; DONE
  880.  
  881. DSM    ENDP            ;
  882.  
  883.  
  884.  
  885. ; ****************************************************************
  886. ; **                                **
  887. ; **            CLOSE OUTPUT FILE            **
  888. ; **                                **
  889. ; ****************************************************************
  890.  
  891. CLOSWR    PROC    NEAR        ;
  892.  
  893.     MOV    AH,CLOSE     ; LOAD CLOSE FILE COMMAND
  894.     MOV    BX,WRHAND    ; LOAD OUTPUT FILE HANDLE
  895.     INT    DOSFUNC        ; CLOSE THE OUTPUT FILE - ERROR?
  896.     JNC    CLOS05        ; NO - DONE
  897.  
  898.     JMP    DSKERR        ; YES - DISPLAY ERROR
  899.  
  900. CLOS05:
  901.     RET            ;
  902.  
  903. CLOSWR    ENDP
  904.  
  905.  
  906. SBRS    PROC    NEAR        ;
  907.  
  908. ; ****************************************************************
  909. ; **                                **
  910. ; **              SUBROUTINES                **
  911. ; **                                **
  912. ; ****************************************************************
  913.  
  914. ; ****************************************************************
  915. ; **    FUNCTION: CONVERT ASCII TO HEXADECIMAL            **
  916. ; **    ENTRY: ASCII REPRESENTATION OF VALID HEX NUMBER IN AL    **
  917. ; **    USES: AL                         **
  918. ; **    EXIT: HEX NUMBER IN AL                    **
  919. ; **    CALLS: NONE                        **
  920. ; ****************************************************************
  921.  
  922. ASCHEX:
  923.     CMP    AL,'9'+1     ; IS IT LESS THAN OR EQUAL TO 9?
  924.     JLE    ASC05        ; YES - JUMP PAST HEX CONVERSION
  925.  
  926.     ADD    AL,9        ; NO - ADD HEX OFFSET
  927.  
  928. ASC05:
  929.     AND    AL,0FH        ; STRIP ASCII BIAS
  930.     RET            ;
  931.  
  932.  
  933. ; ****************************************************************
  934. ; **    FUNCTION: CONVERT 8 BIT VALUE TO TWO ASCII CHARACTERS    **
  935. ; **         AND WRITE THEM TO MEMORY            **
  936. ; **    ENTRY: A=8 BIT VALUE TO BE CONVERTED            **
  937. ; **          BX=ADDRESS OF MEMORY TO BE WRITTEN TO        **
  938. ; **    USES: BX                         **
  939. ; **    EXIT: BX=ADDRESS OF LAST CHARACTER WITTEN + 1        **
  940. ; **    CALLS: HEXASC                        **
  941. ; ****************************************************************
  942.  
  943. EXPAND:
  944.     PUSHF            ;
  945.     PUSH    AX        ;
  946.     PUSH    CX        ;
  947.     PUSH    AX        ; SAVE BYTE TO BE EXPANDED
  948.     MOV    CL,4        ;
  949.     ROL    AL,CL        ; EXCHANGE NIBBLES
  950.     CALL    HEXASC        ; CONVERT HEX TO ASCII
  951.     MOV    [BX],AL        ; WRITE TO MEMORY
  952.     INC    BX        ; ADVANCE MEMORY POINTER
  953.     POP    AX        ; RESTORE ORIGINAL BYTE
  954.     CALL    HEXASC        ; CONVERT HEX TO ASCII
  955.     MOV    [BX],AL        ; WRITE TO MEMORY
  956.     INC    BX        ; ADVANCE MEMORY POINTER
  957.     POP    CX        ;
  958.     POP    AX        ;
  959.     POPF            ;
  960.     RET            ;
  961.  
  962.  
  963.  
  964. ; ****************************************************************
  965. ; **    FUNCTION: FIND FIRST ZERO SEARCHING BACKWARDS IN MEMORY **
  966. ; **    ENTRY: BX=START ADDRESS FOR SEARCH            **
  967. ; **         (NOTE: DOES NOT TEST THIS ADDRESS!)        **
  968. ; **    USES: BX                         **
  969. ; **    EXIT: BX=ADDRESS OF ZERO + 1                **
  970. ; **    CALLS: NONE                        **
  971. ; ****************************************************************
  972.  
  973. FINDZ:
  974.     PUSH    AX        ; SAVE AX
  975.     MOV    AL,'0'        ; LOAD COMPARISON VALUE
  976.  
  977. FZ_05:
  978.     DEC    BX        ; RETARD POINTER
  979.     CMP    AL,[BX]        ; ZERO?
  980.     JNE    FZ_05        ; NO - CONTINUE
  981.  
  982.     INC    BX        ; YES - ADJUST POINTER
  983.     POP    AX        ; RESTORE AX
  984.     RET            ;
  985.  
  986.  
  987.  
  988. ; ****************************************************************
  989. ; **    FUNCTION: CONVERT 4 BIT VALUE TO ASCII            **
  990. ; **    ENTRY: LOWER NIBBLE OF A=VALUE TO BE CONVERTED        **
  991. ; **    USES: AL                         **
  992. ; **    EXIT: A=ASCII CHARACTER                    **
  993. ; **    CALLS: NONE                        **
  994. ; ****************************************************************
  995.  
  996. HEXASC:
  997.     AND    AL,0FH        ; ISOLATE LOWER NIBBLE
  998.     CMP    AL,9+1        ; IS IT LESS THAN OR EQUAL TO 9?
  999.     JL    HXAS05        ; YES - JUMP PAST HEX CONVERSION
  1000.  
  1001.     SUB    AL,9        ; NO - SUBTRACT HEX OFFSET
  1002.     OR    AL,40H        ; COMBINE WITH HEX ASCII BIAS
  1003.     RET            ;
  1004.  
  1005. HXAS05:
  1006.     OR    AL,30H        ; COMBINE WITH DECIMAL ASCII BIAS
  1007.     RET            ;
  1008.  
  1009.  
  1010. ; ****************************************************************
  1011. ; **    FUNCTION: WRITE MESSAGE TO STANDARD OUTPUT        **
  1012. ; **    ENTRY: DX=START ADDRESS OF MESSAGE STRING        **
  1013. ; **    USES: ???                        **
  1014. ; **    EXIT: NONE                        **
  1015. ; **    CALLS: NONE                        **
  1016. ; ****************************************************************
  1017.  
  1018. MSGCO:
  1019.     MOV    AH,PR_STR    ; LOAD PRINT STRING COMMAND
  1020.     INT    DOSFUNC        ; PRINT STRING
  1021.     RET            ; DONE
  1022.  
  1023.  
  1024. ; ****************************************************************
  1025. ; **    FUNCTION: COMPUTE NUMBER OF BYTES FOR OP-CODES        **
  1026. ; **    ENTRY:    CX=OPCODE                    **
  1027. ; **    USES: CL                         **
  1028. ; **    EXIT: NUMBER OF BYTES IN CL                **
  1029. ; **    CALLS: NONE                        **
  1030. ; ****************************************************************
  1031.  
  1032. OPBYTE:
  1033.     PUSH    BX        ; SAVE BX
  1034.     MOV    BX,B_TAB     ; POINT TO BYTES TABLE
  1035.     ADD    BX,CX        ; ADD OFFSET
  1036.     MOV    CL,[BX]        ; LOAD NUMBER OF BYTES
  1037.     POP    BX        ; RESTORE BX
  1038.     RET            ;
  1039.  
  1040. ; ****************************************************************
  1041. ; **    FUNCTION: WRITE ORG STRING TO DISK            **
  1042. ; **    ENTRY: NONE                        **
  1043. ; **    USES: ALL                        **
  1044. ; **    EXIT: ORG STRING WRITTEN TO DISK             **
  1045. ; **    CALLS: EXPAND                        **
  1046. ; ****************************************************************
  1047.  
  1048. ORGWR:
  1049.     MOV    DSKCNT,0     ; CLEAR DISK BUFFER COUNTER
  1050.     MOV    CX,LENORG    ; LOAD "ORG" MESSAGE LENGTH
  1051.     MOV    DI,OFFSET MSGORG; POINT TO "ORG" STRING
  1052.     MOV    BX,OFFSET DSKBUF; POINT TO DISK BUFFER
  1053.  
  1054. ORGW05:
  1055.     MOV    AL,[DI]        ; LOAD NEXT CHARACTER OF "ORG" STRING
  1056.     MOV    [BX],AL        ; WRITE IT TO DISK BUFFER
  1057.     INC    DI        ;
  1058.     INC    BX        ; ADVANCE POINTERS
  1059.     INC    DSKCNT        ; ADVANCE DISK BUFFER COUNTER
  1060.     DEC    CX        ; DECREMENT COUNTER - DONE?
  1061.     JNZ    ORGW05        ; NO - CONTINUE
  1062.  
  1063.     MOV    DSKPTR,BX    ; YES - STORE DISK BUFFER POINTER
  1064.     MOV    DX,OFFSET MEMBUF; LOAD MEMORY BUFFER ADDRESS
  1065.     MOV    BX,MEMPTR    ; LOAD MEMORY BUFFER POINTER
  1066.     MOV    AL,BL        ; LOAD LOW MEMORY BUFFER POINTER
  1067.     SUB    AL,DL        ; COMPUTE LOW ORG ADDRESS
  1068.     PUSH    AX        ; STORE
  1069.     MOV    AL,BH        ; LOAD HIGH MEMORY BUFFER POINTER
  1070.     SBB    AL,DH        ; COMPUTE HIGH ORG ADDRESS
  1071.     MOV    BX,DSKPTR    ; LOAD DISK BUFFER POINTER
  1072.     CALL    EXPAND        ; WRITE TO DISK BUFFER
  1073.     POP    AX        ; LOAD LOW ORG ADDRESS
  1074.     CALL    EXPAND        ; WRITE TO DISK BUFFER
  1075.     MOV    BYTE PTR[BX],'H'; WRITE HEX INDICATOR TO DISK BUFFER
  1076.     INC    BX        ; ADVANCE POINTER
  1077.     MOV    BYTE PTR[BX],CR ; WRITE <CR> TO DISK BUFFER
  1078.     INC    BX        ; ADVANCE POINTER
  1079.     MOV    BYTE PTR[BX],LF ; WRITE LINE FEED TO DISK BUFFER
  1080.     ADD    DSKCNT,7     ; ADJUST DISK BUFFER COUNTER
  1081.     DISKWR    DSKCNT        ; WRITE DKSCNT BYTES TO DISK - ERROR?
  1082.  
  1083.     CMP    AX,DSKCNT    ; NO - ALL BYTES WRITTEN?
  1084.     JZ    ORGW10        ; YES - DONE
  1085.  
  1086.     POP    AX        ; NO - RESTORE STACK
  1087.     MOV    AX,0        ; LOAD ERROR NUMBER
  1088.     JMP    DSKERR        ; DISPLAY ERROR
  1089.  
  1090. ORGW10:
  1091.     RET            ; DONE
  1092.  
  1093.  
  1094.  
  1095. ; ****************************************************************
  1096. ; **    FUNCTION: CONVERT TWO ASCII CHARACTERS TO 8 BIT NUMBER    **
  1097. ; **    ENTRY: BX=START ADDRESS OF VALID ASCII HEX CHARACTERS    **
  1098. ; **    USES: AL, BX                        **
  1099. ; **    EXIT: A;=8 BIT NUMBER, BX=BX+2                **
  1100. ; **    CALLS: ASCHEX                        **
  1101. ; ****************************************************************
  1102.  
  1103. PACK:
  1104.     PUSH    CX        ; SAVE CX
  1105.     MOV    AL,[BX]        ; LOAD CHARACTER
  1106.     CALL    ASCHEX        ; CONVERT ASCII CHARACTER TO HEX
  1107.     MOV    CL,4        ;
  1108.     ROL    AL,CL        ; EXCHANGE NIBBLES
  1109.     MOV    CH,AL        ; STORE
  1110.     INC    BX        ; POINT TO NEXT CHARACTER
  1111.     MOV    AL,[BX]        ; LOAD NEXT CHARACTER
  1112.     CALL    ASCHEX        ; CONVERT ASCII CHARACTER TO HEX
  1113.     OR    AL,CH        ; COMBINE NIBBLES
  1114.     INC    BX        ; POINT TO NEXT CHARACTER
  1115.     ADD    CHKACC,AL    ; UPDATE CHECKSUM ACCUMULATOR
  1116.     POP    CX        ; RESTORE CX
  1117.     RET            ;
  1118.  
  1119. SBRS    ENDP            ;
  1120.  
  1121.  
  1122. ERRHAN    PROC    FAR
  1123.  
  1124. ; ****************************************************************
  1125. ; **                                **
  1126. ; **            DISK ERROR HANDLER            **
  1127. ; **                                **
  1128. ; ****************************************************************
  1129.  
  1130. DSKERR:
  1131.     MOV    DX,OFFSET MDISK0; POINT TO DISK ERROR MESSAGE 0
  1132.     OR    AX,AX        ; ERROR 0?
  1133.     JZ    MISERR        ; YES - DISPLAY ERROR MESSAGE
  1134.  
  1135.     MOV    DX,OFFSET MDISK1; NO - POINT TO DISK ERROR MESSAGE 1
  1136.     DEC    AX        ; ERROR 1?
  1137.     JZ    MISERR        ; YES - DISPLAY ERROR MESSAGE
  1138.  
  1139.     MOV    DX,OFFSET MDISK2; NO - POINT TO DISK ERROR MESSAGE 2
  1140.     DEC    AX        ; ERROR 2?
  1141.     JZ    MISERR        ; YES - DISPLAY ERROR MESSAGE
  1142.  
  1143.     MOV    DX,OFFSET MDISK3; NO - POINT TO DISK ERROR MESSAGE 3
  1144.     DEC    AX        ; ERROR 3?
  1145.     JZ    MISERR        ; YES - DISPLAY ERROR MESSAGE
  1146.  
  1147.     MOV    DX,OFFSET MDISK4; NO - POINT TO DISK ERROR MESSAGE 4
  1148.     DEC    AX        ; ERROR 4?
  1149.     JZ    MISERR        ; YES - DISPLAY ERROR MESSAGE
  1150.  
  1151.     MOV    DX,OFFSET MDISK5; NO - POINT TO DISK ERROR MESSAGE 5
  1152.     DEC    AX        ; ERROR 5?
  1153.     JZ    MISERR        ; YES - DISPLAY ERROR MESSAGE
  1154.  
  1155.     MOV    DX,OFFSET MDISK6; NO - POINT TO DISK ERROR MESSAGE 6
  1156.     DEC    AX        ; ERROR 6?
  1157.     JZ    MISERR        ; YES - DISPLAY ERROR MESSAGE
  1158.  
  1159.     MOV    DX,OFFSET MUKNOW; NO - POINT TO UNKNOWN DISK ERROR MESSAGE
  1160.     JMP    MISERR        ; DISPLAY ERROR MESSAGE
  1161.  
  1162.  
  1163.  
  1164. ; ****************************************************************
  1165. ; **                                **
  1166. ; **            MISCELANEOUS ERROR HANDLER            **
  1167. ; **                                **
  1168. ; ****************************************************************
  1169.  
  1170. MISERR:
  1171.     CALL    MSGCO        ; WRITE MESSAGE TO STANDARD OUTPUT
  1172.     POP    AX        ; RESTORE STACK
  1173.     RET        
  1174.  
  1175. ERRHAN    ENDP            ;
  1176.  
  1177. CODE    ENDS            ;
  1178.  
  1179.     END    DASMZ80        ;
  1180.  
  1181.