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

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