home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 15 / CDACTUAL15.iso / cdactual / program / asm / RE_SOURC.ZIP / RE-SOURC.ASM < prev    next >
Encoding:
Assembly Source File  |  1989-01-05  |  117.9 KB  |  5,363 lines

  1. ;«LM0»RE-SOURCE DISASSEMBLER - modified by JIR 7/87 - 11/88
  2.  
  3. ;Disassembly starts ≈ page 43.
  4. ;Commands, file handling in first half, except Symbol stuff at ≈ page 67. 
  5.  
  6. ;All label addrs stored per pcntr, displayed as pcntr + curorg.
  7. ;Hard-coded addrs found in B cmd stored at coded addr - curorg.
  8.  
  9.     PAGE    192,132
  10. CSEG    segment byte public 'CODE'
  11.     assume    cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG
  12.  
  13.     DB    256 DUP(?)
  14.  
  15. bel        equ    7
  16. tab        equ    9
  17. cr        equ    0Dh
  18. lf        equ    0Ah
  19. initlcnt     equ    20    ;lines displayed initially
  20. DefaultDTA    equ    80h    ;in PSP, used as buffer for disk read/writes
  21. symbas        equ    offset ctlbas + 3072 ;base of 16K symbol (label) table
  22. rembas        equ    symbas + 16384         ;base of 24K remark table
  23.  
  24. ;The scheme above makes the .COM file shorter.  MEMCHK routine makes sure
  25. ; there's enough room for these.
  26.  
  27. start    proc    near
  28.     jmp    memchk
  29.  
  30. banner    db    'RE-SOURCE by C.Derouen,  revised by J. Rebold  '
  31.     db    'Dec 88',cr,lf,'$'
  32.  
  33. ;CHECK FOR DOS V2.0+
  34. memchk:    mov    ah,30h            ;get DOS version
  35.     int    21h
  36.     cmp    al,2
  37.     jae    good_vers
  38.     mov    dx,offset bad_vers
  39.     mov    ah,9
  40.     int    21h
  41.     int    20h            ; Exit
  42.  
  43. bad_vers db    cr,lf,7,'DOS 2.0+ required.  Sorry.$'
  44.  
  45. good_vers:
  46. ;ALLOCATE RAM FOR BUFFERS & TARGET PGM
  47.     mov    ax,cs
  48.     mov    es,ax            ;seg addr of block to change
  49.     mov    bx,2000h        ;allocate 128K
  50.     mov    ah,4Ah            ;modify allocated memory block
  51.     int    21h
  52.     jc    L001
  53.     jmp    goodmem
  54. L001:    cmp    al,8
  55.     jz    notnuf
  56.     cmp    al,7
  57.     jnz    invalid
  58.     mov    dx,offset destro
  59.     jmp    short prtmsg
  60.  
  61. invalid: mov    dx,offset invmsg
  62.     jmp    short prtmsg
  63.  
  64. notnuf:    mov    dx,offset nomem        ;location of string to print
  65. prtmsg:    mov    ah,9            ;print string
  66.     int    21h
  67.     mov    ah,4Ch            ;set Errorlevel & exit
  68.     mov    al,08h            ;Errorlevel=8, failure
  69.     int    21h
  70.  
  71. nomem    db    cr,lf,7,'Not enough memory - program aborted$'
  72. destro    db    cr,lf,7,'DOS mem ctl blocks destroyed - cannot allocate RAM$'
  73. invmsg    db    cr,lf,7,'Invalid MCB addr or other screwup - pgm aborted$'
  74.  
  75. goodmem:
  76.     cli
  77.     mov    ax,ds
  78.     mov    ss,ax            ;SS=DS
  79.     mov    sp,offset stak        ;machine stack now in buffer @ end pgm
  80.     sti
  81.     mov    bx,rembas        ;EQU symbas + 16K
  82.     mov    remtbl,bx        ;used from now on - start of REM table
  83.     mov    dx,offset banner    ;addr of intro message
  84.     mov    ah,9            ;print string
  85.     int    21h
  86.     call    ClearTables
  87.     mov    al,cs:byte ptr [80h]    ;length of cmd line incl the CR
  88.     or    al,al
  89.     jz    fstcmd
  90. ;There is something on the command line
  91.     call    prtstr
  92.     db    cr,lf,'Reading All Files of ',0
  93.     mov    di,offset FileString
  94.     mov    bx,81h            ;point to 1st char of cmd line
  95. BlnkLoop:
  96.     mov    al,[bx]
  97.     cmp    al,' '
  98.     jnz    FirstChar
  99.     inc    bx
  100.     jmp    short BlnkLoop
  101. FirstChar:
  102.     call    MoveField
  103.     mov    DotPtr,di
  104.     mov    byte ptr [di],'.'
  105.     mov    bx,offset FileString
  106. ZLoop:    mov    al,[bx]
  107.     or    al,al
  108.     jz    ZLoopDone
  109.     call    typech
  110.     inc    bx
  111.     jmp    short ZLoop
  112.  
  113. ZLoopDone:
  114.     call    LoadAll
  115.     jmp    short fstcmd
  116.  
  117. Restart:
  118.     call    ClearTables
  119. fstcmd:    call    prtstr
  120.     db    cr,lf,'Enter ? for Stats, H for Help (or hit F1)',cr,lf,cr,lf,0
  121.  
  122. nxcmd:    mov    hlpflg,0        ;cursor keys not to show help
  123. hlpcmd:    mov    wfiflg,0        ;don't write to file
  124. ;     mov     segflg,0         ;clear segment use flag (not now used)
  125.     mov    sp,offset stak        ;for errors in CALLs that jmp to NXCMD
  126.     call    gtcmd
  127.     mov    bx, offset cmdbuf+2    ;first char of command
  128. ;     cmp     word ptr [bx+1],':S'     ;'S:' in reverse order
  129. ;     jz     segonl             ;just change segment
  130.     mov    al,[bx]            ;get 1st char of command
  131.     mov    bx,offset CmdVectorTable
  132.     mov    ch,(offset VectorTblEnd-offset CmdVectorTable)/3 ;no. of entries
  133. FuncLoop:
  134.     cmp    al,cs:[bx]        ;test char match
  135.     jz    fndfun
  136.     inc    bx
  137.     inc    bx
  138.     inc    bx
  139.     dec    ch
  140.     jnz    FuncLoop
  141.     jmp    cmerr
  142.  
  143. fndfun:    inc    bx
  144.     mov    dx,cs:[bx]        ;address of function
  145.     jmp    dx            ;no, NOT jmp [dx] !!
  146.  
  147. ;segonl:    inc    bx        ;pre-adj BX to point to S: in cmdbuf
  148. ;    call    updseg
  149. ;    jmp    short nxcmd
  150.  
  151. CmdVectorTable    db    cr
  152.     dw    offset hlpcmd
  153.     db    ';'
  154.     dw    offset cmrem        ;enter Remark
  155.     db    'A'
  156.     dw    offset cmatmt        ;Attempt to find DB's
  157.     db    'B'
  158.     dw    offset cmbld        ;Build symbol table
  159.     db    'C'
  160.     dw    offset cmctl        ;enter Control (BEHISW) or dump table
  161.     db    'D'
  162.     dw    offset cmdump        ;hex Dump, also Dump Symbol table
  163.     db    'E'
  164.     dw    offset cmentr        ;Enter a label
  165.     db    'H'
  166.     dw    offset cmhelp
  167.     db    'K'
  168.     dw    offset cmkill        ;Kill a label
  169.     db    'L'
  170.     dw    offset cmload        ;load files
  171.     db    'N'
  172.     dw    offset cmpurg        ;clear .CTL, .SMB, .REM tables
  173.     db    'O'
  174.     dw    offset cmorg        ;set ORG addr
  175.     db    'P'
  176.     dw    offset CmPath        ;change D:\path\ to save to
  177.     db    'Q'
  178.     dw    offset cmexit        ;enter Q to quit
  179.     db    'R'
  180.     dw    offset CmRAMpara    ;unassemble anywhere in RAM
  181.     db    'S'
  182.     dw    offset CmSearch
  183.     db    'T'
  184.     dw    offset cmtrim        ;toggle Trim (prints addrs w/labels)
  185.     db    'U'
  186.     dw    offset CmUnasm        ;do Unassembly
  187.     db    'W'
  188.     dw    offset CmWriteRSM    ;write .RSM file
  189.     db    'Z'
  190.     dw    offset cmeof        ;write EOF to .ASM file & close
  191.     db    '?'
  192.     dw    offset CmStats
  193. VectorTblEnd db    0
  194.  
  195. ;--------------------------------
  196. cmerr:    mov    wfiflg,0        ;clear 'write to file' flag
  197.     call    prtstr
  198.     db    'Command Error at ',bel,0
  199.     pop    bx            ;addr called from
  200.     call    Print00BX_        ;     for debugging
  201.     call    prtstr
  202.     db    cr,lf,0
  203.     cli
  204.     mov    sp,offset stak
  205.     sti
  206.     jmp    nxcmd
  207.  
  208. ;--------------------------------
  209. delim:    cmp    al,' '
  210.     jz    deliok
  211.     cmp    al,','
  212.     jz    deliok
  213.     call    cmerr            ;expected delimiter missing
  214. deliok:    ret
  215.  
  216. ;--------------------------------
  217. ; Exit program here
  218. cmexit:    cmp    ChgFlag,0
  219.     jz    ByeBye
  220.     call    prtstr
  221.     db    cr,lf,'Unsaved changes - '
  222.     db    cr,lf,'hit U to update & exit, E to just exit.',0
  223. Gotta:    mov    ah,0            ;read next kbd char into AL
  224.     int    16h
  225.     or    al,al            ;check for non-ASCII key
  226.     jz    Gotta
  227.     and    al,5Fh            ;make upper-case
  228.     cmp    al,'E'
  229.     jz    ByeBye
  230.     cmp    al,'U'
  231.     jnz    Gotta
  232.     call    sav_em
  233. ByeBye:    mov    ax,4C00h        ;exit w/errorlevel = 0
  234.     int    21h
  235.  
  236. ;--------------------------------
  237. ;HELP SCREENS
  238.  
  239. cmhelp:    mov    hlpflg,1        ;signal cursor keys - see gtcmd
  240.     xor    ah,ah
  241.     mov    bx,offset helptr
  242.     mov    al,helpno        ;get which help screen
  243.     add    al,al
  244.     add    bx,ax
  245.     mov    dx,[bx]            ;make dx point to desired screen
  246.     mov    ah,9            ;print string
  247.     int    21h
  248.     jmp    hlpcmd
  249.  
  250. ;line  0
  251. help    db    '             COMMAND SUMMARY - all numbers are HEX!'
  252. ;line  1 & 2
  253.     db    cr,lf,cr,lf,';NNNN,[;]Remark    enter Remark at NNNN'
  254.     db    '   ;=append    \ starts new line'
  255. ;line  3
  256.     db    cr,lf,';[NNNN]    list Remarks Table [from NNNN]    '
  257.     db    ';NNNN,        delete remark at NNNN'
  258. ;line  4
  259.     db    cr,lf,'A (See U)    attempt to find DBs    '
  260.     db    'B (See U)    build Symbol Table'
  261. ;line  5
  262.     db    cr,lf,'C        dump CTL table        '
  263.     db    'CSSSS        dump CTL from SSSS on'
  264. ;line  6
  265.     db    cr,lf,'CNNNN,X        set CTL (X=BEHISW or K)    '
  266.     db    'DSSSS        dump bytes from SSSS on'
  267. ;line  7
  268.     db    cr,lf,'DSSSS,EEEE    dump bytes over range    '
  269.     db    'D,EEEE        dump thru EEEE'
  270. ;line  8
  271.     db    cr,lf,'D        dump a page more    '
  272.     db    'D=NN       bytes (not lines)/dump (HEX)'
  273. ;line  9
  274.     db    cr,lf,'DS        dump the Symbol Table    '
  275.     db    'DS.Label    dump SMB from Label on'
  276. ;line 10
  277.     db    cr,lf,'ENNNN,.Label    enter Label at NNNN    '
  278.     db    'DSssss        dump SMB from ssss on'
  279. ;line 11
  280.     db    cr,lf,'K.Label        kill Label from Table    '
  281.     db    'U        Unassemble entire pgm'
  282. ;line 12
  283.     db    cr,lf,'USSSS,EEEE    Unasm over range    '
  284.     db    'U,EEEE        Unasm to EEEE'
  285. ;line 13
  286.     db    cr,lf,'USSSS        Unasm 20 lns from SSSS    '
  287.     db    'U=NN        Set no. lines to Unasm'
  288. ;line 14
  289.     db    cr,lf,'O        display Current ORG    '
  290.     db    'ONNNN        Set new ORG'
  291. ;line 15
  292.     db    cr,lf
  293. ;line 16
  294.     db    cr,lf,'RNNNN sets, R shows para in RAM to unassemble if '
  295.     db    'no file is loaded'
  296. ;line 17
  297.     db    cr,lf,'L[d:][\path\]name.COM .CTL .SMB .REM .ALL'
  298.     db    '  Load files (no .ext same as .ALL)'
  299. ;line 18
  300.     db    cr,lf,'F9    save .CTL, .SMB, .REM files    '
  301.     db    'N    trash .CTL, .SMB, .REM files'
  302. ;line 19
  303.     db    cr,lf,'W enables saving as you '
  304.     db    'Unassemble. Stops at END or Z closes'
  305. ;line 20
  306.     db    cr,lf,'Z        close .RSM file        '
  307.     db    '?        print Statistics'
  308. ;line 21
  309.     db    cr,lf
  310. ;line 22
  311.     db    cr,lf,'enter Q or hit ESC, Q to exit to DOS'
  312. ;line 23 & 24
  313.     db    cr,lf,tab,tab,tab,196,196,196,'PgDn for next help page'
  314.      db    196,196,196,cr,lf,'$'
  315.  
  316. extnd_help db    '            Commands Continued'
  317.     db    cr,lf,cr,lf,'T  toggle display of label addresses as comments'
  318.     db    cr,lf
  319.     db    cr,lf,'SWWWW    search for WWWW'
  320.     db    cr,lf,'S    continue search for WWWW    '
  321.     db    'SWWWW,SSSS   search WWWW after SSSS'
  322.     db    cr,lf,'ANY KEY stops search.  WWWW is in reverse order in RAM!'
  323.     db    cr,lf,cr,lf,'P lets you edit path to save/load.'
  324.     db    cr,lf,cr,lf,'Control meanings:',cr,lf
  325.     db    '  B=Bytes in ASCII   H=Bytes in hex   E=END (ends Unassembly)'
  326.     db    cr,lf,'  I=Instructions     S=Same [DB n DUP (x)]       W=Words'
  327.     db    cr,lf,'  K=Kill CTL at this addr'
  328.     db    cr,lf,cr,lf,'You can enter .YourLabel in place of any address'
  329.     db    cr,lf,cr,lf,cr,lf
  330.     db    'Run  RE-SOURC [d:][\path\]filename  to load filename.COM (or '
  331.     db    '.EXE or .SYS),'
  332.     db    cr,lf,' .REM, .CTL, and .SMB'
  333.     db    ' automatically.  Files must all be in same directory.'
  334.     db    cr,lf,cr,lf,'PGDN works, CTRL-PGUP goes to start, '
  335.     db    'down arrow does 1 more line',cr,lf
  336.     db    cr,lf,196,196,196,'PgUp for previous help page'
  337.     db    22 dup (196)
  338.     db    'PgDn for next help page',196,196,196
  339.     db    cr,lf,'$'
  340.  
  341. instrs    db    tab,tab,tab,tab,'INSTRUCTIONS',cr,lf,cr,lf
  342.     db    'Lfilename (or .ALL) loads target program and .SMB, .REM, .CTL'
  343.     db    cr,lf,cr,lf,'Load any file with Lfilename.ext '
  344.     db    cr,lf,cr,lf,'For unusual programs, use O to set ORG as desired.'
  345.     db    cr,lf,cr,lf,'A finds approx location of DBs.'
  346.     db    cr,lf,cr,lf,'Build .SMB (label) table with B.  Some'
  347.     db    ' labels will not show until next U.'
  348.     db    cr,lf,cr,lf,'Enter or change labels with ENNNN,.Label',cr,lf
  349.     db    'Add remarks with ;NNNN,inserted remark  or  '
  350.     db    ';NNNN,;appended remark'
  351.     db    cr,lf,cr,lf,'F9 saves the .SMB, .CTL, and .REM files.'
  352.     db    cr,lf,cr,lf,'To write a .RSM "source" file,'
  353.     db    ' hit W and then U.'
  354.     db    cr,lf,cr,lf,cr,lf
  355.     db    'RE-SOURCE works only on the first 64K of a program...'
  356.     db    cr,lf,'  use ? to find and R to set seg of next 64K.'
  357.     db    cr,lf
  358.     db    cr,lf,tab,tab,tab,196,196,196,'PgUp for previous help page'
  359.     db    196,196,196,cr,lf,'$'
  360. ;--------------------------------
  361. cmtrim:    mov    al,trmflg
  362.     not    al
  363.     mov    trmflg,al
  364.     or    al,al
  365.     jz    LblAdrsOn
  366.     call    prtstr
  367.     db    'Label Addresses Off',cr,lf,0
  368.     jmp    nxcmd
  369. LblAdrsOn:
  370.     call    prtstr
  371.     db    'Label Addresses On',cr,lf,0
  372.     jmp    nxcmd
  373.  
  374. ;--------------------------------
  375. cmpurg:    call    prtstr
  376.     db    'purge .SMB (labels), .REM, & .CTL tables? (Y/N)',0
  377.     call    gtcmd
  378.     mov    al,byte ptr cmdbuf+2
  379.     cmp    al,'Y'
  380.     jnz    NoPurge
  381.     call    erstbl            ;empty the segment tables
  382.     mov    segsho,205        ;replace seg char in prompt arrow
  383.     mov    PgmParas,0        ;size of loaded pgm
  384.     jmp    Restart
  385.  
  386. NoPurge:
  387.     jmp    nxcmd
  388.  
  389. ;--------------------------------
  390. ;all calls commented out
  391. sgreqs:    mov    bx,offset cmdbuf+4    ;check for segment prefix, e.g. UDS:1234
  392.     mov    ax,[bx]            ;  (remember,1st char of cmd @ cmdbuf+2)
  393.     cmp    ax,word ptr lblS    ;is xS: there?
  394.     jz    updseg            ;yes, find which and set
  395.     ret                ;else do nothing
  396. lblS    db    ':S'            ;backwards since lo-hi in RAM
  397.  
  398. updseg:    dec    bx
  399.     mov    al,[bx]            ;first seg char, C or D or E or S
  400.     sub    ah,ah            ;start at 0
  401.     cmp    al,'C'
  402.     jz    segmch
  403.     inc    ah
  404.     cmp    al,'D'
  405.     jz    segmch
  406.     inc    ah
  407.     cmp    al,'E'
  408.     jz    segmch
  409.     inc    ah
  410.     cmp    al,'S'
  411.     jz    segmch
  412.     ret                ;ignore any others
  413. ;segmch used only in this routine
  414. segmch:    mov    segsho,al        ;for cmd. prompt display
  415.     mov    segflg,al        ;seg req given
  416.     mov    al,ah            ;count value
  417.     sub    ah,ah
  418.     mov    bx,ax            ;in a base reg
  419.     add    bx,offset segmtb
  420.     mov    cl,cs:[bx]        ;get bit pattern
  421.     mov    OprndType,cl        ;init symbol select
  422.     mov    bl,12            ;size of segment record
  423.     mul    bl            ;index segment records
  424.     mov    bx,offset cofset     ;segment para word base
  425.     add    bx,ax            ;index to right seg.
  426.     mov    ax,[bx]            ;get this para value
  427.     mov    curpar,ax        ;to active para holder
  428.     mov    ax,-8[bx]        ;get segment length
  429.     mov    cl,4
  430.     shl    ax,cl            ;convert to bytes
  431.     mov    segsiz,ax        ;for ctl table limits
  432.     mov    dx,offset cmdbuf[3]     ;dest
  433.     mov    bx,offset cmdbuf[6]     ;source
  434. ;squeeze out segment chars
  435. l03b2:    mov    al,[bx]            ;move cmd line
  436.     xchg    bx,dx
  437.     mov    [bx],al            ;down a notch
  438.     xchg    bx,dx
  439.     inc    bx
  440.     inc    dx
  441.     cmp    al,cr
  442.     jnz    l03b2
  443.     ret
  444.  
  445. segmtb    db    0Ch,04h,08h,0
  446.  
  447. ;--------------------------------
  448. cmdump:    ;call    sgreqs
  449.     mov    dx,DumpStart
  450.     mov    bx,dmpcnt
  451.     add    bx,dx
  452.     mov    DumpEnd,bx
  453.     mov    bx,offset cmdbuf+3
  454.     mov    al,[bx]            ;2nd cmd char
  455.     cmp    al,cr
  456.     jz    dmphdr            ;continue last dump
  457.     cmp    al,'S'            ;DS command, dump symbol table
  458.     jnz    l0411
  459.     mov    al,[bx+1]        ;next char
  460.     cmp    al,':'            ;segment req coming?
  461.     jz    l0411            ;looks like it, not DS command
  462.     jmp    DumpSym
  463.  
  464. l0411:    cmp    al,'='            ;is this a dump length change ?
  465.     jnz    l0418
  466.     jmp    SetDumpCt
  467.  
  468. l0418:    cmp    al,','            ;Dump to end addr only
  469.     jz    dump1
  470. ;Dump from DumpStart (user input DNNNN)
  471. dump0:    call    gtval        ;rets w/bx>char past number, dx=addr less curorg
  472.     jnc    notneg        ;    and carry if DX<0
  473.     xor    dx,dx        ;If Dump addr before ORG, start at ORG
  474. notneg:    push    bx
  475.     mov    bx,dmpcnt
  476.     add    bx,dx
  477.     mov    DumpEnd,bx
  478.     pop    bx
  479. dump1:    cmp    al,cr
  480.     jz    dump3
  481.     call    delim
  482.     inc    bx
  483.     push    dx
  484.     call    gtval
  485.     xchg    bx,dx
  486.     mov    DumpEnd,bx
  487.     pop    dx
  488. dump3:    mov    DumpStart,dx
  489.     cmp    al,cr
  490.     jz    dmphdr
  491.     call    cmerr
  492.  
  493. dmphdr:    call    prtstr
  494.     db    'Addr  +0+1 +2+3  +4+5 +6+7   +8+9 +A+B  +C+D +E+F'
  495.     db    tab,196,196,196,'ASCII',196,196,196,cr,lf,0
  496. cntdmp:    mov    bx,DumpStart
  497.     mov    es,curpar
  498. dump4:    call    BreakChk
  499.     push    bx        ;BX is pointer to code wrt start of target pgm
  500.     add    bx,curorg
  501.     call    Print00BX_
  502.     pop    bx
  503.     push    bx
  504.     call    prspc
  505. dmpln:    mov    es,curpar
  506.     mov    al,es:[bx]
  507.     call    xo
  508.     inc    bx
  509.     mov    al,bl
  510.     and    al,1
  511.     jnz    wdspc1
  512.     call    prspc
  513. wdspc1:    mov    al,bl
  514.     and    al,3
  515.     jnz    wdspc2
  516.     call    prspc
  517. wdspc2:    mov    al,bl
  518.     and    al,7
  519.     jnz    wdspc3
  520.     call    prspc
  521. wdspc3:    mov    al,bl
  522.     and    al,0fh
  523.     jnz    dmpln
  524.     call    prspc
  525.     pop    bx
  526. dmpasc:    mov    es,curpar
  527.     mov    al,es:[bx]
  528.     cmp    al,' '    ;20h
  529.     jb    period
  530.     cmp    al,7Fh
  531.     jb    chrctr
  532. period:    mov    al,'.'    ;2eh
  533. chrctr:    call    typech
  534.     inc    bx
  535.     mov    al,bl
  536.     and    al,0Fh
  537.     jz    lcmplt
  538.     and    al,7
  539.     jnz    wdspc4
  540.     call    prspc
  541. wdspc4:    jmp    dmpasc
  542.  
  543. lcmplt:    call    prspc
  544.     call    pstg
  545.     db    cr,lf,0
  546.     mov    DumpStart,bx
  547.     mov    ax,DumpEnd
  548.     sub    ax,bx
  549.     jnb    dump4
  550.     jmp    nxcmd
  551.  
  552. ;set no of bytes per dump (dmpcnt)
  553. SetDumpCt:
  554.     inc    bx
  555.     call    gtval
  556.     add    dx,curorg        ;gtval subtracts curorg!
  557.     inc    bx
  558.     dec    dx
  559.     xchg    bx,dx
  560.     mov    dmpcnt,bx
  561.     xchg    bx,dx
  562. l04e8:    cmp    al,cr
  563.     jnz    l04ef
  564.     jmp    nxcmd
  565.  
  566. l04ef:    call    delim
  567.     jmp    dump0
  568.  
  569. ;--------------end of Dump command-------------
  570.  
  571. ;DUMP THE SYMBOL TABLE
  572. ; Table is 2 byte addr, 1 byte Seg/Type, 1 byte length, n bytes string
  573.  
  574. DumpSym:
  575.     mov    EntriesLeft,4        ;init items/line
  576.     mov    bx,offset cmdbuf+4    ;1st past the DS
  577.     mov    al,[bx]
  578.     cmp    al,cr
  579.     jz    frmbgn
  580.     call    gtval
  581.     call    symluk
  582.     mov    bx,NxtSymPtr        ;> this or next higher label
  583.     jmp    frmsym
  584.  
  585. frmbgn:    mov    bx,symbas
  586. frmsym:    call    prtstr
  587.     db    'KEY: 1st char = CS, DS, ES, SS   '
  588.     db    '2nd char = Byte, Word, Dword, Undefined',cr,lf,cr,lf,0
  589. NxtSym:    mov    dx,[bx]            ;start of a SMB entry, the addr
  590.     inc    bx
  591.     inc    bx
  592.     inc    bx
  593.     mov    al,[bx]            ;string length
  594.     or    al,al
  595.     jz    DSdone            ;end of table reached
  596. l051a:    push    dx            ;addr
  597.     push    bx            ;pointer to string length
  598.     dec    bx
  599.     add    dx,curorg        ;correct all addrs for ORG
  600.     xchg    bx,dx            ;must be in BX to print
  601.     call    Print00BX_        ;print address in BX, + space
  602.     pop    bx            ;pointer to length byte
  603.     pop    dx            ;addr
  604.     dec    bx
  605.     mov    al,[bx]            ;OprndType byte
  606.     inc    bx            ;back to length byte
  607.     xor    ah,ah
  608.     push    ax            ;save type byte
  609.     mov    bp,offset ltable
  610.     and    al,00110000b        ;get bits 4 & 5
  611.     mov    cl,4
  612.     shr    al,cl            ;into bits 0 & 1
  613.     mov    si,ax
  614.     mov    al,[bp+si]
  615.     call    typech            ;print seg char, S D E or C
  616.     pop    ax
  617.     and    al,3            ;get bits 0 & 1
  618.     mov    si,ax
  619.     mov    al,[bp+si+4]
  620.     call    typech            ;print Type char, U B W or D
  621.     mov    al,' '
  622.     call    typech            ;print a space
  623.     mov    cl,[bx]            ;length of label
  624.     xor    ch,ch
  625.     inc    cx            ;length + 1 to
  626.     add    cx,bx            ;  point to next label field
  627.     mov    NxLblPtr,cx        ;save pointer
  628.     mov    cl,10            ;always print 10d bytes
  629.     inc    bx            ;to 1st char of label
  630. ;print the label, truncated or padded out to 10d characters
  631. spit:    mov    al,[bx]
  632.     call    typech
  633.     inc    bx
  634.     dec    cl            ;keep count of bytes printed
  635.     jz    EntryDone
  636.     cmp    bx,NxLblPtr
  637.     jnz    spit
  638. PadLoop:
  639.     call    prspc
  640.     dec    cl
  641.          jnz    PadLoop
  642. EntryDone:
  643.     call    ChkEntryCt
  644.     call    BreakChk
  645.     mov    bx,NxLblPtr
  646.     jmp    NxtSym
  647.  
  648. ltable    db    'SDECUBWD'
  649.  
  650. DSdone:    call    prtstr
  651.     db    cr,lf,0
  652.     jmp    nxcmd
  653.  
  654. ;after printing entry, see if line is finished (for CTL and SYM dump)
  655. ChkEntryCt:
  656.     dec    EntriesLeft
  657.     jz    NotherLine
  658.     call    prspc
  659.     call    prspc
  660.     ret
  661.  
  662. ;new line of 4 entries
  663. NotherLine:
  664.     call    CrLf
  665.     mov    EntriesLeft,4
  666.     ret
  667. ;--------------------------------
  668. ;SET ORG ADDRESS
  669. cmorg:    ;call    sgreqs            ;any segment data?
  670.     mov    bx,offset cmdbuf+3    ;1st char after the O
  671.     mov    al,[bx]
  672.     cmp    al,cr
  673.     jz    prntos            ;just show curr value
  674.     call    gtval            ;new ORG (less old ORG) from user to DX
  675.     add    dx,curorg        ;correct it for old curorg
  676.     cmp    al,cr            ;end of entry ?
  677.     jz    l0557
  678.     call    cmerr
  679.  
  680. l0557:    mov    curorg,dx        ;this is the ORG for display
  681. prntos:    call    prtstr
  682.     db    'ORG = ',0
  683.     mov    bx,curorg
  684.     call    Print00BX_
  685.     call    CrLf
  686.     jmp    nxcmd
  687.  
  688. ;--------------------------------
  689. ;ATTEMPT TO FIND DBs
  690. cmatmt:    mov    AmodeFlag,1
  691.     mov    BmodeFlag,0
  692.     jmp    short list1
  693. ;BUILD SYMBOL TABLE
  694. cmbld:    mov    BmodeFlag,1
  695.     mov    AmodeFlag,0
  696.     jmp    short list1
  697.  
  698. ;UNASSEMBLE at [pcntr] but show addr [pcntr+curorg], & A or B if reqd
  699. CmUnasm:
  700.     mov    BmodeFlag,0
  701.     mov    AmodeFlag,0
  702. list1:    mov    wfiflg,0        ;write to display only
  703.     mov    al,LnsPerScreen        ;no. of lines to show
  704.     mov    LinesToGo,al
  705.     mov    LCountFlag,al        ;show specific no of lines
  706. ;     call     sgreqs            ;check cmdbuf for segment spec.
  707.     mov    bx,offset cmdbuf+3    ;1st char after the U, A, or B
  708.     mov    al,[bx]
  709.     cmp    al,cr
  710.     jz    ToTheEnd
  711.     cmp    al,','
  712.     jz    list3            ;no starting location
  713.     cmp    al,' '
  714.     jz    list3            ;no starting location
  715.     cmp    al,'='
  716.     jnz    list2
  717.     jmp    SetLineCount        ;change default no of lines
  718.  
  719. ToTheEnd:
  720.     mov    pcntr,0
  721.     mov    dx,0FFFFh
  722.     jmp    short list4
  723.  
  724. ;U B or A from given location
  725. list2:    call    gtval            ;get start pcntr=input-curorg
  726.     mov    pcntr,dx        ;where to start
  727.     cmp    al,cr
  728.     jz    TwentyLines        ;only start given
  729.     call    delim
  730. list3:    inc    bx            ;past delimiter
  731.     call    gtval            ;get ending location
  732. list4:    mov    lastwd,dx
  733.     mov    LCountFlag,0        ;not specific line count
  734.  
  735. ;--------------------------------
  736. ;U B or A default no. of lines - always entered w/wfiflg=0
  737.  
  738. TwentyLines:
  739.     call    BreakChk        ;check for Ctrl-Break w/DOS func 01
  740.     cmp    LCountFlag,0
  741.     jz    contl            ;end addr was input, do reqd no lines
  742.     mov    al,LinesToGo
  743.     dec    al
  744.     jns    flagck            ;another line if screen not full
  745.     jmp    nxcmd
  746.  
  747. contl:    mov    es,curpar        ;para of target pgm
  748.     mov    ax,pcntr
  749.     sub    ax,lastwd
  750.     jb    flagck            ;not at end
  751.     jmp    nxcmd
  752.  
  753. flagck:    cmp    AmodeFlag,0
  754.     jnz    Attempt
  755.     jmp    morel            ;not in 'Attempt find DBs' mode
  756.  
  757. ;ATTEMPT TO FIND DB's WHILE UNASSEMBLING, insert CTL where found
  758. ;first, search for DUPs
  759. Attempt:
  760.     mov    di,pcntr
  761.     mov    es,curpar
  762.     mov    al,es:[di]        ;get 1st byte of line
  763.     mov    cx,17            ;to find 16 DUPs
  764.     repz    scasb
  765.     or    cx,cx
  766.     jnz    ChkASCII
  767. ;16 DUPs in a row have been found, CX is 0
  768.     dec    cx            ;to FFFFh
  769.     dec    di            ;back to 1st un-scanned byte
  770.     repz    scasb
  771.     mov    bx,di
  772.     mov    Control,'S'
  773.     call    SetControl
  774.     jmp    morel
  775.  
  776. ChkASCII:
  777.     mov    bx,pcntr
  778.     mov    cx,8            ;no. of ASCII chars to call it a DB line
  779.     mov    es,curpar
  780. loop8:    mov    al,es:[bx]
  781.     call    IfASCII            ;test one byte for DB
  782.     jc    morel            ;not a DB line
  783.     inc    bx
  784.     loop    loop8            ;must find 8 ASCII chars in a row
  785. ;8 ASCII chars in a row have been found
  786. follow:    mov    al,es:[bx]
  787.     inc    bx
  788.     call    IfASCII            ;keep looking for ASCII
  789.     jnc    follow
  790.     mov    Control,'B'
  791.     call    SetControl
  792.     jmp    morel
  793. ; . . . . . . . . . . . . . . . .
  794. SetControl:                ;insert Control if none here
  795.     dec    bx            ;to 1st non-ASCII/non-DUP byte
  796.     push    bx
  797.     mov    dx,pcntr        ;start addr of line
  798.     call    ctlook
  799.     jc    okchg            ;if no ctl at this location
  800.     cmp    byte ptr [bx+3],'E'    ;if ctl exists
  801.     pop    bx
  802.     jz    morel            ;don't overwrite END ctl
  803.     push    bx
  804. okchg:    mov    dx,pcntr
  805.     mov    al,Control
  806.     call    EnterCTL        ;make entry in CTL table
  807. ;insert I ctl where ASCII bytes/DUPs end
  808.     pop    dx            ;was BX, last byte + 1
  809.     cmp    word ptr PgmBytes+2,0
  810.     jnz    NoENDp            ;there is no END ctl if >64K
  811.     cmp    dx,PgmBytes
  812.     jc    NoENDp            ;if not past end
  813.     push    dx
  814.     mov    dx,PgmBytes
  815.     call    ctlook            ;is there a ctl at end locn ?
  816.     pop    dx
  817.     jc    NoENDp
  818. ;under 64K, past end, there is a ctl at end
  819.     cmp    byte ptr [bx+3],'E'    ;is the ctl at end really END ?
  820.     jz    morel            ;if so, no ctl past END
  821. NoENDp:    call    ctlook
  822.     jc    okchg2            ;no ctl at this location
  823.     cmp    byte ptr [bx+3],'E'
  824.     jz    morel            ;don't overwrite END ctl
  825. okchg2:    mov    al,'I'            ;back to 'I' at end
  826.     jmp    EnterCTL
  827. ; . . . . . . . . . . . . . . . .
  828.  
  829. ;Jump here if not in A mode
  830. morel:    mov    bx,remtbl
  831.     cmp    bx,remend
  832.     jz    ncmt            ;remark table is empty
  833.     mov    dx,pcntr
  834.     call    RemChk            ;test for poss. remark at [DX]
  835.     jc    ncmt            ;if none
  836. ;remark exists, BX points to its matching addr
  837.     inc    bx
  838.     inc    bx            ;skip addr field
  839.     mov    ch,[bx]            ;byte count of remark
  840.     mov    al,[bx+1]        ;first remark character
  841.     cmp    al,';'            ;append it?
  842.     jnz    morel1
  843.     mov    AppendPtr,bx
  844.     jmp    ncmt
  845.  
  846. morel1:    call    DoRemark        ;print the remark
  847.     call    CrLf
  848.     jmp    ncmt
  849. ; . . . . . . . . . . . . . . . .
  850. ;print remark like this on separate line(s)
  851. DoRemark:
  852.     mov    wfiflg,1
  853.     call    semic            ;start lines with a semicolon
  854.     or    ch,ch            ;check for zero-length remark
  855.     jnz    RemContinues
  856.     ret
  857.  
  858. RemContinues:
  859.     inc    bx
  860.     mov    al,[bx]
  861.     cmp    al,'\'            ;multi-line remark ?
  862.     jnz    NoBkslash
  863.     call    CrLf            ;break remark here
  864.     dec    ch
  865.     jmp    DoRemark
  866.  
  867. NoBkslash:
  868.     call    typech
  869.     dec    ch
  870.     jnz    RemContinues
  871.     ret
  872. ; . . . . . . . . . . . . . . . .
  873. ;Line is not remark, or remark is done.  Every line goes thru here.
  874. ncmt:    mov    RelFlag,1        ;line labels not corrected for Org
  875.     mov    dx,pcntr        ;get address of line
  876.     call    ctlook            ;CTL entry for this addr?
  877.                     ;   (rets w/BX>ctlbas+0, 4, etc)
  878.     jc    SameMode        ;carry=not matched addr, use old mode
  879.     add    bx,4            ;use mode of matched addr
  880. SameMode:
  881.     dec    bx            ;to mode byte (prev mode if no change)
  882.     mov    al,[bx]            ;mode char, is at ctlbas-1, +3, +7, etc
  883.     cmp    al,'I'
  884.     jnz    not_i
  885.     mov    ColonFlag,0        ;put colon after label
  886.     call    AddrOrSmb        ;print any label, or addr=pcntr+curorg
  887.     mov    RelFlag,0        ;default not relative JMP, CALL, etc
  888.     mov    SegOvrdPfx,0        ;just in case
  889.     call    dline            ;disassemble one line as instruction
  890.     mov    wfiflg,0        ;write to screen only
  891.     jmp    TwentyLines        ;and go to the next line.
  892.  
  893. not_i:    mov    ColonFlag,1        ;no colon after label
  894.     call    AddrOrSmb        ;print any label, or addr=pcntr+curorg
  895. ;RelFlag stays = 1 so symluk looks for lbls w/o correction
  896.     cmp    al,'E'            ;is it the END ?
  897.     jnz    notend
  898.     jmp    cmeof            ;show end & stop
  899.  
  900. notend:    inc    bx            ;to next CTL record
  901.     mov    dx,[bx+1]        ;address
  902.     mov    nxtctl,dx        ;save to end Hex, Byte & Space lines
  903.     mov    wfiflg,0
  904.     cmp    al,'S'             ;space mode ?
  905.     jnz    ckbmd
  906.     jmp    Smode
  907.  
  908. ckbmd:    cmp    al,'B'            ;byte ASCII mode ?
  909.     jnz    ckhmd
  910.     jmp    bmode
  911.  
  912. ckhmd:    cmp    al,'H'            ;hex mode ?
  913.     jnz    ckwmd
  914.     jmp    hmode
  915.  
  916. ckwmd:    cmp    al,'W'            ;word mode ?
  917.     jnz    badmd
  918.     jmp    wmode
  919.  
  920. badmd:    call    typech
  921.     call    prtstr
  922.     db    ' INVALID CTL ENTRY - check .CTL file at this location.',cr,lf,0
  923.     jmp    nxcmd
  924. ;--------------------------------
  925. ;SET NO OF LINES TO UNASSEMBLE
  926. SetLineCount:
  927.     inc    bx
  928.     call    gtval            ;input less curorg to DX
  929.     add    dx,curorg        ;correct it
  930.     or    dh,dh            ;now check for more than a screen full
  931.     jnz    toerr            ;  and zero lines
  932.     mov    al,dl
  933.     or    al,al            ;test if more than 0
  934.     jz    toerr
  935.     cmp    al,24
  936.     jc    linesok            ;23d lines max
  937. toerr:    call    cmerr
  938.  
  939. linesok:
  940.     mov    LnsPerScreen,al
  941.     mov    LinesToGo,al
  942.     mov    al,[bx]            ;char in cmdbuf after input no.
  943.     inc    bx
  944. l0776:    cmp    al,cr            ;just set no. of lines?
  945.     jnz    l077d
  946.     jmp    nxcmd
  947.  
  948. l077d:    call    delim
  949.     jmp    list2
  950. ;--------------------------------
  951. ;S(ame) control, n DUP (x).
  952. Smode:    mov    wfiflg,1
  953.     call    pstg
  954.     db    'DB',tab,0
  955.     mov    ax,NxtSymAddr
  956.     or    ax,ax            ;note: * problem if >64K file *
  957.     jz    UseNxtctl        ;if no next label; always is an E ctl
  958.     mov    EndSameAddr,ax
  959.     cmp    ax,nxtctl        ;ESAddr - nxtctl
  960.     jc    FindNxtDif
  961. UseNxtctl:
  962.     mov    ax,nxtctl
  963.     mov    EndSameAddr,ax
  964. FindNxtDif:
  965.     mov    di,pcntr
  966.     mov    es,curpar
  967.     mov    al,es:[di]        ;get 1st byte of DUPs
  968.     xor    cx,cx
  969.     dec    cx            ;limit 64K REPs
  970.     repz    scasb            ;1st NZ will still INC DI
  971.     dec    di            ;to 1st byte past match
  972.     cmp    di,EndSameAddr        ;1st different - next ctl or smb
  973.     jnc    PrintDUP
  974.     mov    EndSameAddr,di
  975. PrintDUP:
  976.     push    ax            ;save the DUP char
  977.     mov    dx,EndSameAddr
  978.     sub    dx,pcntr        ;ESAddr - pcntr, * NFG over 64K *
  979.     call    PrintDXh
  980.     call    pstg
  981.     db    ' DUP (',0
  982.     pop    ax            ;the DUP char
  983.     call    PrtALasDB
  984.     call    pstg
  985.     db    ')',0
  986.     mov    dx,EndSameAddr
  987.     mov    pcntr,dx
  988.     jmp    StopLine
  989. ;--------------------------------
  990. ;'W' control, words ***** needs to chk for SMB/CTL at 2nd byte, chg to DB.
  991. wmode:    mov    wfiflg,1
  992.     call    pstg
  993.     db    'DW',tab,0
  994.     mov    bx,pcntr
  995.     mov    es,curpar
  996.     mov    dx,es:[bx]
  997.     call    PrintDXh
  998.     inc    pcntr
  999.     inc    pcntr
  1000. StopLine:
  1001.     call    NewLine
  1002.     jmp    TwentyLines
  1003. ;--------------------------------
  1004. ;Byte-ASCII & Hex byte modes
  1005. hmode:    mov    BytesFlag,0
  1006.     jmp    short bmode1
  1007.  
  1008. bmode:    mov    BytesFlag,1        ;flag Bytes ASCII, not HEX
  1009. bmode1:    mov    wfiflg,1        ;write to file, too
  1010.     call    pstg
  1011.     db    'DB',tab,0
  1012.     mov    strcnt,0        ;chars on this line, any print bumps
  1013.     mov    CrLfFlag,0        ;for Bytes ASCII
  1014.     mov    bx,pcntr
  1015.     mov    es,curpar
  1016.     cmp    BytesFlag,0
  1017.     jz    PrtAsHex        ;jump for sure if Hex mode
  1018. ;CTL is Byte mode, but use Hex routine if unprintable:
  1019. ChkHex:    mov    al,es:[bx]
  1020.     call    ChkSpl
  1021.     jz    ToDoASCII
  1022.     cmp    al,' '
  1023.     jb    ChkComma        ;no print other ctrl codes in Byte mode
  1024.     cmp    al,7Fh
  1025.     jnb    ChkComma        ;7Fh and over also unprintable
  1026. ToDoASCII:
  1027.     jmp    DoASCII
  1028.  
  1029. ChkComma:
  1030.     cmp    strcnt,0
  1031.     jz    PrtAsHex
  1032.     call    comma
  1033. PrtAsHex:
  1034.     mov    al,es:[bx]
  1035.     call    PrintALh
  1036.     inc    bx
  1037.     inc    pcntr
  1038. ;end Hex line if up to a CTL change
  1039.     cmp    bx,nxtctl
  1040.     jnz    trysym
  1041.     jmp    StopLine
  1042.  
  1043. ;end Hex line if up to a label
  1044. trysym:    cmp    bx,NxtSymAddr        ;set by symluk when line addr printed
  1045.     jnz    NoHexSmb
  1046.     jmp    StopLine
  1047.  
  1048. ;end Hex line if up to 31d chars
  1049. NoHexSmb:
  1050.     cmp    strcnt,31
  1051.     jb    NotHexMax
  1052.     jmp    StopLine
  1053.  
  1054. NotHexMax:
  1055.     cmp    BytesFlag,0
  1056.     jz    ChkComma        ;if in Hex mode
  1057.     jmp    ChkHex            ;if in Bytes ASCII mode
  1058.  
  1059. ChkSpl:    xor    ah,ah
  1060.     cmp    al,cr
  1061.     jz    CRet
  1062.     add    ah,3
  1063.     cmp    al,lf
  1064.     jz    CRet
  1065.     add    ah,3
  1066.     cmp    al,tab
  1067.     jz    CRet
  1068.     add    ah,3
  1069.     cmp    al,bel
  1070.     jz    CRet
  1071.     add    ah,3
  1072.     or    al,al
  1073. CRet:    ret                ;w/Z if match
  1074.  
  1075. XpandTbl db    'cr.lf.tabbel0..'
  1076.  
  1077. ;ASCII byte printing loop
  1078. MoreASCII:
  1079.     call    ChkSpl
  1080.     jnz    NoXpand
  1081. ;print expanded special characters
  1082.     cmp    strcnt,0
  1083.     jz    PrtSpl
  1084.     cmp    byte ptr es:[bx-1],' '
  1085.     jb    JusComma
  1086.     cmp    byte ptr es:[bx-1],7Fh
  1087.     jnb    JusComma
  1088.     call    apostrophe        ; ' if prev char was ASCII, not special
  1089. JusComma:
  1090.     call    comma            ;comma before special chars
  1091. PrtSpl:    mov    al,ah
  1092.     push    bx
  1093.     mov    bx,offset XpandTbl
  1094.     call    Prt3FromTabl
  1095.     pop    bx
  1096. ;a Zero after anything else ends the line
  1097.     cmp    ah,12d            ;did we just print a '0' ?
  1098.     jnz    SameByte
  1099.     cmp    strcnt,1
  1100.     jz    SameByte        ;if it was 1st on the line
  1101.     cmp    byte ptr es:[bx-1],0
  1102.     jz    SameByte
  1103.     inc    pcntr
  1104.     jmp    StopLine        ;end the line unless prev char also '0'
  1105.  
  1106. NoXpand:
  1107.     cmp    strcnt,0
  1108.     jz    Apost
  1109.     cmp    byte ptr es:[bx-1],' '
  1110.     jb    Cmma
  1111.     cmp    byte ptr es:[bx-1],7Fh
  1112.     jnb    Cmma
  1113.     jmp    short PrtIt
  1114. Cmma:    call    comma            ;if prev spl or Hex & this is not 1st
  1115. Apost:    call    apostrophe        ;if 1st or prev was special or Hex
  1116. PrtIt:    call    typech            ;print to screen and/or file buffer
  1117. SameByte:
  1118.     mov    al,es:[bx]        ;get byte just printed
  1119.     cmp    al,''''            ;27h, single quote
  1120.     jnz    NotQuote
  1121.     call    typech            ;for special case of quote char only
  1122. NotQuote:
  1123.     inc    pcntr            ;bump character pointer
  1124.     mov    bx,pcntr
  1125. ;end ASCII line if up to a Control location
  1126.     cmp    bx,nxtctl
  1127.     jnz    NoEnd
  1128. ToEndQ:    jmp    EndQuote
  1129. ;end ASCII line with any '$'
  1130. NoEnd:    cmp    al,'$'
  1131.     jz    ToEndQ
  1132. ;end ASCII line if up to a label
  1133.     mov    dx,pcntr
  1134.     cmp    dx,NxtSymAddr        ;set by symluk when line addr printed
  1135.     jz    ToEndQ
  1136. ;end ASCII line if up to 50d chars
  1137.     cmp    strcnt,49
  1138.     jnb    ToEndQ
  1139. ;end the line after a space if line is 40-49 chars long
  1140.     cmp    strcnt,40
  1141.     jb    DoASCII
  1142.     mov    bx,pcntr
  1143.     cmp    byte ptr es:[bx-1],' '    ;was just-printed char a space ?
  1144.     jz    ToEndQ
  1145. ;Entry point for Byte Mode, printable codes only.
  1146. DoASCII:
  1147.     mov    bx,pcntr
  1148.     mov    al,es:[bx]        ;get next char
  1149.     cmp    al,cr
  1150.     jz    CRorLF
  1151.     cmp    al,lf
  1152.     jnz    ChkPrn
  1153. CRorLF:
  1154.     cmp    CrLfFlag,1
  1155.     jnz    SetCL
  1156.     jmp    MoreASCII        ;just printed a cr or lf
  1157.  
  1158. SetCL:    mov    CrLfFlag,1
  1159.     cmp    strcnt,0
  1160.     jnz    EndQuote        ;1st CR/LF after others => new line
  1161.     jmp    MoreASCII        ;cr or lf is 1st on the line
  1162.  
  1163. ;Check if next char is printable. It is not a cr or lf.
  1164. ChkPrn:    call    ChkSpl
  1165.     jz    ToMoreASCII
  1166.     cmp    al,' '            ;20h
  1167.     jb    EndQuote
  1168.     cmp    al,7Fh
  1169.     jnb    EndQuote
  1170.     mov    CrLfFlag,0
  1171. ToMoreASCII:
  1172.     jmp    MoreASCII        ;go print the char & keep going
  1173.  
  1174. EndQuote:
  1175.     mov    al,es:[bx-1]
  1176.     call    ChkSpl
  1177.     jz    ToStop            ;no closing ' if just printed special
  1178.     call    apostrophe
  1179. ToStop:    jmp    StopLine
  1180. ;--------------------------------
  1181.  
  1182. CmStats:
  1183.     call    prtstr
  1184.     db    cr,lf,'RE-SOURC PSP at Segment. ',0
  1185.     mov    bx,cs
  1186.     call    Print00BX_
  1187.     call    prtstr
  1188.     db    cr,lf,'Target Pgm at Segment... ',0
  1189.     mov    bx,curpar
  1190.     call    Print00BX_
  1191.     call    prtstr
  1192.     db    cr,lf,'Loc in Pgm  Now-Last+1.. ',0
  1193.     mov    bx,pcntr
  1194.     add    bx,curorg
  1195.     call    Print00BX_
  1196.     mov    bx,PgmBytes        ;**64K max**
  1197.     add    bx,curorg
  1198.     call    Print00BX_
  1199.     call    prtstr
  1200.     db    cr,lf,cr,lf,'Offsets into RE-SOURCE segment:'
  1201.     db    cr,lf,'CTL Table  Start-End.... ',0
  1202.     mov    bx,offset ctlbas
  1203.     call    Print00BX_
  1204. l0984:    mov    ax,1[bx]
  1205.     and    al,ah
  1206.     add    bx,4
  1207.     inc    al
  1208.     jnz    l0984
  1209.     sub    bx,4
  1210.     call    Print00BX_
  1211.     call    prtstr
  1212.     db    cr,lf,'SMB (labels) Start-End.. ',0
  1213.     mov    bx,symbas
  1214.     call    Print00BX_
  1215.     mov    bx,symtp
  1216.     call    Print00BX_
  1217.     call    prtstr
  1218.     db    cr,lf,'REM Table Start-End..... ',0
  1219.     mov    bx,remtbl
  1220.     call    Print00BX_
  1221.     mov    bx,remend
  1222.     call    Print00BX_
  1223.     call    prtstr
  1224. ;    db    cr,lf,cr,lf,'SEG. LGTH BASE SMIN SMAX PARA',0
  1225.     db    cr,lf,cr,lf,0
  1226. ;    mov    bx,offset cstbl
  1227.  
  1228. ;sgplp:    mov    al,[bx]
  1229. ;    or    al,al
  1230. ;    jz    sgpends            ;found end flag
  1231. ;    cmp    al,' '            ;used entry?
  1232. ;    jnz    usdseg
  1233. ;    add    bx,12
  1234. ;    jmp    short sgplp
  1235. ;usdseg:    mov    ch,2        ;print 2 chars
  1236. ;    call    PrtCHbytesPerBX    ;(seg label & order no)
  1237. ;    call    prtstr
  1238. ;    db    ':  ',0
  1239. ;    call    prwval
  1240. ;    call    prwval
  1241. ;    call    prwval
  1242. ;    call    prwval
  1243. ;    call    prwval
  1244. ;    call    CrLf
  1245. ;    jmp    short sgplp
  1246. ;sgpends:
  1247.     jmp    nxcmd
  1248.  
  1249. prwval:    mov    dx,[bx]
  1250.     xchg    bx,dx
  1251.     call    Print00BX_
  1252.     xchg    bx,dx
  1253.     inc    bx
  1254.     inc    bx
  1255.     ret
  1256. ;--------------------------------
  1257. ;SEARCH FOR HEX WORD
  1258. CmSearch:
  1259.     ;call    sgreqs
  1260.     mov    bx,offset cmdbuf+3    ;1st char after the S
  1261.     mov    al,[bx]
  1262.     cmp    al,cr
  1263.     jz    ContinueSearch
  1264.     call    gtval            ;word to search for to DX (less curorg)
  1265.     add    dx,curorg        ;correct it
  1266.     mov    fndadd,dx
  1267.     mov    SearchPointer,0
  1268.     xor    dx,dx
  1269.     cmp    al,cr
  1270.     jz    ContinueSearch
  1271.     call    delim
  1272. l09c6:    inc    bx
  1273.     call    gtval            ;start addr of search to DX (w.r.t. ORG)
  1274.     cmp    al,cr
  1275.     jz    StartSearch
  1276.     call    cmerr
  1277.  
  1278. StartSearch:
  1279.     mov    es,curpar
  1280.     mov    SearchPointer,dx
  1281. ContinueSearch:
  1282.     call    prtstr
  1283.     db    'Lo-Hi word found at ',0
  1284.     mov    bx,fndadd
  1285.     xchg    bx,dx
  1286. ;this is the step-&-compare loop
  1287. nyet:    call    BreakChk
  1288. ;check for end of pgm
  1289.     mov    ax,PgmBytes        ;end of pgm **64K max**
  1290.     mov    bx,SearchPointer
  1291.     cmp    bx,ax
  1292.     jng    NotPast
  1293.     call    prtstr
  1294.     db    cr,lf,'End of program reached',cr,lf,0
  1295.     jmp    nxcmd
  1296. NotPast:
  1297.     mov    es,curpar
  1298.     mov    al,es:[bx]        ;get byte in target pgm
  1299.     inc    bx
  1300.     mov    SearchPointer,bx
  1301.     cmp    al,dl            ;match?
  1302.     jnz    nyet
  1303.     mov    es,curpar
  1304.     mov    al,es:[bx]        ;get next byte
  1305.     cmp    al,dh            ;match too?
  1306.     jnz    nyet
  1307. ;the word matches
  1308.     push    bx
  1309.     push    dx
  1310.     dec    bx
  1311.     add    bx,curorg        ;correct the find addr for ORG
  1312.     call    Print00BX_
  1313.     pop    dx
  1314.     pop    bx
  1315.     call    prspc
  1316.     jmp    nyet            ;continue searching
  1317.  
  1318. ;--------------------------------
  1319. ;The 'Z' command, also used when Control E found while Unassembling.
  1320. cmeof:    mov    al,ASMopenFlag
  1321.     or    al,al
  1322.     jnz    CloseRSM
  1323.     call    pstg
  1324.     db    'END',cr,lf,0        ;to screen only
  1325.     jmp    nxcmd
  1326.  
  1327. CloseRSM:
  1328.     mov    wfiflg,1        ;print to file, too
  1329.     call    pstg
  1330.     db    cr,lf,'CSEG',tab,'ends'
  1331.     db    cr,lf,tab,'END',0
  1332.     cmp    EXTflag,'C'
  1333.     jz    DoStart
  1334.     cmp    EXTflag,'E'
  1335.     jnz    StartFin
  1336. DoStart:
  1337.     call    pstg
  1338.     db    tab,'Start',cr,lf,0
  1339. StartFin:
  1340.     call    WriteNclose        ;add 1Ah, flush buffer to disk
  1341.     mov    wfiflg,0        ;no more printing to file
  1342.     mov    ASMopenFlag,0
  1343.     call    prtstr
  1344.     db    cr,lf,'.RSM file is closed',cr,lf,0
  1345.     jmp    nxcmd
  1346.  
  1347. ;--------------------------------
  1348. EXTtoSpec:
  1349.     mov    di,DotPtr
  1350.     inc    di
  1351. ;put \path\name or .ext [BX] in FileString [DI] - stops at a '.' w/C set
  1352. MoveField:
  1353.     mov    al,[bx]
  1354.     cmp    al,cr
  1355.     jz    MovDone
  1356.     mov    [di],al
  1357.     cmp    al,'.'
  1358.     jz    DotFound
  1359.     or    al,al
  1360.     jz    MovDone
  1361.     inc    di
  1362.     inc    bx
  1363.     jmp    short MoveField
  1364.  
  1365. MovDone:
  1366.     clc
  1367.     ret
  1368.  
  1369. DotFound:
  1370.     stc
  1371.     ret
  1372.  
  1373. ;--------------------------------
  1374. cmload:    mov    al,ASMopenFlag
  1375.     or    al,al
  1376.     jz    OKtoLoad
  1377.     jmp    ASMstillOpenErr
  1378.  
  1379. OKtoLoad:
  1380.     mov    bx,offset cmdbuf+3    ;BX > 1st char after the 'L'
  1381.     mov    al,byte ptr cmdbuf+4    ;2nd char after the 'L'
  1382.     cmp    al,' '            ;2nd char blank?
  1383.     jnz    NameEntered
  1384.     call    cmerr
  1385.  
  1386. NameEntered:
  1387.     mov    di,offset FileString
  1388.     cmp    al,':'            ;drive specified ?
  1389.     jnz    nodriv
  1390.     mov    al,byte ptr cmdbuf+3
  1391.     inc    bx
  1392.     inc    bx            ;to 1st char after the colon
  1393.     mov    byte ptr [di],al
  1394.     inc    di
  1395.     mov    byte ptr [di],':'
  1396.     inc    di            ;to area for \path\name
  1397. nodriv:    call    MoveField        ;get \path\name, stops at a '.'
  1398.     mov    DotPtr,di        ;save pointer to the '.'
  1399.     mov    byte ptr [di],'.'    ;in case no '.' found
  1400.     jnc    SpecDone
  1401.     inc    di            ;to byte after the dot
  1402.     inc    bx
  1403.     call    MoveField        ;get .EXT
  1404.     mov    byte ptr [di],0        ;mark end of ASCIIZ string
  1405.     stc
  1406. SpecDone:
  1407.     jnc    wntall            ;if no .EXT entered
  1408.     mov    dx,offset LitALL
  1409.     mov    cl,3            ;bytes to compare at [BX]
  1410.     call    cmpstr
  1411.     jz    wntall            ;want .ALL files
  1412.     jmp    ntlall            ;if .EXT other than .ALL entered
  1413. wntall:    call    LoadAll
  1414.     jmp    nxcmd
  1415.  
  1416. LoadAll:
  1417.     mov    EXTflag,0
  1418. ;try to load any file with name.COM, .EXE, or .SYS
  1419.     call    prtstr
  1420.     db    cr,lf,'Loading target file..',0
  1421.     mov    EXTflag,'C'        ;in case a .COM is found
  1422.     mov    bx,offset LitCOM
  1423.     call    EXTtoSpec        ;'COM',0 to filespec
  1424.     call    LoadPGM
  1425.     jnc    TargetLoadDone        ;if successful
  1426.     mov    EXTflag,'E'
  1427.     mov    bx,offset LitEXE
  1428.     call    EXTtoSpec
  1429.     call    LoadPGM
  1430.     jnc    TargetLoadDone
  1431.     mov    EXTflag,0
  1432.     mov    bx,offset LitSYS
  1433.     call    EXTtoSpec
  1434.     call    LoadPGM
  1435.     jnc    TargetLoadDone
  1436.     call    prtstr
  1437.     db    tab,tab,tab,'.COM, .EXE, or .SYS FILE NOT FOUND',0
  1438. TargetLoadDone:
  1439.     mov    bx,offset LitREM
  1440.     call    EXTtoSpec
  1441.     call    prtstr
  1442.     db    cr,lf,'Loading .REM file..',0
  1443.     call    LoadREM
  1444.     mov    bx,offset LitCTL
  1445.     call    EXTtoSpec
  1446.     call    prtstr
  1447.     db    cr,lf,'Loading .CTL file..',0
  1448.     call    LoadCTL
  1449.     mov    bx,offset LitSMB
  1450.     call    EXTtoSpec
  1451.     call    prtstr
  1452.     db    cr,lf,'Loading .SMB file..',0
  1453.     call    LoadSMB
  1454.     call    crlf
  1455.     ret
  1456.  
  1457. ntlall:    mov    bx,DotPtr
  1458.     inc    bx
  1459.     mov    cl,3
  1460.     mov    dx,offset LitSMB    ;LitSMB holds 'SMB'
  1461.     call    cmpstr
  1462.     jnz    AintSMB
  1463.     call    LoadSMB
  1464.     call    crlf
  1465.     jmp    nxcmd
  1466.  
  1467. AintSMB:
  1468.     mov    dx,offset LitCTL
  1469.     call    cmpstr
  1470.     jnz    AintCTL
  1471.     call    LoadCTL
  1472.     call    crlf
  1473.     jmp    nxcmd
  1474.  
  1475. AintCTL:
  1476.     mov    dx,offset LitREM
  1477.     call    cmpstr
  1478.     jnz    AintREM
  1479.     call    LoadREM
  1480.     call    crlf
  1481.     jmp    nxcmd
  1482.  
  1483. AintREM:
  1484.     mov    dx,offset LitALL
  1485.     call    cmpstr
  1486.     jnz    AsTarget
  1487.     call    LoadALL
  1488.     jmp    nxcmd
  1489.  
  1490. ;load any other .ext as target pgm
  1491. AsTarget:
  1492.     mov    EXTflag,0
  1493.     mov    dx,offset LitCOM
  1494.     call    cmpstr
  1495.     jnz    TryEXE
  1496.     mov    EXTflag,'C'
  1497.     jmp    short NowLd
  1498. TryEXE:    mov    dx,offset LitEXE
  1499.     call    cmpstr
  1500.     jnz    NowLd
  1501.     mov    EXTflag,'E'
  1502. NowLd:    call    LoadPGM
  1503.     jnc    TgtMsg
  1504.     call    OpenError
  1505.     call    crlf
  1506.     jmp    nxcmd
  1507.  
  1508. TgtMsg:    call    prtstr
  1509.     db    'Loaded specified file as target program.',cr,lf,0
  1510.     jmp    nxcmd
  1511.  
  1512. ;--------------------------------
  1513. ;LOAD pgm at curpar (end of RE-SOURC + buffers) & set pcntr to 0
  1514.  
  1515. LoadPGM:
  1516.     call    fopen            ; open file. Saves BX.
  1517.     jnc    cmdlds            ; opened successfully
  1518.     ret
  1519. ;this is approx 1A70 in code
  1520. cmdlds:    call    erstbl            ; erase seg table (presently unused)
  1521.     mov    segsho,205        ; reset cmd line arrow
  1522.     call    ClearTables        ; reset ctl, rem, smb tables
  1523.     mov    ah,42h            ; move pointer, returns size in DX:AX
  1524.     mov    al,2            ; move to EOF + CX:DX
  1525.     xor    cx,cx
  1526.     xor    dx,dx
  1527.     mov    bx,Handle
  1528.     int    21h
  1529.     mov    PgmBytes,ax
  1530.     mov    PgmBytes+2,dx
  1531. ;convert Pgmbytes to paras
  1532.     mov    cx,4
  1533. llll:    shr    dx,1
  1534.     rcr    ax,1
  1535.     loop    llll
  1536.     or    dx,dx            ;over 1 meg ?
  1537.     jnz    pppp
  1538.     cmp    ax,0FFFEh        ;just at 1 meg ?
  1539.     jna    oooo
  1540. pppp:    mov    ax,0FFFEh    ;1 meg max, ALLOC MEM below is more limiting
  1541. oooo:    inc    ax            ; for round-off
  1542.     mov    PgmParas,ax        ; size of Target Pgm in paragraphs
  1543. ;reset file pointer to start of file
  1544.     mov    ah,42h            ;move file pointer
  1545.     xor    al,al            ;move to CX:DX
  1546.     xor    cx,cx
  1547.     xor    dx,dx
  1548.     mov    bx,Handle
  1549.     int    21h
  1550. ;Store locn of end of RE-SOURCE
  1551.     mov    bx,rembas        ; length of RE-SOURC program
  1552.     mov    cl,4
  1553.     shr    bx,cl
  1554.     add    bx,600h            ; 24K in paras, for remark table
  1555.     mov    ax,cs
  1556.     add    ax,bx            ; seg of end of RE-SOURC w/buffers,
  1557.     mov    curpar,ax        ;  = current para of target pgm
  1558. ;change size of allocated memory
  1559.     mov    bx,cs            ;no math on seg registers !
  1560.     sub    ax,bx            ;length of RE-SOURCE in paras
  1561.     add    ax,PgmParas
  1562.     jnc    nnnn
  1563.     mov    ax,0FFFFh        ;crude trap for over 1 Meg
  1564. nnnn:    mov    bx,ax            ;paras requested
  1565.     push    cs
  1566.     pop    es            ;seg of block to change
  1567.     push    ax
  1568.     mov    ah,4Ah            ;change allocated block
  1569.     int    21h
  1570.     pop    ax            ;paras requested
  1571.     jnc    ReadFile
  1572. ;insufficient RAM for target program
  1573.     sub    ax,bx            ;shortfall
  1574.     mov    bx,ax
  1575.     call    prtstr            ;saves BX
  1576.     db    cr,lf,'Not enough memory, you need ',0
  1577.     call    Print00BX_
  1578.     call    prtstr
  1579.     db    ' paras more...',cr,lf,0
  1580.     clc                ;no '.COM, etc NOT FOUND' message
  1581.     ret
  1582. ;Read a file with 32-bit length
  1583. ;(this might be simpler if you can read 0 bytes)
  1584. ReadFile:
  1585.     mov    ParasRead,0
  1586.     mov    cx,PgmBytes        ;bytes to load, lo word
  1587.     mov    dx,word ptr PgmBytes+2    ;hi word
  1588. ReadMore:
  1589.     or    dx,dx            ;over 64K left ?
  1590.     jnz    Read64            ;yes, read 64K bytes
  1591.     push    dx            ;will pop as CX so CX:DX=0 => done
  1592.     jmp    short ReadSome        ;read CX bytes
  1593.  
  1594. Read64:    sub    cx,0FFFFh
  1595.     sbb    dx,0            ;DX:CX = DX:CX - 64K
  1596.     push    cx
  1597.     mov    cx,0FFFFh        ;read 1st 64K
  1598. ReadSome:
  1599.     push    dx
  1600.     mov    bx,Handle
  1601.     push    ds
  1602.     mov    ax,curpar        ;end of RE-SOURCE and its buffers
  1603.     add    ax,ParasRead
  1604.     mov    ds,ax            ;  is seg of target buffer
  1605.     xor    dx,dx            ;start target buffer on para boundary
  1606.     mov    ah,3Fh            ;read w/handle, 64K bytes max
  1607.     int    21h
  1608.     pop    ds
  1609.     pop    dx
  1610.     pop    cx
  1611.     jc    ReadErr
  1612. ;are we done reading ?
  1613.     add    ParasRead,1000h
  1614.     or    cx,cx
  1615.     jnz    ReadMore
  1616.     or    dx,dx
  1617.     jnz    ReadMore
  1618.     call    prtstr
  1619.     db    'Size of loaded file in paragraphs = ',0
  1620.     mov    bx,PgmParas
  1621.     call    Print00BX_
  1622.     call    CrLf
  1623.     call    fclose        ;reads use fclose, writes use WriteNclose
  1624.     mov    pcntr,0            ;'real' addr to unassemble
  1625.     mov    DumpStart,0        ;Dump command's start addr
  1626. ;set END & ORG
  1627.     cmp    word ptr PgmBytes+2,0
  1628.     jnz    CantEnd
  1629.     mov    dx,PgmBytes        ;lo word of file length***MAX 64K !!
  1630.     mov    al,'E'
  1631.     call    ALtoCTLatDX
  1632. CantEnd:
  1633.     mov    curorg,0
  1634.     cmp    EXTflag,'C'
  1635.     jnz    OrgZero
  1636. ;It's a .COM file, set ORG
  1637.     mov    curorg,100h
  1638. OrgZero:
  1639.     mov    ChgFlag,0        ;for 'Update/Exit'
  1640.     clc                ;no '.COM, .EXE, etc NOT FOUND'
  1641.     ret
  1642.  
  1643. ReadErr:
  1644.     push    ax
  1645.     call    prtstr
  1646.     db    cr,lf,'Error reading file: Func 3Fh, AX returned ',0
  1647.     pop    bx
  1648.     call    Print00BX_
  1649.     call    prtstr
  1650.     db    'hex',cr,lf,0
  1651.     ret
  1652.  
  1653. ;--------------------------------
  1654. LoadSMB:
  1655.     mov    bx,symbas        ;table start
  1656.     mov    REMflag,0        ;do SMB, not REM file
  1657.     call    LoadREMorSMB
  1658.     jc    gggg
  1659.     mov    symtp,bx
  1660.     mov    byte ptr [bx+3],0    ;zero count = end flag
  1661.     clc
  1662. gggg:    ret                ;w/C set if not found
  1663.  
  1664. LoadREM:
  1665.     mov    bx,remtbl
  1666.     mov    REMflag,1
  1667.     call    LoadREMorSMB
  1668.     jnc    MarkRemEnd
  1669.     ret
  1670.  
  1671. MarkRemEnd:
  1672.     mov    remend,bx
  1673.     mov    word ptr [bx],0FFFFh
  1674.     ret
  1675.  
  1676. LoadREMorSMB:
  1677.     call    fopen            ;C set if file not found
  1678.     jnc    RemSmbCharLoop
  1679.     call    OpenError        ;print 'File Not Found'
  1680.     ret
  1681.  
  1682. RemSmbCharLoop:
  1683.     call    GetByte            ;get 1 byte from buffer, read if req'd
  1684.     cmp    al,1Ah
  1685.     jnz    l0b6c
  1686.     call    fclose
  1687.     ret
  1688.  
  1689. l0b6c:    cmp    al,' '
  1690.     jb    RemSmbCharLoop        ;eat CR, LF, ctrl chars
  1691.     call    hexbin            ;hex to binary, variable, space ends
  1692.     mov    [bx],dx
  1693.     inc    bx
  1694.     inc    bx
  1695.     test    byte ptr REMflag,1    ;DAMN MASM requires BYTE PTR
  1696.     jnz    drdsk1
  1697. ;for SMB file only:
  1698.     call    GetByte
  1699.     mov    [bx],al            ;OprndType byte
  1700.     inc    bx
  1701.     call    GetByte            ;eat delim space
  1702. drdsk1:    push    bx            ;save locn for count
  1703.     inc    bx
  1704.     xor    ch,ch
  1705. lpasld:    call    GetByte
  1706.     cmp    al,tab
  1707.     jz    FoundDelim
  1708.     cmp    al,cr
  1709.     jz    FoundDelim
  1710.     mov    [bx],al
  1711.     inc    bx
  1712.     inc    ch            ;char count
  1713.     jmp    lpasld
  1714.  
  1715. FoundDelim:
  1716.     pop    si
  1717.     xchg    bx,si
  1718.     push    si
  1719.     mov    [bx],ch            ;store byte count
  1720.     pop    bx
  1721.     jmp    RemSmbCharLoop
  1722.  
  1723. hexbin:    xor    dx,dx
  1724. l0ba3:    cmp    al,' '
  1725.     jnz    l0ba8
  1726.     ret
  1727.  
  1728. l0ba8:    cmp    al,1Ah
  1729.     jnz    l0baf
  1730.     jmp    UnexpEOF
  1731.  
  1732. l0baf:    call    DigitToDX
  1733.     call    GetByte
  1734.     cmp    al,1Ah
  1735.     jnz    l0ba3
  1736.     jmp    UnexpEOF
  1737.  
  1738. DigitToDX:
  1739.     cmp    al,'9'+1        ;can it be decimal digit ?
  1740.     jb    l0bb5
  1741.     sub    al,7            ;alpha to hex
  1742. l0bb5:    sub    al,'0'            ;30h, to binary
  1743.     add    dx,dx
  1744.     add    dx,dx
  1745.     add    dx,dx
  1746.     add    dx,dx            ;now DX times 16d
  1747.     add    al,dl
  1748.     mov    dl,al
  1749.     ret
  1750.  
  1751. ;--------------------------------
  1752. ;put d:\path\name entered in GTCMD into FileString
  1753. CmPath:    mov    bx,offset cmdbuf+3    ;1st byte past the 'P'
  1754.     mov    di,offset FileString
  1755.     call    MoveField        ;stops at CR or '.'
  1756.     mov    byte ptr [di],'.'
  1757.     mov    DotPtr,di
  1758.     jmp    nxcmd
  1759. ;--------------------------------
  1760. CmRAMpara:
  1761.     mov    bx,offset cmdbuf+3    ;1st char after the R
  1762.     mov    al,[bx]
  1763.     cmp    al,cr
  1764.     jnz    NewPara
  1765.     call    ShowAddr        ;just show curr value
  1766.     jmp    nxcmd
  1767. NewPara:
  1768.     mov    EXTflag,0        ;in case a .SMB file is to be loaded
  1769.     call    gtval            ;hex no. entered - curorg to DX
  1770.     add    dx,curorg
  1771.     cmp    al,cr            ;end of entry ?
  1772.     jz    RAMparaOK
  1773.     call    cmerr
  1774. RAMparaOK:
  1775.     mov    curpar,dx
  1776.     mov    DotPtr,0        ;to flag .RSM header routine
  1777.     mov    curorg,0        ;ORG = 0 for RAM unassemblies
  1778.     call    ShowAddr
  1779.     jmp    cmpurg            ;Dump .REM, .CTL, .SMB tables ?
  1780.  
  1781. ShowAddr:
  1782.     call    prtstr
  1783.     db    'ORG = 0 at ',0
  1784.     mov    bx,curpar
  1785.     call    Print00BX_
  1786.     call    prtstr
  1787.     db    ': 0000',0
  1788.     call    CrLf
  1789.     ret
  1790.  
  1791. ;--------------------------------
  1792.  
  1793. ;erase the seg tables - called by Load .COM file, cmpurg
  1794. erstbl:    mov    bx,offset cstbl
  1795.     mov    nrsegs,0
  1796.     mov    ch,8
  1797. etlp1:    mov    cl,5
  1798.     mov    ax,'  '
  1799. etlp2:    mov    [bx],ax
  1800.     xor    ax,ax
  1801.     inc    bx
  1802.     inc    bx
  1803.     dec    cl
  1804.     jnz    etlp2
  1805.     inc    bx
  1806.     inc    bx
  1807.     dec    ch
  1808.     jnz    etlp1
  1809.     ret
  1810.  
  1811. ;--------------------------------
  1812. SaveAll:
  1813.     mov    ChgFlag,0        ;for 'Update/Exit' in CmExit
  1814.     mov    dx,remend
  1815.     mov    bx,remtbl
  1816.     cmp    bx,dx
  1817.     jz    nosrem
  1818.     mov    bx,offset LitREM
  1819.     call    EXTtoSpec
  1820.     call    prtstr
  1821.     db    cr,lf,'Saving .REM file..',0
  1822.     call    SaveREM
  1823. nosrem:    mov    dx,symtp
  1824.     mov    bx,symbas
  1825.     cmp    bx,dx
  1826.     jz    nossym
  1827.     mov    bx,offset LitSMB
  1828.     call    EXTtoSpec
  1829.     call    prtstr
  1830.     db    cr,lf,'Saving .SMB file..',0
  1831.     call    SaveSMB
  1832. nossym:    mov    dx,ctltop
  1833.     mov    bx,offset ctlbas
  1834.     cmp    bx,dx
  1835.     jnz    havctl
  1836.     jmp    nxcmd
  1837. havctl:    mov    bx,offset LitCTL
  1838.     call    EXTtoSpec
  1839.     call    prtstr
  1840.     db    cr,lf,'Saving .CTL file..',0
  1841.     call    prtstr
  1842.     db    cr,lf,0
  1843.     jmp    SaveCTL
  1844.  
  1845. ;--------------------------------
  1846. ;save labels (routine at l0bf4 also used to save remark table)
  1847. SaveSMB:
  1848.     mov    bx,symbas
  1849.     mov    REMflag,0        ;saving .SMB, not .REM
  1850.  
  1851. l0bf4:    call    creatf
  1852. l0bf7:    mov    dx,[bx]            ;address in rem or smb table
  1853.     inc    bx            ;to 2nd addr byte
  1854.     test    byte ptr REMflag,1
  1855.     jnz    sdskp1            ;if .REM, no type byte
  1856.     inc    bx
  1857.     mov    ah,[bx]            ;OprndType byte
  1858. sdskp1:    inc    bx
  1859.     mov    al,[bx]            ;string length
  1860.     inc    bx            ;to 1st byte of string
  1861.     mov    ch,al
  1862.     or    al,al
  1863.     jz    oufend            ;end of table found
  1864.     push    ax            ;save OprndType byte
  1865.     call    outadr            ;convert to hex & write 4 char number
  1866.     mov    al,' '
  1867.     call    WriteChar
  1868.     pop    ax
  1869.     test    byte ptr REMflag,1
  1870.     jnz    StringLoop        ;if doing REM, not SMB
  1871.     mov    al,ah            ;get OprndType byte
  1872.     call    WriteChar
  1873.     mov    al,' '
  1874.     call    WriteChar
  1875. StringLoop:
  1876.     mov    al,[bx]
  1877.     call    WriteChar
  1878.     inc    bx
  1879.     dec    ch
  1880.     jnz    StringLoop
  1881.     mov    al,cr
  1882.     call    WriteChar
  1883.     mov    al,lf
  1884.     call    WriteChar
  1885.     jmp    l0bf7
  1886.  
  1887. oufend:    call    WriteNclose        ;flush buffer to disk
  1888.     ret
  1889.  
  1890. outadr:    mov    al,dh
  1891.     call    hexl
  1892.     call    WriteChar
  1893.     mov    al,dh
  1894.     call    hexr
  1895.     call    WriteChar
  1896.     mov    al,dl
  1897.     call    hexl
  1898.     call    WriteChar
  1899.     mov    al,dl
  1900.     call    hexr
  1901.     jmp    WriteChar
  1902.  
  1903. ;--------------------------------
  1904. ChkNoFSpec:
  1905.     cmp    DotPtr,0        ;any filespec been entered ?
  1906.     jz    PutRAMaddr
  1907.     ret
  1908. ;R command has been used, or no file has been loaded
  1909. PutRAMaddr:
  1910.     mov    di,offset FileString
  1911.     mov    bx,offset SEG_string
  1912.     call    MoveField
  1913.     mov    bx,di
  1914.     mov    ax,curpar
  1915.     xchg    al,ah
  1916.     call    StoreHex        ;AL to 2 hex bytes [BX] & inc BX
  1917.     xchg    al,ah
  1918.     call    StoreHex
  1919.     mov    byte ptr [bx],'.'
  1920.     mov    DotPtr,bx
  1921.     ret
  1922.  
  1923. ;Enable saving .RSM file as you Unasm
  1924. CmWriteRSM:
  1925.     mov    ASMopenFlag,1
  1926.     mov    wfiflg,0        ;don't write message to file
  1927.     call    ChkNoFSpec        ;save as 'SEG_nnnn.RSM' if doing RAM
  1928.     mov    bx,offset LitRSM
  1929.     call    EXTtoSpec
  1930.     call    creatf
  1931.     call    prtstr
  1932.     db    '  Writing .RSM is enabled... '
  1933.     db    'use Z command to close file before END',cr,lf,cr,lf,0
  1934. ;create .RSM header (title, org addr, equ's for labels outside the pgm)
  1935.     mov    wfiflg,1        ;write to both screen & file
  1936.     call    pstg
  1937.     db    ';Re-Source Disassembly of ',0
  1938.     mov    bx,offset FileString
  1939. FileNameLoop:
  1940.     mov    al,[bx]
  1941.     cmp    al,'.'            ;don't print '.RSM'
  1942.     jz    PrintHeader
  1943.     or    al,al            ;end of string ?
  1944.     jz    PrintHeader
  1945.     call    typech
  1946.     inc    bx
  1947.     jmp    short FileNameLoop
  1948.  
  1949. PrintHeader:
  1950.     test    Direc286Flag,1
  1951.     jz    NoDirec
  1952.     call    pstg
  1953.     db    cr,lf,'.286P',0        ;file has '186+ instr's
  1954. ;note: .386P calls MOV  wr,OFFSET H001234 "illegal size for operand"
  1955. NoDirec:
  1956.     call    pstg
  1957.     db    cr,lf,cr,lf,'cr',tab,'EQU',tab,'0Dh'
  1958.     db    cr,lf,'lf',tab,'EQU',tab,'0Ah'
  1959.     db    cr,lf,'tab',tab,'EQU',tab,'9'
  1960.     db    cr,lf,'bel',tab,'EQU',tab,'7'
  1961.     db    cr,lf,cr,lf,'CSEG',tab,'segment',tab,'byte public',0
  1962.     cmp    EXTflag,'E'
  1963.     jz    SegsDone
  1964.     call    pstg
  1965.     db    cr,lf,tab,'assume',tab,'CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG',0
  1966. SegsDone:
  1967.     mov    OutsideFlag,0        ;don't print header if none outside
  1968.     xor    cx,cx            ;start at beginning of pgm
  1969.     mov    bx,symbas
  1970. FarLabelLoop:
  1971.     inc    bx
  1972.     inc    bx
  1973.     inc    bx            ;>length byte
  1974.     mov    al,[bx]
  1975.     or    al,al            ;0 marks end of table
  1976.     jnz    l032c            ;not table end, check for more labels
  1977.     cmp    EXTflag,'E'
  1978.     jz    OrgDone
  1979.     call    pstg
  1980.     db    cr,lf,cr,lf,tab,'ORG',tab,0
  1981.     mov    dx,curorg
  1982.     call    PrintDXh
  1983. OrgDone:
  1984.     call    CrLf
  1985.     call    CrLf
  1986.     jmp    nxcmd
  1987.  
  1988. l032c:    dec    bx
  1989.     dec    bx
  1990.     dec    bx            ;>addr @ 1st of entry
  1991.     push    bx
  1992.     push    cx            ;pointer to code
  1993.     inc    bx
  1994.     inc    bx
  1995.     inc    bx
  1996. ;only print labels outside the pgm
  1997.     push    bx            ;>length byte
  1998.     dec    bx
  1999.     dec    bx
  2000.     dec    bx
  2001.     mov    dx,[bx]            ;label's addr
  2002.     cmp    dx,PgmBytes        ;1st after pgm, locn of END**64K max**
  2003.     jb    nodisp
  2004.     pop    bx
  2005. ;print the label
  2006.     cmp    OutsideFlag,0
  2007.     jnz    NoOutsideHdr
  2008.     call    pstg
  2009.     db    cr,lf,cr,lf,';Labels outside the program:',cr,lf,0
  2010.     mov    OutsideFlag,1        ;flag it's been printed
  2011. NoOutsideHdr:
  2012.     mov    ch,[bx]            ;length of label
  2013. l0362:    inc    bx
  2014.     mov    al,[bx]
  2015.     call    typech
  2016.     dec    ch
  2017.     jnz    l0362
  2018.     call    pstg
  2019.     db    tab,'EQU',tab,'$+',0
  2020.     pop    cx            ;pointer to code
  2021.     pop    bx            ;>addr @ 1st of entry
  2022.     push    bx
  2023.     mov    dx,[bx]
  2024.     inc    bx
  2025.     inc    bx            ;to type byte
  2026.     add    dx,curorg        ;correct all addrs for ORG
  2027.     mov    al,dh
  2028.     call    xo0
  2029.     mov    al,dl
  2030.     call    xo
  2031.     call    pstg
  2032.     db    'h',cr,lf,0
  2033.     pop    bx            ;>addr @ 1st of entry
  2034. l0394:    inc    bx
  2035.     inc    bx
  2036.     inc    bx            ;to 4th (length) byte
  2037.     mov    al,[bx]
  2038.     xor    ah,ah
  2039.     add    bx,ax
  2040.     inc    bx            ;to 1st of next label entry
  2041.     call    BreakChk        ;test for Ctrl-Break
  2042.     jmp    FarLabelLoop        ;loop to next entry in symbol table
  2043.  
  2044. nodisp:    pop    bx
  2045.     pop    cx
  2046.     pop    bx
  2047.     jmp    l0394
  2048. ;--------------------------------
  2049.  
  2050. SaveREM:
  2051.     mov    REMflag,1
  2052.     mov    bx,remend
  2053.     inc    bx
  2054.     inc    bx            ;2 bytes past end
  2055.     mov    byte ptr [bx],0        ;mark length byte so end will be found
  2056.     mov    bx,remtbl
  2057.     jmp    l0bf4
  2058.  
  2059. ;--------------------------------
  2060. ASMstillOpenErr:
  2061.     call    prtstr
  2062.     db    'NO FILE ACCESSES UNTIL .RSM CLOSED',cr,lf,0
  2063.     jmp    nxcmd
  2064.  
  2065. ;an EOF has been found in the middle of a number, jumped to 2 places
  2066. UnexpEOF:
  2067.     call    prtstr
  2068.     db    'Unexpected EOF',cr,lf,0
  2069.     jmp    nxcmd
  2070. ;--------------------------------
  2071. ;SET CONTROL or dump CTL table
  2072.  
  2073. ;control table structure:
  2074. ;    cfence is ctltbl-1, holds mode char for 1st line
  2075. ;    each entry 4 bytes: 1 byte segment char,
  2076. ;    2 byte address, 1 byte mode char (BEHISW).
  2077. ;    Table terminated by 0FFFFh in address bytes
  2078.  
  2079. cmctl:    ;call    sgreqs
  2080.     mov    bx,offset cmdbuf+3    ;1st byte after the C in the command
  2081.     mov    al,[bx]
  2082.     cmp    al,cr            ;C alone ?
  2083.     jnz    ChkNnList        ;command has more than C
  2084.     jmp    ShowCTLtable
  2085.  
  2086. ChkNnList:
  2087.     call    gtval
  2088.     cmp    al,cr            ;C and just a no. 
  2089.     jnz    setctl            ;more follows the number
  2090.     jmp    ListCtl            ;list .CTL from NNNN
  2091.  
  2092. setctl:    call    delim
  2093. l0d5a:    inc    bx
  2094.     mov    al,[bx]            ;BEHISW to use
  2095.     call    ALtoCTLatDX        ;make a manual entry in .CTL table
  2096.     jmp    nxcmd
  2097.  
  2098. ;called by A command only.  Enter w/new char in AL, DX=locn
  2099. EnterCTL:
  2100.     push    bx
  2101.     push    dx            ;pcntr
  2102.     push    ax            ;save CTL char in AL
  2103.     call    ctlook            ;search ctl table
  2104.     jc    OldEntry        ;if table end or past right addr
  2105.     add    bx,4            ;point to curr entry
  2106. OldEntry:
  2107.     pop    ax            ;the CTL char
  2108.     pop    dx            ; and pcntr location
  2109.     dec    bx            ;to mode char at this or last locn
  2110.     cmp    al,[bx]            ;compare to current mode char
  2111.     pop    bx
  2112.     jnz    ALtoCTLatDX        ;if different from CTL at this or last
  2113.     ret
  2114.  
  2115. ;make manual entry in .CTL table - AL=ctl char, DX=addr
  2116. ALtoCTLatDX:
  2117.     mov    typndx,al    ;save CTL char (BEHIS or W)
  2118.     call    ctlook        ;if found, BX points to entry in ctltbl
  2119.     jnc    ChgExist    ;if matches an existing entry
  2120.     jmp    NewCtl        ;make a new entry
  2121.  
  2122. ChgExist:
  2123.     mov    al,typndx    ;recover the char
  2124.     call    cltrck        ;test all legal values
  2125.     mov    ChgFlag,1    ;for 'Update/Exit'
  2126.     cmp    al,'K'
  2127.     jz    KillIt
  2128.     jmp    ChgCtl        ;modify existing entry
  2129.  
  2130. KillIt:    mov    ax,[bx+1]    ;addr field of entry
  2131.     cmp    ax,0FFFFh
  2132.     jz    l0bf5        ;if at table end
  2133.     mov    cx,4        ;entry length
  2134. KillLoop:
  2135.     mov    al,[bx+4]    ;move from higher rec
  2136.     mov    [bx],al        ;down to lower rec
  2137.     inc    bx
  2138.     loop    KillLoop
  2139.     jmp    KillIt        ;repeat for rest of recs
  2140.  
  2141. ;entries past kill are all moved down
  2142. l0bf5:    sub    bx,4        ;base of last valid entry
  2143.     jmp    nxcmd
  2144.  
  2145. cltrck:    cmp    al,'K'
  2146.     jz    cltrrt
  2147. ChkValidCtl:
  2148.     cmp    al,'E'
  2149.     jz    cltrrt
  2150.     cmp    al,'B'
  2151.     jz    cltrrt
  2152.     cmp    al,'H'
  2153.     jz    cltrrt
  2154.     cmp    al,'W'
  2155.     jz    cltrrt
  2156.     cmp    al,'I'
  2157.     jz    cltrrt
  2158.     cmp    al,'S'
  2159.     jz    cltrrt
  2160.     call    cmerr
  2161. cltrrt:    ret
  2162.  
  2163. ;make a new entry in the .CTL table - AL=type, DX=addr.
  2164. ; ctlook returned C set, BX > entry for next higher addr.
  2165. NewCtl:    mov    al,typndx    ;the BEHIS or W
  2166.     call    ChkValidCtl    ;to cmerr if not valid
  2167.     mov    ChgFlag,1    ;for 'Update/Exit'
  2168.     push    dx        ;addr of the entered control
  2169.     push    bx        ;location for new entry
  2170.     mov    bx,offset ctlbas
  2171. FindEndLoop:
  2172.     mov    ax,[bx+1]    ;addr of this entry
  2173.     add    bx,4        ;to start next entry
  2174.     cmp    ax,0FFFFh    ;end of table ?
  2175.     jnz    FindEndLoop
  2176. ;now BX points to the end-marker 0FFFFh entry
  2177.     mov    dx,bx
  2178.     add    dx,4        ;make space for new FFFF entry
  2179.     pop    cx        ;was BX, > next higher entry
  2180. entrc8:    dec    bx        ;to seg (1st) char first
  2181.     dec    dx        ;dest
  2182.     mov    al,[bx]        ;old entry byte
  2183.     xchg    bx,dx
  2184.     mov    [bx],al        ;to new place higher
  2185.     xchg    bx,dx
  2186.     cmp    dx,cx        ;at insert location yet?
  2187.     jnz    entrc8        ;no, loop
  2188. ;make the entry
  2189.     mov    bx,cx        ;restore table pointer
  2190.     pop    dx        ;pcntr value to store
  2191.     mov    ch,segsho    ;segment char (now always 205d)
  2192.     mov    [bx],ch
  2193.     mov    [bx+1],dx    ;store address
  2194.     mov    al,typndx
  2195.     mov    [bx+3],al    ;store CTL code
  2196.     add    bx,4
  2197.     ret
  2198.  
  2199. ;modify existing entry
  2200. ChgCtl:    mov    ah,segsho    ;segment char (now always 205d)
  2201.     mov    [bx],ah
  2202.     mov    [bx+3],al    ;modify existing entry (the BEHIS or W)
  2203.     ret
  2204.  
  2205. ;--------------------------------
  2206. ;Check the .CTL table for entry @DX.  4 bytes/entry.  Rets w/BX pointing
  2207. ;to ctlbas+0, +4 etc of entry for addr just past DX.  Uses AX, BX, CX; saves DX
  2208.  
  2209. ctlook:    mov    bx,offset ctlbas    ;point BX at table's start
  2210.     mov    ch,segsho        ;(presently always 205d)
  2211. LookLoop:
  2212.     mov    ax,[bx+1]        ;addr value
  2213.     cmp    ax,0FFFFh        ;end of table ?
  2214.     stc
  2215.     jnz    l0e4s            ;wasn't the end
  2216.     ret                ;w/carry set if no match below end
  2217.  
  2218. l0e4s:    cmp    ch,[bx]            ;(presently always 205d)
  2219.     jz    l0e48            ; in right segment
  2220. l0e5c:    jnb    ctlk4            ;still too low in table
  2221.     ret                ;too far, stop w/carry set
  2222.  
  2223. l0e48:    cmp    dx,[bx+1]
  2224.     jnz    l0e5c
  2225.     ret                ;found exact match
  2226.  
  2227. ctlk4:    add    bx,4            ;to next entry
  2228.     jmp    short LookLoop
  2229. ;--------------------------------
  2230.  
  2231. ListCtl:
  2232.     mov    EntriesLeft,4
  2233.     call    ctlook            ;find starting entry
  2234.     jmp    clist
  2235. ;--------------------------------
  2236. ;display the .CTL table in 4 columns
  2237. ShowCTLtable:
  2238.     mov    EntriesLeft,4
  2239.     mov    bx,offset ctlbas    ;start with first CTL entry
  2240. clist:    call    BreakChk        ;test for user break
  2241.     mov    dx,1[bx]        ;addr of entry
  2242.     add    bx,3            ;last of this entry, the BESHI or W
  2243.     cmp    dx,0FFFFh
  2244.     jnz    clist2            ;not at table end
  2245.     call    CrLf
  2246.     jmp    nxcmd
  2247.  
  2248. clist2:    mov    al,-3[bx]    ;1st of this entry, the seg char
  2249.     cmp    al,segsho    ;is special seg char showing?
  2250.     jnz    skclis        ;if so, skip this entry
  2251.     push    bx
  2252.     mov    bx,dx
  2253.     add    bx,curorg    ;correct for ORG
  2254.     call    Print00BX_    ;print location
  2255.     call    prtstr
  2256.     db    '= ',0
  2257.     pop    bx
  2258.     mov    al,[bx]
  2259.     call    typech        ;ctl char from table (BEHIS or W)
  2260.     call    prspc
  2261.     push    dx
  2262.     push    bx
  2263.     call    symluk        ;symbol at this address?
  2264.     jc    NoLblCtl
  2265. ;locn has label, CH is length, BX points to start ot text
  2266.     mov    EntriesLeft,1    ;signal no more entries on this line
  2267.     call    prtstr
  2268.     db    '= ',0
  2269.     call    PrtCHbytesPerBX
  2270. NoLblCtl:
  2271.     pop    bx
  2272.     pop    dx
  2273.     call    prspc
  2274.     call    prspc
  2275.     call    ChkEntryCt
  2276. skclis:    inc    bx
  2277.     jmp    clist
  2278.  
  2279. ;--------------------------------
  2280. SaveCTL:
  2281.     call    creatf        ;make a new file
  2282.     mov    bx,offset ctlbas ;start of CTL table
  2283. NxtEntry:
  2284.     mov    dx,1[bx]    ;address value
  2285.     cmp    dx,0FFFFh
  2286.     jz    HitEnd        ;0FFFFh is flag for end of table
  2287.     mov    al,[bx]        ;seg char
  2288.     call    WriteChar
  2289.     call    outadr        ;convert to hex & write 4 chars
  2290.     mov    al,','
  2291.     call    WriteChar
  2292.     mov    al,3[bx]
  2293.     call    WriteChar
  2294.     mov    al,cr
  2295.     call    WriteChar
  2296.     mov    al,lf
  2297.     call    WriteChar
  2298.     add    bx,4
  2299.     jmp    NxtEntry
  2300.  
  2301. HitEnd:    jmp    WriteNclose
  2302.  
  2303. ;--------------------------------
  2304. ;.CTL file format: 1 line/entry, seg byte, variable length hex address
  2305. ; (always 4 chars now), a comma, and the Ctl byte (BEHISW). E.g., ═0123,B
  2306.  
  2307. LoadCTL:
  2308.     call    fopen        ;C set if file not found
  2309.     jnc    FoundCTL
  2310.     call    OpenError
  2311.     ret
  2312.  
  2313. FoundCTL:
  2314.     mov    bx,offset ctlbas
  2315. CtlLineLoop:
  2316.     call    GetByte        ;get byte from buffer, read another 128 if empty
  2317.     cmp    al,1Ah
  2318.     jz    IsEOF
  2319.     cmp    al,' '+1
  2320.     jb    CtlLineLoop    ;eat space, CR, LF, ctrl chars
  2321.     mov    [bx],al        ;segment char (now always 205d)
  2322.     call    GetByte        ;1st byte of hex address
  2323.     xor    dx,dx        ;clear addr accumulator
  2324. CtlDigitLoop:
  2325.     cmp    al,1Ah
  2326.     jz    IsEOF
  2327.     cmp    al,','        ;comma marks end of addr field
  2328.     jz    ItsComma
  2329.     call    DigitToDX
  2330.     call    GetByte
  2331.     jmp    CtlDigitLoop
  2332.  
  2333. ItsComma:
  2334.     mov    1[bx],dx
  2335.     call    GetByte
  2336.     mov    3[bx],al
  2337.     add    bx,4
  2338.     jmp    CtlLineLoop
  2339.  
  2340. IsEOF:    mov    word ptr 1[bx],0FFFFh
  2341.     add    bx,4
  2342.     call    fclose
  2343.     ret
  2344. ;--------------------------------
  2345. ; ADD REMARKS
  2346.  
  2347. ;    remark table structure, variable length records:
  2348. ;    2 byte address, 1 byte string count, n byte string
  2349. ;    table terminated by 0ffffh in address field
  2350. ;    if 1st char = ; remark appended to instruction
  2351. ;    else remark on separate line before instruction
  2352.  
  2353. cmrem:    ;call    sgreqs
  2354.     mov    bx,offset cmdbuf+3    ;1st char after the ';'
  2355.     mov    al,[bx]
  2356.     cmp    al,cr
  2357.     jnz    cmnt1
  2358.     jmp    DumpRem            ;dump the remark table
  2359.  
  2360. cmnt1:    call    gtval        ;addr of remark to DX, corrected for ORG
  2361.     inc    bx
  2362.     cmp    al,cr
  2363.     jnz    l0f52
  2364.     jmp    adr_dmp        ;user entered ;NNNN (dump remarks from NNNN)
  2365.  
  2366. l0f52:    call    delim
  2367.     push    bx
  2368. ;at this point, a Rem will be added or deleted
  2369.     mov    ChgFlag,1    ;for 'Update/Exit'
  2370.     call    RemChk        ;point BX at entry for addr user has input
  2371.     jc    AddRem        ;jump if at end of table, no remark here
  2372.     call    delrem        ;delete any existing remark
  2373.     pop    bx        ;pointer to cmdbuf
  2374.     push    bx
  2375.     mov    al,[bx]
  2376.     cmp    al,cr        ;input was ;NNNN, (delete remark at NNNN)
  2377.     jnz    AddRem
  2378.     jmp    nxcmd
  2379. ;make new entry at end of table
  2380. AddRem:    mov    bx,remend
  2381.     mov    [bx],dx        ;addr for the new last entry
  2382.     inc    bx
  2383.     inc    bx        ;to String Count byte
  2384.     pop    si        ;points in cmdbuf
  2385.     xor    ch,ch        ;clear string count
  2386.     mov    di,bx        ;bx still holds pointer to String Count
  2387.     inc    di        ;point to first char for remark string
  2388.     push    cs
  2389.     pop    es        ;just to be sure
  2390. RemCharCopy:
  2391.     lodsb            ;get char from cmdbuf & inc SI
  2392.     cmp    al,cr        ;is it CR ?
  2393.     jz    EndRemStr
  2394.     stosb            ;put it in rem table & inc DI
  2395.     inc    ch
  2396.     jmp    short RemCharCopy
  2397. EndRemStr:
  2398.     mov    remend,di
  2399.     mov    word ptr [di],0FFFFh
  2400.     mov    [bx],ch        ;string count
  2401.     jmp    nxcmd
  2402.  
  2403. ;--------------------------------
  2404. ;point BX to entry at addr in DX.  C set if not found.
  2405. RemChk:    mov    bx,remtbl        ;points to rembas
  2406. NxtRem:    cmp    word ptr [bx],0FFFFh    ;check for end-of-table
  2407.     jnz    RemsGoOn
  2408.     stc
  2409.     ret                ;w/carry if at end of table
  2410.  
  2411. RemsGoOn:
  2412.     cmp    dx,[bx]
  2413.     jnz    l0fc3
  2414.     ret                ;w/BX > matching addr and no carry
  2415.  
  2416. l0fc3:    inc    bx
  2417.     inc    bx
  2418.     mov    al,[bx]            ;length of remark
  2419.     call    AddALtoBX
  2420.     inc    bx
  2421.     jmp    NxtRem
  2422. ;--------------------------------
  2423. adr_dmp:
  2424.     call    RemChk        ;point BX at entry user has input
  2425.     jmp    l0fd8
  2426.  
  2427. ;dump the remarks table to the screen
  2428. DumpRem:
  2429.     mov    bx,remtbl    ;point BX at start of table
  2430. l0fd8:    call    BreakChk    ;check for CTRL-BREAK
  2431.     mov    dl,[bx]
  2432.     inc    bx
  2433.     mov    dh,[bx]
  2434.     inc    bx
  2435.     mov    al,dh
  2436.     and    al,dl
  2437.     inc    al
  2438.     jnz    l0fec
  2439.     jmp    nxcmd
  2440.  
  2441. l0fec:    xchg    bx,dx
  2442.     push    bx
  2443.     add    bx,curorg    ;correct printed address for ORG
  2444.     call    Print00BX_
  2445.     pop    bx
  2446.     xchg    bx,dx
  2447.     mov    al,';'
  2448.     call    typech
  2449.     mov    ch,[bx]        ;length of remark
  2450. l0ffa:    inc    bx
  2451.     mov    al,[bx]
  2452.     call    typech
  2453.     dec    ch
  2454.     jnz    l0ffa
  2455.     call    CrLf
  2456.     inc    bx
  2457.     jmp    l0fd8
  2458. ;--------------------------------
  2459. ;enter w/BX > entry for addr in DX that user has input.  Saves DX.
  2460. delrem:    cmp    word ptr [bx],0FFFFh
  2461.     jnz    l1015
  2462.     ret            ;if at end of table
  2463.  
  2464. l1015:    push    dx
  2465.     mov    dx,bx        ;now DX > start of entry to overwrite
  2466.     inc    bx
  2467.     inc    bx
  2468.     mov    al,[bx]
  2469.     call    AddALtoBX
  2470.     inc    bx        ;to start of next entry's string
  2471.     xor    ch,ch
  2472. l1023:    mov    al,[bx]
  2473.     xchg    bx,dx
  2474.     mov    [bx],al
  2475.     xchg    bx,dx
  2476.     inc    bx
  2477.     inc    dx
  2478.     mov    cl,al        ;char just moved
  2479.     and    al,ch        ;AND previous char moved
  2480.     inc    al        ;if both were 0FFh, gives Z
  2481.     mov    ch,cl        ;save char just moved
  2482.     jnz    l1023        ;loop if not at end of table
  2483.     xchg    bx,dx
  2484.     dec    bx
  2485.     dec    bx
  2486.     mov    remend,bx
  2487.     pop    dx
  2488.     ret
  2489.  
  2490. ;==============================================================================
  2491. ;Start of actual disassembly routines.
  2492.  
  2493. LitStart db    'Start'
  2494.  
  2495. ;Print any label to screen and file, space & addr at start of line to scrn only
  2496. AddrOrSmb:
  2497.     push    ax
  2498.     push    dx
  2499.     push    bx
  2500.     mov    wfiflg,1    ;print to output file, too
  2501.     mov    dx,pcntr
  2502. ;insert 'Start' in B mode if .COM file at 100h, for MASM
  2503.     cmp    BmodeFlag,0
  2504.     jz    NoStart
  2505.     or    dx,dx
  2506.     jnz    NoStart
  2507.     cmp    EXTflag,'C'
  2508.     jnz    NoStart
  2509.     mov    bx,offset LitStart
  2510.     mov    ch,5        ;length of 'Start'.  DX is already 0000.
  2511.     call    symtch        ;inserts sym if not already present
  2512. NoStart:
  2513.     mov    dx,pcntr
  2514.     call    symluk        ;BX>label, CH=label length, carry if no label
  2515.     jc    NoLblHere
  2516. ;print the label
  2517.     push    cx        ;save label's length
  2518.     call    PrtCHbytesPerBX
  2519.     pop    cx
  2520. ;check for non-Instruction
  2521.     cmp    ColonFlag,0
  2522.     jz    ItsAnInstr
  2523. ;no addr as comment for DB, DW, DS lines, MASM req label on SAME LINE !
  2524.     cmp    ch,7
  2525.     jna    TabExit
  2526.     mov    wfiflg,1        ;now print to file, too
  2527.     call    prspc
  2528.     jmp    JusExit
  2529.  
  2530. ItsAnInstr:
  2531.     mov    al,':'
  2532.     call    typech        ;saves CX
  2533.     inc    ch        ;length of label determines no. of Tabs
  2534.     cmp    trmflg,0
  2535.     jz    AddrAsComment
  2536. ;trim is on, check for label over 7 chars long
  2537.     cmp    ch,7
  2538.     jna    TabExit
  2539.     call    CrLf
  2540.     jmp    TabExit
  2541.  
  2542. AddrAsComment:
  2543.     call    PrtTab
  2544.     call    PrtTab
  2545.     cmp    ch,8
  2546.     jae    NoMoreTab
  2547.     call    PrtTab        ;extra tab to keep label addr's aligned
  2548. NoMoreTab:
  2549.     call    semic        ;print a semicolon
  2550.     mov    bx,pcntr
  2551.     add    bx,curorg    ;correct for ORG
  2552.     call    Print00BX_    ;print address
  2553.     call    CrLf
  2554.     jmp    TabExit
  2555.  
  2556. ;line has no label, just print address
  2557. NoLblHere:
  2558.     mov    wfiflg,0        ;don't print to .RSM file, just screen
  2559.     call    prspc            ;print the space at start of line
  2560.     mov    bx,pcntr
  2561.     add    bx,curorg        ;correct for ORG
  2562.     call    Print00BX_        ;print address
  2563. TabExit:
  2564.     mov    wfiflg,1        ;now print to file, too
  2565.     call    PrtTab
  2566. JusExit:
  2567.     pop    bx
  2568.     pop    dx
  2569.     pop    ax
  2570.     ret
  2571.  
  2572. ;--------------------------------
  2573. ;UNASSEMBLE A LINE OF CODE at [curpar:pcntr]  - always called w/wfiflg=0
  2574.  
  2575. dline:    mov    es,curpar
  2576.     mov    OprndType,10h        ;DS unless changed, do correct for ORG
  2577.     mov    bx,pcntr
  2578.     mov    curadr,bx
  2579.     inc    pcntr
  2580. ;Find Op Code in opct table
  2581.     mov    ch,es:[bx]        ;first byte of code for this line
  2582.     mov    CurInstr,ch        ;also signals blank line if req'd
  2583.     mov    bx,offset opct-7
  2584.     mov    dx,7            ;size of table entry -1
  2585.  
  2586. OpLineLoop:
  2587.     add    bx,dx
  2588.     mov    al,cs:[bx]        ;starts at beginning of opct table
  2589.     or    al,al
  2590.     jnz    KeepLooking
  2591.     jmp    PrtDBandByte        ;end of table
  2592.  
  2593. KeepLooking:
  2594.     and    al,ch
  2595.     mov    cl,al            ;masked opcode
  2596.     inc    bx
  2597.     mov    al,cs:[bx]
  2598.     cmp    al,cl            ;nxt byte in opct match masked opcode?
  2599.     jnz    OpLineLoop
  2600.     inc    bx            ;to 3rd byte of line in opct,
  2601.     mov    al,cs:[bx]        ;  the instr's Kind no.
  2602.     mov    typndx,al        ;typndx also holds the BEHISW later
  2603.  
  2604. ;PRINT THE OP CODE (the instruction)
  2605.     mov    ch,5            ;every entry is 5 bytes incl the ...
  2606. OpLoop:    inc    bx
  2607.     mov    al,cs:[bx]
  2608.     cmp    al,'.'            ;dot is ignored
  2609.     jz    nodot
  2610.     call    typech            ;print opcode char
  2611. nodot:    dec    ch
  2612.     jnz    OpLoop
  2613.  
  2614.     mov    dl, typndx
  2615.     and    dl,3Fh
  2616.     xor    dh,dh
  2617.     mov    bx,offset jmptbl
  2618.     add    bx,dx
  2619.     add    bx,dx
  2620.     mov    dx,cs:[bx]
  2621.     mov    bx,curadr
  2622.     mov    al,es:[bx]
  2623. ;pick out the '186+ op codes. 0F, C0 and C1 done in kindXX routines.
  2624. ;The codes are 60-63, 68-6F, C8 and C9
  2625.     cmp    al,0C8h
  2626.     jz    Is186
  2627.     cmp    al,0C9h
  2628.     jz    Is186
  2629.     cmp    al,60h
  2630.     jb    GoJmp
  2631.     cmp    al,6Fh
  2632.     ja    GoJmp
  2633.     cmp    al,68h
  2634.     ja    Is186
  2635.     cmp    al,64h
  2636.     ja    GoJmp
  2637. Is186:    mov    Direc286Flag,1    ;this is a '186+ instr
  2638. GoJmp:    jmp    dx        ;with AL, CurInstr, BX and curadr set
  2639.  
  2640. ;Jump table is indexed by typndx.
  2641. ;See list of which codes are which KIND at opct table.
  2642.  
  2643. jmptbl    dw    offset kind00
  2644.     dw    offset kind01
  2645.     dw    offset kind02
  2646.     dw    offset kind03
  2647.     dw    offset kind04
  2648.     dw    offset kind05
  2649.     dw    offset kind06
  2650.     dw    offset kind07
  2651.     dw    offset kind08
  2652.     dw    offset kind09
  2653.     dw    offset kind10        ;'186 PUSH nnnn
  2654.     dw    offset kind11
  2655.     dw    offset kind12
  2656.     dw    offset kind13
  2657.     dw    0            ;kind14 unused
  2658.     dw    offset kind15
  2659.     dw    offset kind16
  2660.     dw    offset kind17
  2661.     dw    offset kind18
  2662.     dw    offset kind19
  2663.     dw    offset kind20
  2664.     dw    offset kind21
  2665.     dw    offset kind22        ;'286 protected mode instrs
  2666.     dw    offset kind23
  2667.     dw    offset kind24
  2668.     dw    offset kind25
  2669.     dw    offset kind26
  2670.     dw    offset kind27
  2671.     dw    offset kind28
  2672.     dw    offset kind29
  2673.     dw    offset kind30
  2674.     dw    offset kind31
  2675.     dw    offset kind32
  2676.     dw    offset kind33
  2677.     dw    offset kind34
  2678.     dw    offset kind35
  2679.     dw    offset kind36
  2680.     dw    offset kind37
  2681.     dw    offset kind38
  2682. ; - - - - - - - - - - - - - - - -
  2683. ;Routines to print the operands.  On entry:
  2684. ;BX = curadr, points to the 1st op code byte.  CurInstr holds op code.
  2685.  
  2686. kind00:    jmp    NewLine
  2687. ; - - - - - - - - - - - - - - - -
  2688. kind01:    call    PrtTab            ;IN AL or AX,DX and OUT DX,AL or AX
  2689.     mov    al,es:[bx]
  2690.     test    al,2
  2691.     jnz    k01out
  2692.     test    al,1
  2693.     jnz    k01iw
  2694.     call    pstg
  2695.     db    'AL,DX',0
  2696.     jmp    NewLine
  2697.  
  2698. k01iw:    call    pstg
  2699.     db    'AX,DX',0
  2700.     jmp    NewLine
  2701.  
  2702. k01out:    test    al,1
  2703.     jnz    k01ow
  2704.     call    pstg
  2705.     db    'DX,AL',0
  2706.     jmp    NewLine
  2707.  
  2708. k01ow:    call    pstg
  2709.     db    'DX,AX',0
  2710.     jmp    NewLine
  2711. ; - - - - - - - - - - - - - - - -
  2712. kind02:                    ;IN AX,nn and OUT nn,AX
  2713.     mov    al,es:[bx+1]
  2714.     mov    CurModRegRM,al        ;use for immed data
  2715.     inc    pcntr
  2716.     inc    curadr
  2717.     call    PrtTab
  2718.     test    byte ptr CurInstr,2    ; AND it w/2 to check bit 1
  2719.     jnz    OutnnAX
  2720.     call    pstg
  2721.     db    'AX,',0
  2722.     mov    al,CurModRegRM
  2723.     call    PrintALh
  2724.     jmp    NewLine
  2725.  
  2726. OutnnAX:
  2727.     mov    al,CurModRegRM
  2728.     call    PrintALh        ;print port no.
  2729.     call    pstg
  2730.     db    ',AX',0
  2731.     jmp    NewLine
  2732.  
  2733. ; - - - - - - - - - - - - - - - -
  2734. kind37:                    ;IN AL,nn and OUT nn,AL
  2735.                     ;same as kind02 above, except AL
  2736.     mov    al,es:[bx+1]
  2737.     mov    CurModRegRM,al        ;use for immed data
  2738.     inc    pcntr
  2739.     inc    curadr
  2740.     call    PrtTab
  2741.     test    byte ptr CurInstr,2    ; AND it w/2 to check bit 1
  2742.     jnz    OutnnAL
  2743.     call    pstg
  2744.     db    'AL,',0
  2745.     mov    al,CurModRegRM
  2746.     call    PrintALh
  2747.     jmp    NewLine
  2748.  
  2749. OutnnAL:
  2750.     mov    al,CurModRegRM
  2751.     call    PrintALh        ;print port no.
  2752.     call    pstg
  2753.     db    ',AL',0
  2754.     jmp    NewLine
  2755.  
  2756. ; - - - - - - - - - - - - - - - -
  2757. kind03:    call    PrtTab            ;MOV immed data to reg
  2758.     mov    al,es:[bx]        ;get the op code
  2759.     inc    pcntr
  2760.     inc    curadr
  2761.     test    al,8
  2762.     jnz    k03Word
  2763.     and    al,7
  2764.     call    namrg8
  2765.     call    comma
  2766.     call    bytopd
  2767.     jmp    NewLine
  2768.  
  2769. k03Word:
  2770.     inc    pcntr
  2771.     and    al,7
  2772.     call    namr16
  2773.     call    comma
  2774.     jmp    ImmedWord
  2775.  
  2776. ; - - - - - - - - - - - - - - - -
  2777. kind04:                    ;byte arith, logic, CMP, TEST to AL
  2778.     inc    pcntr
  2779.     call    PrtTab
  2780.     call    pstg
  2781.     db    'AL,',0
  2782.     mov    al,CurInstr
  2783.     inc    curadr
  2784.     jmp    OldArith
  2785. ; - - - - - - - - - - - - - - - -
  2786.  
  2787. ;ONE-BYTE operand shown as ASCII if so
  2788. bytopd:    mov    bx,curadr    ;has been inc'd
  2789.     mov    al,es:[bx]    ;get data byte
  2790.     push    ax
  2791.     call    PrtALasDB    ;C set => don't show comment hex
  2792.     pop    ax
  2793.     jnc    ShAsCm
  2794.     ret
  2795.  
  2796. ShAsCm:    push    ax
  2797.     call    PrtTab
  2798.     call    PrtTab
  2799.     call    semic        ;print semicolon
  2800.     pop    ax
  2801.     jmp    PrintALh    ;print actual code byte
  2802.  
  2803. PrtALasDB:
  2804.     cmp    al,cr
  2805.     jnz    cccc
  2806.     call    pstg
  2807.     db    'cr',0
  2808.     clc            ;show as comment hex
  2809.     ret
  2810.  
  2811. cccc:    cmp    al,lf
  2812.     jnz    dddd
  2813.     call    pstg
  2814.     db    'lf',0
  2815.     clc
  2816.     ret
  2817.  
  2818. dddd:    cmp    al,' '
  2819.     jb    JustPrtNumber
  2820.     cmp    al,'z'+1
  2821.     jnb    JustPrtNumber
  2822. ;print AL in quotes
  2823.     call    apostrophe
  2824.     cmp    al,''''
  2825.     jnz    Normal
  2826.     call    apostrophe    ;print an extra '
  2827. Normal:    call    typech
  2828.     call    apostrophe    ;print ending quote
  2829.     clc            ;show as comment hex
  2830.     ret
  2831.  
  2832. JustPrtNumber:
  2833.     call    PrintALh
  2834.     stc            ;don't show as comment hex
  2835.     ret
  2836.  
  2837. ; - - - - - - - - - - - - - - - -
  2838. kind05:    call    PrtTab        ;CALL/long JMP to relative address - word displ
  2839.     inc    pcntr
  2840.     inc    pcntr
  2841.     inc    bx
  2842.     mov    dx,es:[bx]    ;displacement from 1st byte past instr
  2843.     inc    bx
  2844.     inc    bx        ;to 1st byte past instr
  2845.     add    bx,dx
  2846.     mov    dx,bx        ;now DX = pcntr + displ
  2847.     mov    RelFlag,1
  2848.     or    OprndType,2    ; word
  2849.     call    PrtNoOrSmb ;print DX + org, and ;ADDR if label, add SMB if in B
  2850.     jmp    NewLine
  2851. ; - - - - - - - - - - - - - - - -
  2852. kind06:    call    PrtTab        ;16-bit immediate data arith to AX
  2853.     inc    pcntr
  2854.     inc    pcntr
  2855.     inc    curadr
  2856.     call    pstg
  2857.     db    'AX,',0
  2858. ImmedWord:            ;used by kind10, PUSH immed & kind03, MOV immed
  2859.     mov    bx,curadr    ;has been inc'd
  2860.     mov    dx,es:[bx]
  2861. ImSE:    call    symluk        ;saves DX
  2862.     jnc    hvsym3        ;jmp if label
  2863.     call    PrintDXh    ;print word in DX, followed by 'h'
  2864.     jmp    NewLine
  2865.  
  2866. hvsym3:    call    pstg
  2867.     db    'OFFSET ',0
  2868.     call    HaveSmb
  2869.     jmp    NewLine
  2870.  
  2871. ; - - - - - - - - - - - - - - - -
  2872. ;print operand words following 'WORD PTR' (AddrOrSmb does line addrs)
  2873. ; and Rel JMPs and CALLs.  Adds symbols if in B mode.
  2874. PrtNoOrSmb:
  2875.     mov    al,OprndType
  2876.     and    al,00110000b    ;look at seg override for this line
  2877.     cmp    al,10h        ;is it DS:, the default set at Dline ?
  2878.     jnz    NoDS
  2879.     cmp    RelFlag,0
  2880.     jnz    NoDS        ;no 'DS:' for JZ, LOOP, etc.
  2881.     call    pstg
  2882.     db    'DS:',0        ;req'd by dumb MASM for [addr] !
  2883. NoDS:    push    dx        ;holds the addr or data to print
  2884.     call    symluk        ;check for symbol
  2885.     pop    dx
  2886.     jnc    HaveSmb        ;print it
  2887. mkopds:    cmp    BmodeFlag,0    ;building symbols?
  2888.     jz    PrtAdr        ;just print addr if not
  2889.     push    dx
  2890.     call    addsym        ;this is the only call to addsym
  2891.     pop    dx
  2892.     jmp    PrtAdr        ;it's too late to print new label (is it ??)
  2893.  
  2894. HaveSmb:
  2895.     call    PrtCHbytesPerBX
  2896.     cmp    NoCommentAddr,1
  2897.     jz    JustLabel
  2898.     test    byte ptr trmflg,0FFh
  2899.     jnz    JustLabel
  2900.     call    PrtTab
  2901.     call    semic
  2902.     mov    bx,dx        ;the address
  2903.     cmp    RelFlag,0
  2904.     jz    NoCorr
  2905.     add    bx,curorg    ;correct for ORG
  2906. NoCorr:    jmp    Print00BX_
  2907.  
  2908. JustLabel:
  2909.     mov    NoCommentAddr,0
  2910.     ret
  2911.  
  2912. ;print operand addr pushed on stack (line addrs done by Print00BX_)
  2913. ;called only by mkopds
  2914. PrtAdr:    cmp    RelFlag,0
  2915.     jz    PrintDXh    ;Jump for hard-coded addrs
  2916.     add    dx,curorg    ;correct relative addrs for ORG,
  2917. PrintDXh:            ;leading zeros only where MASM requires,
  2918.                 ;  EXCEPT, e.g., 400h shows as 0400h
  2919.     mov    al,'0'
  2920.     or    dx,dx
  2921.     jz    l147d
  2922.     mov    al,dh
  2923.     or    al,al
  2924.     jz    PrintDLh
  2925.     call    xo0
  2926.     mov    al,dl
  2927.     call    xo
  2928. phxsfx:    mov    al,'h'
  2929. l147d:    jmp    typech
  2930.  
  2931. PrintDLh:
  2932.     mov    al,dl
  2933. PrintALh:
  2934.     cmp    al,0Ah
  2935.     jb    padigt
  2936.     call    xo0
  2937.     jmp    phxsfx
  2938.  
  2939. padigt:    add    al,'0'        ;30h
  2940.     jmp    typech
  2941. ; - - - - - - - - - - - - - - - -
  2942. kind07:    call    PrtTab        ;INT is the only kind07 opcode
  2943.     inc    pcntr
  2944.     mov    al,es:[bx+1]
  2945.     call    PrintALh
  2946.     jmp    NewLine
  2947. ; - - - - - - - - - - - - - - - -
  2948. kind08:    inc    pcntr        ;AAM, AAD. Doesn't check 2nd byte (0Ah)
  2949.     jmp    NewLine
  2950. ; - - - - - - - - - - - - - - - -
  2951. kind09:    call    PrtTab        ;lock/rep/repnz prefixes
  2952.     jmp    dline        ;to continue instr
  2953. ; - - - - - - - - - - - - - - - -
  2954. kind10:    call    PrtTab        ;'186 PUSH nnnn
  2955.     mov    al,CurInstr
  2956.     inc    pcntr
  2957.     inc    curadr
  2958.     cmp    al,6Ah        ;is the Sign-Extend bit set ?
  2959.     jz    SExt
  2960.     inc    pcntr
  2961.     jmp    ImmedWord    ;print no. or 'OFFSET label'
  2962.     
  2963. SExt:    xor    dh,dh
  2964.     mov    bx,curadr
  2965.     mov    dl,es:[bx]
  2966.     or    dl,dl
  2967.     jns    ExDone
  2968.     dec    dh        ;to 0FFh
  2969. ExDone:    jmp    ImSE        ;last part of ImmedWord routine
  2970.  
  2971. ; - - - - - - - - - - - - - - - -
  2972. kind11:    call    pcndop        ;conditional jumps. 'J' has been printed.
  2973. kind21:    call    PrtTab        ;JCXZ, JMP SHORT
  2974.     mov    al,CurInstr    ;get op code byte again
  2975.     cmp    al,0EBh        ;was it JMP SHORT, not JCXZ ?
  2976.     jnz    NoShort
  2977.     call    pstg
  2978.     db    'SHORT ',0
  2979. NoShort:
  2980.     inc    pcntr
  2981.     mov    bx,curadr
  2982.     inc    bx
  2983.     mov    al,es:[bx]    ;get displacement byte
  2984.     test    al,80h        ;get sign
  2985.     jnz    k21neg
  2986.     inc    bx
  2987.     call    AddALtoBX
  2988.     jmp    k21add
  2989.  
  2990. k21neg:    inc    bx
  2991.     not    al
  2992.     inc    al
  2993.     xor    ah,ah
  2994.     sub    bx,ax
  2995. k21add:    mov    dx,bx
  2996.     mov    RelFlag,1    ;flag rel-displ for
  2997.     call    PrtNoOrSmb    ;  print DX + curorg, add SMB if in B mode
  2998.     jmp    NewLine
  2999. ; - - - - - - - - - - - - - - - -
  3000. kind12:                ;movs, cmps, lods, stos, scas
  3001.     mov    al,CurInstr
  3002.     and    al,1
  3003.     jnz    k12wrd
  3004.     call    pstg
  3005.     db    'B',0
  3006.     jmp    NewLine
  3007.  
  3008. k12wrd:    call    pstg
  3009.     db    'W',0
  3010.     jmp    NewLine
  3011. ; - - - - - - - - - - - - - - - -
  3012. kind13:    call    pstg        ;xchg ax,
  3013.     db    tab,'AX,',0
  3014.     mov    al,CurInstr
  3015.     and    al,7
  3016.     call    namr16
  3017.     jmp    NewLine
  3018. ; - - - - - - - - - - - - - - - -
  3019. kind15:    call    PrtTab        ;PUSH, POP, INC, DEC one 16 bit register
  3020.     mov    al,CurInstr
  3021.     and    al,7
  3022.     call    namr16
  3023.     jmp    NewLine
  3024. ; - - - - - - - - - - - - - - - -
  3025. PrtRegOfRM:
  3026.     mov    bx,curadr
  3027.     inc    bx
  3028.     mov    al,es:[bx]        ;get ModRegR/M byte
  3029.     and    al,00000111b        ;look at R/M field only
  3030.     jmp    l156d
  3031.  
  3032. PrtReg:    mov    bx,curadr
  3033.     inc    bx
  3034.     mov    al,es:[bx]
  3035.     and    al,38h            ;look at reg field only
  3036.     shr    al,1
  3037.     shr    al,1
  3038.     shr    al,1
  3039. l156d:    push    ax
  3040. ;'286 LAR, etc are WORD reg's, must filter out
  3041.     cmp    LongFlag,0
  3042.     jnz    WordReg
  3043.     mov    bx,curadr
  3044.     mov    al,es:[bx]        ;get current op code
  3045.     test    al,1
  3046.     jnz    WordReg
  3047.     pop    ax
  3048.     jmp    namrg8
  3049. WordReg:
  3050.     pop    ax
  3051.     jmp    namr16
  3052.  
  3053. ;used for TEST, MOV, XCHG, kind18 arith, and '286 ARPL, LSL, LAR
  3054. ModRegRM:
  3055.     mov    bx,curadr
  3056.     inc    bx
  3057.     mov    al,es:[bx]        ;get modregr/m byte
  3058.     and    al,11000000b        ;the MOD field
  3059.     or    al,al
  3060.     jz    ChkQuirk        ;no displacement unless [BP]
  3061.     cmp    al,11000000b
  3062.     jz    RMisReg
  3063.     jmp    Displacement
  3064.  
  3065. RMisReg:                ;mod = 11
  3066.     inc    pcntr
  3067.     mov    bx,curadr
  3068.     mov    al,es:[bx]        ;get op code again
  3069.     cmp    al,63h            ;ARPL ?
  3070.     jz    RegLast
  3071.     cmp    al,69h            ;'186 IMUL immed ?
  3072.     jz    RegFirst
  3073.     test    al,2            ;the D bit. Never set for TEST
  3074.                 ; **** ignored for '286 long instrs ??
  3075.     jnz    RegFirst
  3076. RegLast:
  3077.     call    PrtRegOfRM
  3078.     call    comma
  3079.     jmp    PrtReg
  3080.  
  3081. RegFirst:
  3082.     call    PrtReg
  3083.     call    comma
  3084.     jmp    PrtRegOfRM
  3085.  
  3086. ChkQuirk:                ; the MOD field is 00
  3087.     inc    pcntr
  3088.     mov    bx,curadr
  3089.     mov    al,es:[bx]        ;get the op code again
  3090.     cmp    al,63h            ;ARPL ?
  3091.     jz    QuirkRegLast
  3092.     test    al,2
  3093.     jnz    QuirkReg1st
  3094. QuirkRegLast:
  3095.     call    l1606
  3096.     call    comma
  3097.     jmp    PrtReg
  3098.  
  3099. QuirkReg1st:
  3100.     call    PrtReg
  3101.     call    comma
  3102.     jmp    l1606
  3103.  
  3104. Displacement:                ;mod = 01 or 10, [XX+YY+disp]
  3105.     inc    pcntr
  3106.     mov    bx,curadr
  3107.     mov    al,es:[bx]        ;get op code again
  3108.     cmp    al,63h            ;ARPL ?
  3109.     jz    DisplFirst
  3110.     cmp    al,69h            ;'186 IMUL ?
  3111.     jz    DisplLast
  3112.     test    al,2            ;set, 1st operand is displ, 2nd is reg
  3113.     jnz    DisplLast
  3114. DisplFirst:
  3115.     call    PrtPTRandDisplPerReg    ;print XS:XXXX PTR nn[XX+YY]
  3116.     call    comma
  3117.     jmp    PrtReg
  3118.  
  3119. DisplLast:
  3120.     call    PrtReg
  3121.     call    comma
  3122.     jmp    PrtPTRandDisplPerReg
  3123.  
  3124. ;This is a CALL from above ModRegRM routine - - - - -
  3125. l1606:    cmp    LongFlag,0
  3126.     jnz    DoWORD            ;'286 0F-prefix instrs are WORD
  3127.     mov    bx,curadr
  3128.     mov    al,es:[bx]
  3129.     test    al,1
  3130.     jnz    DoWORD
  3131.     call    pstg
  3132.     db    'BYTE PTR ',0
  3133.     or    OprndType,1        ;byte size
  3134.     jmp    l1630
  3135.  
  3136. DoWORD:    call    pstg
  3137.     db    'WORD PTR ',0
  3138.     or    OprndType,2        ;word size
  3139. l1630:    call    psgprf            ;show segment override prefix if any
  3140. ;if mod=00, and r/m=110 then addr word is present
  3141.     mov    bx,curadr
  3142.     inc    bx
  3143.     mov    al,es:[bx]        ;the modregr/m byte of the instr
  3144.     and    al,7            ;bits 0, 1, 2 only, the r/m field
  3145.     cmp    al,6            ;r/m = [BP]+disp ?
  3146.     jnz    NotDoingBP
  3147. ;it's addr word, not [BP]
  3148.     inc    pcntr
  3149.     inc    pcntr
  3150.     inc    bx
  3151.     mov    dx,es:[bx]        ;the 'displ' word
  3152.     mov    NoCommentAddr,1        ;don't show addr as a comment
  3153.     call    PrtNoOrSmb        ;add SMB if in B mode
  3154.     ret
  3155.  
  3156. NotDoingBP:
  3157.     call    PrtIndxedOprd        ;print [BP+SI], etc
  3158.     ret
  3159.  
  3160. PrtPTRandDisplPerReg:
  3161.     cmp    LongFlag,0
  3162.     jnz    PrtWordPtr        ;'286 0F-prefix instrs are WORD
  3163.     mov    bx,curadr
  3164.     mov    al,es:[bx]
  3165.     test    al,1            ;check the W bit
  3166.     jnz    PrtWordPtr
  3167.     call    pstg
  3168.     db    'BYTE PTR ',0
  3169.     or    OprndType,1        ;byte size
  3170.     jmp    PrtDisplPerReg
  3171.  
  3172. PrtWordPtr:
  3173.     call    pstg
  3174.     db    'WORD PTR ',0
  3175.     or    OprndType,2        ;word size
  3176. ;print reg or reg+displ (like  3[BP+SI], etc)
  3177. PrtDisplPerReg:
  3178.     call    psgprf
  3179. ;at this point, the line looks like   0123 MOV    WORD PTR CS:
  3180.     inc    pcntr
  3181.     mov    bx,curadr
  3182.     inc    bx
  3183.     mov    al,es:[bx]        ;the modregr/m byte
  3184.     inc    bx            ;points DISP byte
  3185.     and    al,11000000b
  3186.     cmp    al,01000000b        ;is DISP 1 byte ?
  3187.     jnz    Not1ByteDisp
  3188.     mov    al,es:[bx]        ;get 1-byte disp
  3189. ;CONVERT NEG NOS TO -nn form
  3190.     test    al,80h            ;is disp negative ?
  3191.     jz    PosNo
  3192.     push    ax
  3193.     call    pstg
  3194.     db    '-',0
  3195.     pop    ax
  3196.     neg    al
  3197. PosNo:    call    PrintALh
  3198.     call    PrtIndxedOprd        ;print [BP+SI], etc
  3199.     ret
  3200.  
  3201. Not1ByteDisp:
  3202.     inc    pcntr
  3203.     mov    dx,es:[bx]        ;get disp word, just past modregr/m
  3204.     call    PrintDXh
  3205.     call    PrtIndxedOprd        ;print [BP+SI], etc
  3206.     ret
  3207. ;--------------------------------
  3208. psgprf:    push    ax
  3209.     mov    al,SegOvrdPfx
  3210.     or    al,al
  3211.     jz    NoPrefix
  3212.     and    al,18h
  3213.     call    PrtaSegReg
  3214.     call    colon
  3215.     mov    al,SegOvrdPfx
  3216.     shl    al,1            ;get the 2 REG bits into the hi nibble
  3217.     and    al,00110000b        ;look at only those bits
  3218.     xor    al,00100000b        ;invert hi bit, now S D E C - why??
  3219.     mov    OprndType,al
  3220.     mov    SegOvrdPfx,0
  3221. NoPrefix:
  3222.     pop    ax
  3223.     ret
  3224.  
  3225. namr16:    mov    bx,offset rtb16
  3226.     add    al,al
  3227.     call    AddALtoBX
  3228.     mov    al,cs:[bx]
  3229.     call    typech
  3230.     inc    bx
  3231.     mov    al,cs:[bx]
  3232.     jmp    typech
  3233.  
  3234. rtb16    db    'AX','CX','DX','BX','SP','BP','SI','DI'
  3235.  
  3236. namrg8:    mov    bx,offset rtb08
  3237.     add    al,al
  3238.     call    AddALtoBX
  3239.     mov    al,cs:[bx]
  3240.     call    typech
  3241.     inc    bx
  3242.     mov    al,cs:[bx]
  3243.     jmp    typech
  3244.  
  3245. rtb08    db    'AL','CL','DL','BL','AH','CH','DH','BH'
  3246. ; - - - - - - - - - - - - - - - -
  3247. kind22:                ;80286, 386 Protected mode instrs begin w/0Fh
  3248.     ror    Direc286Flag,1    ;move present status to hi bit
  3249.     or    Direc286Flag,1    ;and set flag (invalid codes will restore)
  3250.     mov    LongFlag,1    ;'long' 2-byte op codes with ModRegR/M ex CLTS
  3251.     inc    curadr
  3252.     inc    pcntr
  3253.     mov    bx,curadr    ;to 2nd byte of opcode, now curadr
  3254.     mov    al,es:[bx+1]
  3255.     mov    CurModRegRM,al
  3256.     mov    al,es:[bx]
  3257.     mov    CurInstr,al
  3258.     test    al,11111100b    ;look at all but lo 2 bits of instr
  3259.     jnz    BetterBeCLTS
  3260.     cmp    al,3
  3261.     jz    ItsLSL
  3262.     cmp    al,2
  3263.     jnz    xxyy
  3264.     jmp    ItsLAR
  3265. xxyy:    or    al,al            ;AL has lo 2 bits of opcode
  3266.     jz    ItsLD_TR_VER
  3267. ;2nd byte is 01, instr is LGDT, SGDT, LIDT, SIDT, LMSW, or SMSW
  3268.     mov    bl,CurModRegRM
  3269.     and    bl,00111000b
  3270.     cmp    bl,00111000b
  3271.     jz    NotAny
  3272.     cmp    bl,00101000b
  3273.     jz    NotAny
  3274.     mov    bx,offset DTandSWtbl
  3275.     call    PrtLongInstrs
  3276.     call    PrtTab
  3277.     mov    al,CurModRegRM
  3278.     and    al,00111000b
  3279.     cmp    al,00100000b
  3280.     jae    ItsMSW
  3281.     call    pstg
  3282.     db    'F',0            ;MASM 5.0 bug requires Q here
  3283.     call    PrtMoprnd
  3284.     jmp    NewLine
  3285.  
  3286. ;2nd byte is 00, instr is LLDT, SLDT, LTR, STR, VERR, or VERW
  3287. ItsLD_TR_VER:
  3288.     mov    bl,CurModRegRM
  3289.     and    bl,00111000b
  3290.     cmp    bl,00110000b
  3291.     jae    NotAny
  3292.     mov    bx,offset LongZeroTbl
  3293.     call    PrtLongInstrs
  3294.     call    PrtTab
  3295. ItsMSW:    call    PrtWhatsShifted
  3296.     jmp    NewLine
  3297.  
  3298. BetterBeCLTS:
  3299.     cmp    al,6
  3300.     jnz    NotAny
  3301.     call    pstg
  3302.     db    'CLTS',0
  3303.     jmp    NewLine
  3304.  
  3305. NotAny:    call    pstg
  3306.     db    'DB',tab,'0Fh,',0
  3307.     mov    al,CurInstr
  3308.     call    PrintALh
  3309.     rol    Direc286Flag,1    ;restore bit 0 to previous status
  3310.     jmp    NewLine
  3311.  
  3312. ItsLSL:    call    pstg
  3313.     db    'LSL',tab,0
  3314.     call    ModRegRM
  3315.     jmp    NewLine
  3316.  
  3317. ItsLAR:    call    pstg
  3318.     db    'LAR',tab,0
  3319.     call    ModRegRM
  3320.     jmp    NewLine
  3321.  
  3322. ; - - - - - - - - - - - - - - - -
  3323. kind23:    mov    al,CurInstr    ;segment override prefix
  3324.     mov    SegOvrdPfx,al
  3325.     jmp    dline        ;to continue instr
  3326. ; - - - - - - - - - - - - - - - -
  3327. kind24:    call    PrtTab        ;push/pop seg regs
  3328.     mov    al,CurInstr
  3329.     and    al,18h
  3330.     call    PrtaSegReg
  3331.     jmp    NewLine
  3332. ; - - - - - - - - - - - - - - - -
  3333. kind25:    call    PrtTab        ;MOV AL or AX <-> mem, codes A0h - A3h
  3334.     inc    pcntr
  3335.     inc    pcntr
  3336.     mov    al,CurInstr
  3337.     test    al,2
  3338.     jz    MemToAccum
  3339.     call    PrtMemory
  3340.     call    comma
  3341.     call    paccum
  3342.     jmp    NewLine
  3343.  
  3344. MemToAccum:
  3345.     call    paccum
  3346.     call    comma
  3347.     call    PrtMemory
  3348.     jmp    NewLine
  3349.  
  3350. paccum:    mov    al,CurInstr
  3351.     test    al,1        ;the W bit
  3352.     jnz    acc16b
  3353.     call    pstg
  3354.     db    'AL',0
  3355.     ret
  3356.  
  3357. acc16b:    call    pstg
  3358.     db    'AX',0
  3359.     ret
  3360.  
  3361. PrtMemory:
  3362.     mov    al,CurInstr
  3363.     test    al,1
  3364.     jnz    TisWord
  3365.     call    pstg
  3366.     db    'BYTE PTR ',0
  3367.     or    OprndType,1        ;byte size
  3368.     jmp    l17b3
  3369.  
  3370. TisWord:
  3371.     call    pstg
  3372.     db    'WORD PTR ',0
  3373.     or    OprndType,2        ;word size
  3374. l17b3:    call    psgprf
  3375.     mov    bx,curadr
  3376.     inc    bx
  3377.     mov    dx,es:[bx]
  3378.     mov    NoCommentAddr,1        ;don't show addr as a comment
  3379.     call    PrtNoOrSmb
  3380.     ret
  3381. ; - - - - - - - - - - - - - - - -
  3382. kind26:                    ;shift/rotate instr's
  3383.     mov    al,es:[bx+1]        ;get byte after op code, modTTTr/m
  3384.     mov    CurModRegRM,al
  3385.     and    al,00111000b        ;get the TTT field
  3386.     cmp    al,00110000b        ;TTT=110 ?
  3387.     jnz    ValidTTT
  3388.     jmp    PrtDBandByte        ;it's not a valid Op code
  3389.  
  3390. ValidTTT:
  3391.     call    PrtShiftOpds
  3392.     call    PrtTab
  3393.     call    PrtWhatsShifted        ;does single-operand Extnd Addrs
  3394.     call    comma
  3395.     mov    al,CurInstr        ;get the Op code again
  3396.     and    al,0FEh            ;look at all but last bit
  3397.     cmp    al,0C0h            ;is it '286 sh/rotate by count ?
  3398.     jnz    NotByCount
  3399.     mov    Direc286Flag,1
  3400.     mov    bx,pcntr        ;because length of instr is variable
  3401.     mov    al,es:[bx]        ;the count byte
  3402.     call    PrintALh
  3403.     inc    pcntr            ;these are 1 byte longer
  3404.     jmp    NewLine
  3405.  
  3406. NotByCount:
  3407.     and    al,2            ;bit 1 signals 'by CL'
  3408.     jz    Shift1
  3409.     call    pstg
  3410.     db    'CL',0
  3411.     jmp    NewLine
  3412.  
  3413. Shift1:    mov    al,'1'
  3414.     call    typech
  3415.     jmp    NewLine
  3416.  
  3417. PrtWhatsShifted:
  3418.     inc    pcntr
  3419.     mov    al,CurModRegRM
  3420.     and    al,11000000b        ;look at 'mod' field
  3421.     cmp    al,11000000b
  3422.     jz    ItsaReg
  3423.     or    al,al
  3424.     jz    NoDispl
  3425.     jmp    PrtPTRandDisplPerReg
  3426.  
  3427. ItsaReg:
  3428.     jmp    PrtRegOfRM
  3429.  
  3430. NoDispl:
  3431.     jmp    l1606
  3432.  
  3433. ; - - - - - - - - - - - - - - - -
  3434. kind27:    inc    bx            ;POP to memory
  3435.     mov    al,es:[bx]
  3436.     mov    CurModRegRM,al
  3437.     and    al,38h
  3438.     jz    YesPOPmem
  3439.     jmp    PrtDBandByte
  3440.  
  3441. YesPOPmem:
  3442.     call    pstg
  3443.     db    'POP',0
  3444.     call    PrtTab
  3445.     call    PrtWhatsShifted
  3446.     jmp    NewLine
  3447. ; - - - - - - - - - - - - - - - -
  3448. kind28:                    ;MOV to or from segment reg
  3449.     mov    al,es:[bx+1]        ;get 2nd byte of instr
  3450.     mov    CurModRegRM,al
  3451.     test    al,20h            ;nondest AND AL, 0010000
  3452.     jz    YesMOVsegreg
  3453.     jmp    PrtDBandByte
  3454.  
  3455. YesMOVsegreg:
  3456.     call    pstg
  3457.     db    'MOV',0
  3458.     call    PrtTab
  3459.     mov    al,CurInstr
  3460.     test    al,2
  3461.     jnz    l1865
  3462.     call    l187d
  3463.     call    comma
  3464.     call    l1871
  3465.     jmp    NewLine
  3466.  
  3467. l1865:    call    l1871
  3468.     call    comma
  3469.     call    l187d
  3470.     jmp    NewLine
  3471.  
  3472. l1871:    mov    al,CurModRegRM
  3473.     and    al,18h
  3474.     jmp    PrtaSegReg
  3475.  
  3476. l187d:    inc    pcntr
  3477.     mov    al,CurModRegRM
  3478.     and    al,11000000b
  3479.     cmp    al,11000000b
  3480.     jz    RMisaReg
  3481.     or    al,al
  3482.     jnz    l18ba
  3483.     jmp    DoWORD
  3484.  
  3485. RMisaReg:
  3486.     mov    al,CurModRegRM
  3487.     and    al,7
  3488.     jmp    namr16
  3489.  
  3490. l18ba:    call    pstg
  3491.     db    'WORD PTR ',0
  3492.     or    OprndType,2        ;word type
  3493.     jmp    PrtDisplPerReg        ;prints Seg Ovrd Pfx, if any
  3494. ; - - - - - - - - - - - - - - - -
  3495. kind29:                    ;MOV immed to r/m
  3496.     inc    bx
  3497.     mov    al,es:[bx]        ;modregr/m byte
  3498.     mov    CurModRegRM,al
  3499.     and    al,38h
  3500.     jz    ItsMov
  3501.     jmp    PrtDBandByte        ;not a valid code
  3502.  
  3503. ItsMov:    call    pstg
  3504.     db    'MOV',0
  3505.     call    PrtTab
  3506.     jmp    l1c19
  3507. ; - - - - - - - - - - - - - - - -
  3508. kind30:                    ;LEA, ModRegR/M, but no Reg
  3509. ;MASM always assumes DS:, but old code may have Seg Ovrd Pfx
  3510.     mov    al,SegOvrdPfx
  3511.     or    al,al
  3512.     jz    NoLEApfx
  3513.     and    al,18h
  3514.     cmp    al,00011000b        ;DS:
  3515.     jz    NoLEApfx
  3516.     call    pstg
  3517.     db    'DB',tab,0
  3518.     mov    al,SegOvrdPfx
  3519.     call    PrintALh
  3520.     call    PrtTab
  3521.     call    semic
  3522.     call    pstg
  3523.     db    'Seg Prefix for code length, MASM will use DS:',cr,lf,tab,0
  3524. NoLEApfx:
  3525.     call    pstg
  3526.     db    'LEA',0
  3527.     call    PrtTab
  3528.     mov    al,es:[bx+1]
  3529.     mov    CurModRegRM,al
  3530.     and    al,38h
  3531.     shr    al,1
  3532.     shr    al,1
  3533.     shr    al,1            ;which register in list
  3534.     call    namr16            ;print register (AX, BX, etc)
  3535.     call    comma
  3536.     call    PrtMoprnd
  3537.     jmp    NewLine
  3538.  
  3539. PrtMoprnd:
  3540.     inc    pcntr
  3541.     mov    al,CurModRegRM
  3542.     and    al,0C0h            ;the mod field
  3543.     or    al,al
  3544.     jnz    Tol18ba            ;print 'WORD PTR' and addr
  3545.     jmp    DoWORD
  3546. Tol18ba:
  3547.     jmp    l18ba            ;print 'WORD PTR' and [XX+nn]
  3548.  
  3549. ; - - - - - - - - - - - - - - - -
  3550. kind31:                    ;NOT r/m
  3551.     inc    bx
  3552.     mov    al,es:[bx]
  3553.     mov    CurModRegRM,al
  3554.     and    al,38h
  3555.     cmp    al,8
  3556.     jnz    YesNOT
  3557.     jmp    PrtDBandByte
  3558.  
  3559. YesNOT:    call    pmisci
  3560.     call    PrtTab
  3561.     mov    al,CurModRegRM
  3562.     and    al,38h
  3563.     jz    Tol1c19
  3564.     call    PrtWhatsShifted
  3565.     jmp    NewLine
  3566.  
  3567. Tol1c19:
  3568.     jmp    l1c19
  3569. ; - - - - - - - - - - - - - - - -
  3570. kind32:    inc    bx            ;INC, DEC reg/mem
  3571.     mov    al,es:[bx]
  3572.     mov    CurModRegRM,al
  3573.     and    al,38h
  3574.     or    al,al
  3575.     jz    l1971
  3576.     cmp    al,8
  3577.     jz    l197f
  3578.     jmp    PrtDBandByte
  3579.  
  3580. l1971:    call    pstg
  3581.     db    'INC',0
  3582.     jmp    l1986
  3583.  
  3584. l197f:    call    pstg
  3585.     db    'DEC',0
  3586. l1986:    call    PrtTab
  3587.     call    PrtWhatsShifted
  3588.     jmp    NewLine
  3589. ; - - - - - - - - - - - - - - - -
  3590. kind33:    inc    bx        ;code FFh. Many: INC, DEC, CALLs, JMP, PUSH mem
  3591.     mov    al,es:[bx]    ;2nd byte, mod sub-opcode r/m
  3592.     mov    CurModRegRM,al
  3593.     and    al,38h        ;sub-opcode
  3594.     cmp    al,38h
  3595.     jnz    OK33
  3596.     jmp    PrtDBandByte    ;db, not valid instr
  3597.  
  3598. OK33:    or    al,al        ;inc reg/mem word
  3599.     jz    ItsINC
  3600.     cmp    al,8        ;dec reg/mem word
  3601.     jz    ItsDEC
  3602.     cmp    al,30h        ;push reg/mem
  3603.     jz    ItsPUSHrm
  3604.     cmp    al,00011000b    ;indir interseg call
  3605.     jz    ItsCallDword
  3606.     cmp    al,00101000b    ;indir interseg jmp
  3607.     jz    ItsJmpDword
  3608.     cmp    al,00010000b    ;reg/mem indir intraseg call
  3609.     jz    ItsCallPER
  3610.     jmp    ItsJmpPER    ;reg/mem indir intraseg jmp (AL must be 20h)
  3611.  
  3612. ItsINC:    call    pstg
  3613.     db    'INC',0
  3614.     jmp    l19d1
  3615.  
  3616. ItsDEC:    call    pstg
  3617.     db    'DEC',0
  3618. l19d1:    call    PrtTab
  3619.     call    PrtMoprnd
  3620.     jmp    NewLine
  3621.  
  3622. ItsPUSHrm:
  3623.     call    pstg
  3624.     db    'PUSH',0
  3625.     jmp    l19d1
  3626.  
  3627. ItsCallPER:
  3628.     call    pstg
  3629.     db    'CALL',tab,0
  3630.     call    PrtWhatsShifted
  3631.     jmp    NewLine
  3632.  
  3633. ItsJmpPER:
  3634.     call    pstg
  3635.     db    'JMP',tab,0
  3636.     call    PrtWhatsShifted
  3637.     mov    CurInstr,0E9h        ;signal to put blank line after this
  3638.     jmp    NewLine
  3639.  
  3640. ItsCallDword:
  3641.     call    pstg
  3642.     db    'CALL',tab,0
  3643.     jmp    DoDWORD
  3644.  
  3645. ItsJmpDword:
  3646.     call    pstg
  3647.     db    'JMP',tab,0
  3648.     mov    CurInstr,0E9h        ;signal to put blank line after this
  3649. DoDWORD:
  3650.     call    pstg
  3651.     db    'DWORD PTR ',0
  3652.     or    OprndType,3        ;dword type
  3653.     inc    pcntr
  3654.     mov    al,CurModRegRM        ;for BOUND, LDS & LES
  3655.     and    al,11000000b        ;the Mode field
  3656.     or    al,al
  3657.     jz    NoDis
  3658. ;register or reg+displ
  3659.     call    PrtDisplPerReg
  3660.     jmp    NewLine
  3661.  
  3662. ;Mod = 0, no displacement unless R/M = 110 then is word addr
  3663. NoDis:    call    l1630
  3664.     jmp    NewLine
  3665.  
  3666. ; - - - - - - - - - - - - - - - -
  3667. kind34:                ;call  far ptr, 9Ah & jmp  far ptr, EAh
  3668.                 ;MASM req SEGMENT AT to generate these
  3669.     call    PrtTab
  3670.     add    pcntr,4
  3671.     mov    dx,es:[bx+3]        ;get segment
  3672.     call    PrintDXh
  3673.     call    colon
  3674.     mov    dx,es:[bx+1]        ;get offset
  3675.     call    PrintDXh
  3676.     jmp    NewLine
  3677. ; - - - - - - - - - - - - - - - -
  3678. kind35:                    ;'186 ENTER nnnn,nn
  3679.     call    PrtTab
  3680.     mov    dx,es:[bx+1]
  3681.     call    PrintDXh
  3682.     call    comma
  3683.     mov    al,es:[bx+3]
  3684.     call    PrintALh
  3685.     add    pcntr,3
  3686.     jmp    NewLine
  3687.  
  3688. ; - - - - - - - - - - - - - - - -
  3689. kind36:                    ;RET nnnn, RET FAR nnnn
  3690.     call    PrtTab
  3691.     mov    dx,es:[bx+1]
  3692.     call    PrintDXh
  3693.     inc    pcntr
  3694.     inc    pcntr
  3695.     jmp    NewLine
  3696. ; - - - - - - - - - - - - - - - -
  3697. kind16:    call    PrtTab            ;ESC nn,reg for 80x87
  3698. ; *** not right, do the FLoating instr's ***
  3699.     mov    al,CurInstr
  3700.     and    al,7            ;get the TTT field
  3701.     mov    cl,3
  3702.     shl    al,cl
  3703.     mov    ah,al
  3704.     mov    al,es:[bx+1]
  3705.     mov    CurModRegRM,al
  3706.     and    al,38h            ;the LLL field
  3707.     mov    cl,3
  3708.     shr    al,cl
  3709.     add    al,ah            ;now AL = 00 TTT LLL
  3710.     call    PrintALh
  3711.     call    comma
  3712.     call    l187d
  3713.     jmp    NewLine
  3714. ; - - - - - - - - - - - - - - - -
  3715. kind17:    mov    al,CurInstr        ;LOOPZ and LOOPNZ
  3716.     and    al,3
  3717.     cmp    al,0
  3718.     jnz    ItsLOOPZ
  3719.     call    pstg
  3720.     db    'NZ',0
  3721.     jmp    kind21
  3722.  
  3723. ItsLOOPZ:
  3724.     cmp    al,1
  3725.     jnz    l1b55
  3726.     call    pstg
  3727.     db    'Z',0
  3728. l1b55:    jmp    kind21
  3729. ; - - - - - - - - - - - - - - - -
  3730. kind18:                    ;arith, r/m & reg to either
  3731.     call    PrtArithInstr        ; (opcode bits 00111011 only)
  3732. kind19:    call    PrtTab        ;TEST, XCHG, MOV, IMUL186, ARPL reg w/reg/mem
  3733.     mov    bx,curadr
  3734.     mov    al,CurInstr
  3735.     call    ModRegRM
  3736.     mov    al,CurInstr
  3737.     cmp    al,69h            ;is it '186 IMUL immed word ?
  3738.     jz    ItsIMUL
  3739.     cmp    al,6Bh            ;is it IMUL immed Sign-Ext byte ?
  3740.     jz    ItsIMUL
  3741.     jmp    NewLine
  3742.  
  3743. ItsIMUL:
  3744.     mov    bx,pcntr        ;ModRegRM routine has variable bytes
  3745.     inc    pcntr
  3746.     call    comma
  3747.     mov    al,CurInstr
  3748.     cmp    al,6Bh
  3749.     jnz    IMULword
  3750.     jmp    SignExtend
  3751.  
  3752. IMULword:
  3753.     mov    dx,es:[bx]
  3754.     inc    pcntr
  3755.     call    PrintDXh
  3756.     jmp    NewLine
  3757.  
  3758. ; - - - - - - - - - - - - - - - -
  3759. ;LES, LDS, BOUND. Enter w/BX=curadr, points 1st byte of op code
  3760. kind38:    call    PrtTab            ;the instr has just been printed
  3761.     mov    al,es:[bx+1]        ;get modregr/m byte
  3762.     mov    CurModRegRM,al
  3763.     and    al,00111000b        ;the Reg field
  3764.     shr    al,1
  3765.     shr    al,1
  3766.     shr    al,1            ;AL=which register in list
  3767.     call    namr16            ;print the register
  3768.     call    comma
  3769.     jmp    DoDWORD
  3770. ; - - - - - - - - - - - - - - - -
  3771. kind20:                    ;Arith immed to reg/mem, code 80,1,2,3h
  3772.     mov    al,CurInstr        ;NOTE: Intel book is WRONG, uses d bit
  3773. L1c0c:    inc    bx            ;to ModRegRM, has actual instr
  3774.     call    PrtArithInstr
  3775.     call    PrtTab
  3776. ;print the ModRegR/M and immed data for arith & mov immed.
  3777. ;  PrtModRegRM does similar, but no immed data
  3778. l1c19:    mov    bx,curadr
  3779.     inc    bx
  3780.     mov    al,es:[bx]        ;get the modregr/m byte
  3781.     mov    CurModRegRM,al
  3782.     and    al,0C0h            ;look at the mod field
  3783.     or    al,al
  3784.     jnz    ModNotZero
  3785.     jmp    ModIsZero
  3786. ModNotZero:
  3787.     cmp    al,0C0h
  3788.     jz    ModIs11
  3789. ;mod is 01 or 10, disp is present
  3790.     inc    pcntr
  3791.     call    PrtPTRandDisplPerReg    ;no use BX
  3792.     call    comma
  3793.     mov    al,CurModRegRM
  3794.     mov    bx,curadr
  3795.     inc    bx
  3796.     inc    bx
  3797.     inc    bx
  3798.     test    al,80h            ;word disp ?
  3799.     jz    bbbb
  3800.     inc    bx            ;curadr + 3 or 4 to get past DISP
  3801. bbbb:    inc    pcntr
  3802.     jmp    PrtImmedData
  3803.  
  3804. ModIs11:
  3805.     inc    pcntr
  3806.     call    PrtRegOfRM        ;no use BX
  3807.     call    comma
  3808.     inc    pcntr
  3809.     mov    al,CurInstr
  3810.     mov    bx,curadr
  3811.     inc    bx        ;ought to use Curadr, not BX
  3812.     inc    bx
  3813. PrtImmedData:
  3814.     push    bx        ;must save BX, locn diff if DISP present
  3815.     mov    bx,curadr
  3816.     mov    al,es:[bx]
  3817.     cmp    al,83h        ;is the sign-extend bit set ?
  3818.     pop    bx
  3819.     jz    SignExtend    ;doesn't use AX, DOES use BX
  3820.     test    al,1
  3821.     jnz    WordData
  3822. ;it is Byte Data
  3823.     mov    curadr,bx
  3824.     cmp    al,0C6h        ;is it MOV ea,ib ?
  3825.     jz    OKtoShowASCII
  3826.     mov    al,CurModRegRM
  3827. OldArith:            ;used by kind04, arith/logic to AL
  3828.                 ; - the 3 bits in the op code are same as REG
  3829.     and    al,00111000b    ;get the sub-opcode field
  3830.     cmp    al,00111000b    ;is it CMP ?
  3831.     jnz    ChkLogic
  3832. OKtoShowASCII:
  3833.     call    bytopd        ;print [curadr] as ASCII if so
  3834.     jmp    NewLine
  3835.  
  3836. ChkLogic:
  3837.     cmp    al,00100000b    ;AND
  3838.     jz    ItsLogic
  3839.     cmp    al,00001000b    ;OR
  3840.     jz    ItsLogic
  3841.     cmp    al,00110000b    ;XOR
  3842.     jz    ItsLogic
  3843.     mov    bx,curadr
  3844.     mov    al,es:[bx]
  3845. ForZero:
  3846.     call    PrintALh
  3847.     jmp    NewLine
  3848.  
  3849. ItsLogic:            ;print the byte as Binary
  3850.     mov    bx,curadr
  3851.     mov    al,es:[bx]
  3852.     or    al,al
  3853.     jz    ForZero
  3854.     mov    dl,al
  3855.     push    es
  3856.     push    cs
  3857.     pop    es
  3858.     mov    di,offset Bits
  3859.     mov    cx,8
  3860. BitLoop:
  3861.     mov    al,'0'
  3862.     shl    dl,1
  3863.     jnc    StoreBit
  3864.     inc    al
  3865. StoreBit:
  3866.     stosb
  3867.     loop    BitLoop
  3868.  
  3869.     pop    es
  3870.     call    pstg
  3871. Bits    db    8 dup('0'),'b',0
  3872.     jmp    NewLine
  3873.  
  3874. WordData:
  3875.     inc    pcntr
  3876.     mov    dx,es:[bx]
  3877.     call    PrintDXh
  3878.     jmp    NewLine
  3879.  
  3880. SignExtend:
  3881.     xor    dh,dh
  3882.     mov    dl,es:[bx]
  3883.     or    dl,dl
  3884.     jns    PosExtend
  3885.     dec    dh        ;to 0FFh
  3886. PosExtend:
  3887.     call    PrintDXh
  3888.     jmp    NewLine
  3889.  
  3890. ModIsZero:
  3891.     inc    pcntr
  3892.     call    l1606
  3893.     call    comma
  3894.     mov    bx,curadr
  3895.     inc    bx
  3896.     mov    al,es:[bx]        ;get the modregr/m byte
  3897.     and    al,7            ;look at the r/m field
  3898.     cmp    al,6            ;check the [BP] quirk
  3899.     jnz    l1c93
  3900. ;mod=00 and r/m=110, so word disp, not [BP]
  3901.     inc    bx
  3902.     inc    bx
  3903. l1c93:    inc    bx
  3904.     inc    pcntr
  3905.     jmp    PrtImmedData
  3906. ;--------------------------------
  3907. comma:    push    ax
  3908.     mov    al,','
  3909.     call    typech
  3910.     pop    ax
  3911.     ret
  3912.  
  3913. apostrophe:
  3914.     push    ax
  3915.     mov    al,''''
  3916.     call    typech
  3917.     pop    ax
  3918.     ret
  3919.  
  3920. PrtTab:    mov    al,tab
  3921.     jmp    typech
  3922.  
  3923. semic:    mov    al,';'
  3924.     jmp    typech
  3925.  
  3926. colon:    mov    al,':'
  3927.     jmp    typech
  3928.  
  3929. PrtDBandByte:
  3930.     call    pstg
  3931.     db    'DB',tab,0
  3932.     call    bytopd
  3933.     jmp    NewLine
  3934.  
  3935. ;--------------------------------
  3936. PrtaSegReg:
  3937.     shr    al,1
  3938.     shr    al,1
  3939.     mov    bx,offset segtbl
  3940.     mov    ch,2
  3941.     call    AddALtoBX
  3942.     jmp    PrtFromTabl
  3943.  
  3944. PrtIndxedOprd:
  3945.     mov    bx,offset indtbl    ;holds [BP+SI][BX]...[BX+SI], etc
  3946.     push    bx            ;  (only ref to indtbl)
  3947.     mov    bx,curadr
  3948.     inc    bx
  3949.     mov    al,es:[bx]        ;get the modregr/m byte
  3950.     and    al,7            ;the r/m field, it's a reg
  3951.     shl    al,1
  3952.     shl    al,1
  3953.     shl    al,1            ;multiply by eight
  3954.     pop    bx
  3955.     mov    ch,8            ;each entry is 8 bytes
  3956.     call    AddALtoBX
  3957.     jmp    PrtFromTabl        ;print the entry in the table
  3958.  
  3959. PrtLongInstrs:
  3960.     push    bx
  3961.     jmp    Prt4ByteTbl
  3962.  
  3963. pmisci:    mov    bx,offset msctbl
  3964.     push    bx
  3965. Prt4ByteTbl:
  3966.     mov    bx,curadr
  3967.     inc    bx
  3968.     mov    al,es:[bx]        ;get the ModREgR/M byte
  3969.     and    al,38h
  3970.     shr    al,1
  3971.     pop    bx
  3972.     mov    ch,4            ;each entry is 4 bytes
  3973.     call    AddALtoBX
  3974.     jmp    PrtFromTabl        ;print the entry in msctbl
  3975.  
  3976. PrtShiftOpds:
  3977.     mov    bx,curadr
  3978.     inc    bx
  3979.     mov    al,es:[bx]
  3980.     and    al,38h            ;00111000b, just look at the TTT field
  3981.     shr    al,1
  3982.     shr    al,1
  3983.     mov    ah,al
  3984.     shr    al,1
  3985.     add    al,ah
  3986.     mov    bx,offset shftbl
  3987.     jmp    Prt3FromTabl
  3988.  
  3989. PrtArithInstr:
  3990.     mov    al,es:[bx]
  3991.     and    al,38h
  3992.     shr    al,1
  3993.     shr    al,1
  3994.     mov    ah,al
  3995.     shr    al,1
  3996.     add    al,ah
  3997.     mov    bx,offset aritbl
  3998.     jmp    Prt3FromTabl
  3999.  
  4000. pcndop:    mov    bx,curadr        ;print Conditional ops (JC, JNZ, etc)
  4001.     mov    al,es:[bx]        ;get op code
  4002.     and    al,0Fh            ;just look at low nibble
  4003.     mov    ch,al
  4004.     add    al,al
  4005.     add    al,ch            ;lo nibble X 3
  4006.     mov    bx,offset cndtbl
  4007. Prt3FromTabl:
  4008.     mov    ch,3
  4009.     call    AddALtoBX
  4010. PrtFromTabl:
  4011.     mov    al,cs:[bx]
  4012.     cmp    al,'.'
  4013.     jz    PrtSkip
  4014.     call    typech
  4015. PrtSkip:
  4016.     inc    bx
  4017.     dec    ch
  4018.     jnz    PrtFromTabl
  4019.     ret
  4020.  
  4021. AddALtoBX:
  4022.     push    ax
  4023.     xor    ah,ah
  4024.     add    bx,ax
  4025.     pop    ax
  4026.     ret
  4027. ;--------------------------------
  4028. ;PRINT [BX] until CH=0
  4029. PrtCHbytesPerBX:
  4030.     mov    al,[bx]
  4031.     call    typech
  4032.     inc    bx
  4033.     dec    ch
  4034.     jnz    PrtCHbytesPerBX
  4035.     ret
  4036. ;--------------------------------
  4037. segtbl    db    'ES','CS','SS','DS'
  4038.  
  4039. cndtbl    db    'O..','NO.','C..','NC.'
  4040.     db    'Z..','NZ.','NA.','A..'
  4041.     db    'S..','NS.','PE.','PO.'
  4042.     db    'NGE','GE.','NG.','G..'
  4043.  
  4044. shftbl    db    'ROL','ROR','RCL','RCR'
  4045.     db    'SHL','SHR','...','SAR'
  4046.  
  4047. msctbl    db    'TEST','....','NOT.','NEG.'
  4048.     db    'MUL.','IMUL','DIV.','IDIV'
  4049.  
  4050. aritbl    db    'ADD','OR.','ADC','SBB'
  4051.     db    'AND','SUB','XOR','CMP'
  4052.  
  4053. ;this table entries 8 char for ease of math
  4054. indtbl    db    '[BX+SI].','[BX+DI].','[BP+SI].','[BP+DI].'
  4055.     db    '[SI]....','[DI]....','[BP]....','[BX]....'
  4056.  
  4057. DTandSWtbl    db    'SGDT','SIDT','LGDT','LIDT','SMSW','....','LMSW'
  4058.  
  4059. LongZeroTbl    db    'SLDT','STR.','LLDT','LTR.','VERR','VERW'
  4060.  
  4061. ;--------------------------------
  4062. ;    Opcode mask, Opcode pattern, Kind, Literal
  4063. ;    Each line is 8 bytes.  Opcode ANDED 1st byte must=2nd byte
  4064. ;    3rd byte is Kind - see 'kindNN:' routines
  4065. ;    Most of these lines can be in any order, see last line.
  4066. ;    Don't print instr if do additional chk for valid instr first.
  4067.  
  4068. opct    db    0ffh,098h,00,'CBW..'    ;Kind00 have no operands
  4069.     db    0ffh,027h,00,'DAA..'
  4070.     db    0ffh,02fh,00,'DAS..'
  4071.     db    0ffh,037h,00,'AAA..'
  4072.     db    0ffh,0c3h,00,'RET..'
  4073.     db    0ffh,0cbh,00,'RETF.'    ;MASM 5.0+ takes this
  4074.     db    0ffh,099h,00,'CWD..'
  4075.     db    0ffh,09bh,00,'FWAIT'
  4076.     db    0ffh,09ch,00,'PUSHF'
  4077.     db    0ffh,09dh,00,'POPF.'
  4078.     db    0ffh,09eh,00,'SAHF.'
  4079.     db    0ffh,09fh,00,'LAHF.'
  4080.     db    0ffh,0ceh,00,'INTO.'
  4081.     db    0ffh,0cfh,00,'IRET.'
  4082.     db    0ffh,0f4h,00,'HLT..'
  4083.     db    0ffh,0f5h,00,'CMC..'
  4084.     db    0ffh,0f8h,00,'CLC..'
  4085.     db    0ffh,0f9h,00,'STC..'
  4086.     db    0ffh,0fah,00,'CLI..'
  4087.     db    0ffh,0fbh,00,'STI..'
  4088.     db    0ffh,0fch,00,'CLD..'
  4089.     db    0ffh,0fdh,00,'STD..'
  4090.     db    0ffh,090h,00,'NOP..'
  4091.     db    0ffh,03fh,00,'AAS..'
  4092.     db    0ffh,0d7h,00,'XLAT.'
  4093.     db    0ffh,060h,00,'PUSHA'    ;186
  4094.     db    0ffh,061h,00,'POPA.'    ;186
  4095.     db    0ffh,0c9h,00,'LEAVE'    ;186
  4096.     db    0ffh,0cch,00,'INT 3'
  4097.     db    0feh,0ech,01,'IN...'    ;AL or AX,DX
  4098.     db    0feh,0eeh,01,'OUT..'    ;DX, AL or AX
  4099.     db    0ffh,0e5h,02,'IN...'    ;AX,nn
  4100.     db    0ffh,0e7h,02,'OUT..'    ;nn,AX
  4101.     db    0f0h,0b0h,03,'MOV..'    ;immed to reg
  4102.     db    0ffh,004h,04,'ADD..'    ; Kind 4 are arith & logic to AL
  4103.     db    0ffh,00ch,04,'OR...'
  4104.     db    0ffh,014h,04,'ADC..'
  4105.     db    0ffh,01ch,04,'SBB..'
  4106.     db    0ffh,024h,04,'AND..'
  4107.     db    0ffh,02ch,04,'SUB..'
  4108.     db    0ffh,034h,04,'XOR..'
  4109.     db    0ffh,03ch,04,'CMP..'    ;immed w/AL, byte
  4110.     db    0ffh,0a8h,04,'TEST.'
  4111.     db    0ffh,005h,06,'ADD..'    ;Kind 6 are arith & logic to AX
  4112.     db    0ffh,00dh,06,'OR...'
  4113.     db    0ffh,015h,06,'ADC..'
  4114.     db    0ffh,01dh,06,'SBB..'
  4115.     db    0ffh,025h,06,'AND..'
  4116.     db    0ffh,02dh,06,'SUB..'
  4117.     db    0ffh,035h,06,'XOR..'
  4118.     db    0ffh,03dh,06,'CMP..'    ;immed w/AX, word
  4119.     db    0ffh,0a9h,06,'TEST.'
  4120.     db    0ffh,0cdh,07,'INT..'
  4121.     db    0ffh,0d4h,08,'AAM..'
  4122.     db    0ffh,0d5h,08,'AAD..'    ;Kind 08 are 2-bytes, 2nd is 0Ah
  4123.     db    0ffh,0f3h,09,'REP..'    ;Kind 09 are prefix instrs...
  4124.     db    0ffh,0f2h,09,'REPNZ'    ;   REPZ, REPE same as REP
  4125.     db    0ffh,0f0h,09,'LOCK.'
  4126.     db    0fdh,068h,10,'PUSH.'    ;186 PUSH nnnn
  4127.     db    0feh,0a4h,12,'MOVS.'    ;Kind 12 are String instructions
  4128.     db    0feh,0a6h,12,'CMPS.'
  4129.     db    0feh,0aah,12,'STOS.'
  4130.     db    0feh,0ach,12,'LODS.'
  4131.     db    0feh,0aeh,12,'SCAS.'
  4132.     db    0feh,06ch,12,'INS..'    ;186 ins [dx]
  4133.     db    0feh,06eh,12,'OUTS.'    ;186 outs [dx]
  4134.     db    0f8h,090h,13,'XCHG.'    ;with AX
  4135.     db    0f8h,040h,15,'INC..'    ;Kind 15 are one 16 bit reg
  4136.     db    0f8h,048h,15,'DEC..'
  4137.     db    0f8h,050h,15,'PUSH.'
  4138.     db    0f8h,058h,15,'POP..'    ;non-seg register
  4139.     db    0f8h,0d8h,16,'Fxxxx'    ;80x87 codes, not done yet
  4140.     db    0f0h,070h,11,'J....'    ;Jxx are 70h-7Fh         [DISPL]
  4141.     db    0ffh,0e3h,21,'JCXZ.'    ;                [DISPL]
  4142.     db    0ffh,0ebh,21,'JMP..'    ;(SHORT jump)            [DISPL]
  4143.     db    0ffh,0e8h,05,'CALL.'    ;                 [DISPL]
  4144.     db    0ffh,0e9h,05,'JMP..'    ;word relative             [DISPL]
  4145.     db    0feh,0e0h,17,'LOOP.'    ;LOOPNZ (E0h) and LOOPZ (E1h)    [DISPL]
  4146.     db    0ffh,0e2h,17,'LOOP.'    ;plain LOOP short-label        [DISPL]
  4147.     db    0c4h,000h,18,'.....'    ;arith, r/m & r to ModRegR/M
  4148.     db    0feh,084h,19,'TEST.'    ;ModRegR/M
  4149.     db    0feh,086h,19,'XCHG.'    ;except with AX
  4150.     db    0fch,088h,19,'MOV..'    ;MOV reg <-> reg/mem
  4151.     db    0fdh,069h,19,'IMUL.'    ;186 ModRegR/M,nnnn
  4152.     db    0ffh,063h,19,'ARPL.'    ;286
  4153.     db    0fch,080h,20,'.....'    ;arith & logic immed to reg/mem
  4154.     db    0ffh,00fh,22,'.....'    ;286 prot control & CLTS prefix
  4155.     db    0ffh,026h,23,'.....'    ;Kind23 is seg override prefix only
  4156.     db    0ffh,02eh,23,'.....'
  4157.     db    0ffh,036h,23,'.....'
  4158.     db    0ffh,03eh,23,'.....'
  4159.     db    0ffh,006h,24,'PUSH.'    ;Kind24 are push/pop SEG REG
  4160.     db    0ffh,00eh,24,'PUSH.'
  4161.     db    0ffh,016h,24,'PUSH.'
  4162.     db    0ffh,01eh,24,'PUSH.'
  4163.     db    0ffh,007h,24,'POP..'    ;ES
  4164.     db    0ffh,017h,24,'POP..'    ;SS
  4165.     db    0ffh,01Fh,24,'POP..'    ;DS
  4166. ;note: POP CS (0Fh) works on 8088,6 only, used as prefix on '186+ !
  4167.     db    0fch,0a0h,25,'MOV..'    ;MOV AL or AX <-> mem
  4168.     db    0fch,0d0h,26,'.....'    ;shift/rotate
  4169.     db    0feh,0C0h,26,'.....'    ;186 shift by count
  4170.     db    0ffh,08fh,27,'.....'    ;POP memory
  4171.     db    0ffh,08ch,28,'.....'    ;MOV mem-or-reg, seg reg
  4172.     db    0ffh,08eh,28,'.....'    ;MOV seg reg, mem-or-reg
  4173.     db    0feh,0c6h,29,'.....'    ;MOV immed to reg/mem
  4174.     db    0ffh,08dh,30,'.....'    ;LEA ModRegR/M, but no Reg
  4175.     db    0feh,0f6h,31,'.....'    ;NOT reg/mem
  4176.     db    0ffh,0feh,32,'.....'    ;INC, DEC  ModRegR/M
  4177.     db    0ffh,0ffh,33,'.....'    ;many: call/jmp DWORD PTR, PUSH mem. etc
  4178.     db    0ffh,09ah,34,'CALL.'    ;OOOO:SSSS
  4179.     db    0ffh,0eah,34,'JMP..'    ;OOOO:SSSS
  4180.     db    0ffh,0C8h,35,'ENTER'    ;'186 ENTER nnnn,nn
  4181.     db    0ffh,0c2h,36,'RET..'    ;RET nnnn
  4182.     db    0ffh,0cah,36,'RETF.'    ;RETF nnnn
  4183.     db    0ffh,0e4h,37,'IN...'    ;IN AL,nn
  4184.     db    0ffh,0e6h,37,'OUT..'    ;OUT nn,AL
  4185.     db    0ffh,062h,38,'BOUND'    ;'186 BOUND wr,dw[nnnn]
  4186.     db    0ffh,0c4h,38,'LES..'    ;ModRegR/M mod not 11
  4187.     db    0ffh,0c5h,38,'LDS..'    ;ModRegR/M mod not 11
  4188.     db    0
  4189. ;--------------------------------
  4190.  
  4191. ;    .SMB (label) table structure, variable length records:
  4192.  
  4193. ;    2 bytes address, 1 byte seg/type, 1 byte string length, n bytes string
  4194. ;    table end defined by length byte = 0
  4195. ;    first byte past end pointed to by symtp
  4196. ;    type bits 1-0: 0=instr, 1=byte, 2=word, 3=dword
  4197. ;    type bits 5-4: 0=ss, 1=ds, 2=es, 3=cs (bit 3 inverted from REG code)
  4198.  
  4199. ;ADDSYM called only in B cmd, creates H0[DX] (or [DX-ORG] for hard coded).
  4200. ;Generates text of H0NNNN (same form as DASM).
  4201. addsym:    mov    bx,offset lblbuf    ;use to build up label string
  4202.     mov    byte ptr [bx],'H'
  4203.     inc    bx
  4204.     mov    byte ptr [bx],'0'
  4205.     inc    bx
  4206.     push    dx            ;label's pcntr addr
  4207.     cmp    RelFlag,0
  4208.     jz    hardcod
  4209.     add    dx,curorg        ;correct text for ORG, rel-displ only
  4210. hardcod:
  4211.     mov    al,dh            ;put DX into string
  4212.     call    StoreHex        ;AL to 2 hex bytes [BX] & inc bx
  4213.     mov    al,dl
  4214.     call    StoreHex
  4215.     pop    dx            ;restore pcntr addr of label
  4216.     mov    bx,offset lblbuf    ;point beginning of string
  4217.     mov    ch,6            ;string length of H0nnnn
  4218. ;SYMTCH also used by E command & to enter 'Start:'.
  4219. symtch:    push    cx
  4220.     push    bx
  4221.     call    symluk            ;is there a label for addr=DX ?
  4222.     pop    bx
  4223.     pop    cx
  4224.     jc    entsym            ;jump if no label at addr
  4225.     ret
  4226.  
  4227. ;first, open up space for new entry
  4228. entsym:    mov    ChgFlag,1        ;for 'Update/Exit'
  4229.     push    bx            ;pointer to string to insert
  4230.     push    cx            ;CH = string length
  4231.     mov    bx,symtp
  4232.     mov    si,bx            ;save old symtp
  4233.     mov    al,ch            ;length of label
  4234.     xor    ah,ah
  4235.     add    al,4
  4236.     add    si,ax
  4237.     mov    symtp,si         ;new '1-past-end' pointer
  4238.     mov    byte ptr [si+3],0    ;zero length byte marks end
  4239.  
  4240. ;now SI = new symtp, BX = old symtp (used SI not DI so no change to ES)
  4241. l22a5:    cmp    bx,NxtSymPtr        ;set by symluk
  4242.     jz    inssym
  4243.     dec    bx
  4244.     dec    si
  4245.     mov    al,[bx]            ;start w/1st byte below old symtp
  4246.     mov    [si],al            ;move to 1st below new sympt
  4247.     jmp    l22a5
  4248.  
  4249. ;put new entry in hole just made, DX = addr of label
  4250. inssym:    pop    cx            ;CH is length byte
  4251.     cmp    RelFlag,0        ;rel-displ ?
  4252.     jnz    notchg
  4253.     cmp    byte ptr cmdbuf+2,'E'    ;in E command? [BYTE PTR reqd]
  4254.     jz    notchg
  4255.     sub    dx,curorg        ;hard-coded oprnds in B command only
  4256. notchg:    mov    [bx],dx
  4257.     inc    bx
  4258.     inc    bx
  4259.     mov    al,OprndType
  4260.     mov    [bx],al
  4261.     inc    bx
  4262.     mov    [bx],ch            ;length of label
  4263.     pop    si            ;was BX, pointer to string to insert
  4264. l22cb:    inc    bx
  4265.     mov    al,[si]
  4266.     mov    [bx],al
  4267.     inc    si
  4268.     dec    ch
  4269.     jnz    l22cb
  4270.     ret
  4271.  
  4272. ;--------------------------------
  4273. ;locate symbol.  BX > start of string to match, CH = length of string.
  4274. ;  Returns w/C set and BX unchanged if not found.
  4275. locsym:    push    dx
  4276.     push    bx        ;string start
  4277.     mov    bx,symbas
  4278. NxSym:    pop    dx
  4279.     push    dx        ;string start
  4280.     inc    bx
  4281.     inc    bx
  4282.     inc    bx
  4283.     push    bx
  4284.     mov    al,[bx]        ;entry's length
  4285.     or    al,al
  4286.     jz    NotFoundExit    ;table end
  4287.     inc    bx
  4288.     cmp    al,ch        ;entry length - string length
  4289.     jnz    PointNext
  4290. ;length matches
  4291.     mov    cl,al        ;bytes to compare
  4292.     call    cmpstr
  4293.     jz    symfnd        ;found right entry
  4294. PointNext:
  4295.     pop    bx        ;points length byte of same entry
  4296.     mov    al,[bx]
  4297.     inc    bx        ;string start
  4298.     call    AddALtoBX
  4299.     jmp    NxSym
  4300.  
  4301. symfnd:    pop    bx        ;points length byte of same entry
  4302.     dec    bx
  4303.     dec    bx
  4304.     dec    bx        ;back to entry start
  4305.     pop    dx        ;adj stack
  4306.     pop    dx
  4307.     clc
  4308.     ret
  4309.  
  4310. NotFoundExit:
  4311.     pop    bx
  4312.     pop    bx
  4313.     pop    dx
  4314.     stc            ;not found flag
  4315.     ret
  4316.  
  4317. ;--------------------------------
  4318. ;Check for symbol/label at [DX] (or [DX-ORG] for hard coded addrs)
  4319. ;Struc: 2 bytes address, 1 byte Oprndtype, 1 byte string length, n bytes string
  4320. ;saves DX, BX lost - no carry & BX > start of string, CH=length if found.
  4321. symluk:    mov    bx,symbas
  4322.     mov    NxtSymAddr,0        ;changed if exist lbl at or past DX addr
  4323.     push    dx
  4324.     cmp    RelFlag,0        ;rel-displ instr ?
  4325.     jnz    SymlookLoop        ;yes, jump
  4326.     cmp    byte ptr cmdbuf+2,'E'    ;are we entering a label?
  4327.     jz    SymlookLoop
  4328.     cmp    word ptr cmdbuf+2,'SD'    ;are we Dumping Symbol table ?
  4329.     jz    SymlookLoop
  4330.     cmp    word ptr cmdbuf+2,0D43h    ;cr,'C' - are we dumping the CTL table ?
  4331.     jz    SymlookLoop
  4332.     sub    dx,curorg
  4333. SymlookLoop:
  4334.     mov    ax,[bx]            ;get address
  4335.     add    bx,3            ;to length byte
  4336.     cmp    ax,dx            ;this lbl's addr - one we want
  4337.     jz    SmbFound
  4338.     jc    ChkForEnd
  4339. ;this is 1st label is for addr higher than DX
  4340.     sub    bx,3            ;back to addr
  4341.     mov    NxtSymPtr,bx
  4342.     mov    dx,[bx]
  4343.     mov    NxtSymAddr,dx
  4344.     stc                ;signal not found
  4345.     jmp    EndSymLook
  4346.  
  4347. ;this label addr is less than the one we're looking for
  4348. ChkForEnd:
  4349.     mov    al,[bx]
  4350.     or    al,al            ;end of table ?
  4351.     stc
  4352.     jnz    l2348            ;not end
  4353.     mov    bx,symtp
  4354.     mov    NxtSymPtr,bx
  4355.     jmp    EndSymlook        ;addr past highest in table, ret w/C
  4356.  
  4357. l2348:    inc    bx            ;to 1st of string
  4358.     call    AddALtoBX        ;adj for string length
  4359.     jmp    short SymlookLoop
  4360.  
  4361. SmbFound:                ;(segment scheme req chk seg here)
  4362.     mov    ch,[bx]            ;string length to return
  4363.     mov    NxtSymPtr,bx
  4364.     sub    NxtSymPtr,3        ;point to start of entry, the addr
  4365.     inc    bx            ;string pointer to return
  4366.     or    ch,ch            ;clears carry flag, too
  4367.     jz    EOT            ;ret w/carry if end of table
  4368.     push    bx
  4369.     mov    al,ch
  4370.     call    AddALtoBX        ;point to next label's address
  4371.     mov    dx,[bx]
  4372.     mov    NxtSymAddr,dx
  4373.     pop    bx
  4374.     clc
  4375.     jmp    short EndSymlook
  4376.  
  4377. EOT:    stc
  4378. EndSymlook:
  4379.     pop    dx
  4380.     ret                ;with carry if end of table
  4381. ;--------------------------------
  4382.  
  4383. ;ENTER A LABEL (SYMBOL)
  4384. cmentr:    mov    bx,offset cmdbuf+3    ;1st byte after the E
  4385.     call    gtval            ;label (pcntr, not ORG) address to DX
  4386.     mov    al,[bx]
  4387.     call    delim            ;comma or space must exist
  4388.     inc    bx
  4389.     mov    al,[bx]
  4390.     cmp    al,'.'
  4391.     jz    DotIsThere        ;dot must prefix label text
  4392.     call    cmerr
  4393.  
  4394. DotIsThere:
  4395.     push    dx            ;label pcntr address
  4396.     push    bx            ;cmdbuf pointer to '.'
  4397.     call    LblChk            ;checks permissible characters
  4398. ;be sure label doesn't exist
  4399.     call    locsym
  4400.     jb    nohit
  4401.     call    prtstr
  4402.     db    'Label already exists...',cr,lf,0
  4403.     jmp    nxcmd
  4404.  
  4405. nohit:    mov    ChgFlag,1        ;for 'Update/Exit'
  4406.     pop    bx            ;cmdbuf pointer to '.'
  4407.     pop    dx            ;label pcntr address
  4408.     push    dx
  4409.     push    bx
  4410.     call    symluk            ;is there a label at this addr?
  4411.     jc    symnf            ;jmp if not
  4412.     push    bx
  4413.     call    CrLf
  4414.     call    PrtCHbytesPerBX
  4415.     call    prtstr
  4416.     db    ' was killed',7,cr,lf,0
  4417.     pop    bx            ;from symluk, >1st of text
  4418.     dec    bx
  4419.     dec    bx
  4420.     mov    al,[bx]            ;type byte of found label
  4421.     mov    OprndType,al        ;to be same for replacement label
  4422.     dec    bx
  4423.     dec    bx
  4424.     call    lkill
  4425. symnf:    pop    bx            ;orig cmdbuf pointer
  4426.     call    LblChk            ;BX > 1st char in label, CH = chars
  4427.     pop    dx            ;label address
  4428.     call    symtch            ;puts label in table at DX
  4429.     jmp    nxcmd
  4430. ;--------------------------------
  4431.  
  4432. cmkill:    mov    bx,offset cmdbuf+3    ;1st byte after the K in command
  4433.     mov    al,[bx]
  4434.     cmp    al,'.'
  4435.     jz    l2396
  4436.     call    cmerr
  4437.  
  4438. l2396:    call    LblChk
  4439.     call    locsym
  4440.     jnc    l23a1            ;found it
  4441.     call    cmerr
  4442.  
  4443. l23a1:    call    lkill
  4444.     jmp    nxcmd
  4445.  
  4446. lkill:    mov    cx,bx
  4447.     inc    bx
  4448.     inc    bx
  4449.     inc    bx
  4450.     mov    al,[bx]
  4451.     sub    ah,ah
  4452.     add    bx,ax
  4453.     inc    bx
  4454.     xchg    bx,dx        ;hold in dx
  4455.     mov    bx,symtp
  4456. l23b8:    cmp    dx,bx        ;at top yet?
  4457.     jz    l23d5
  4458.     xchg    bx,dx
  4459.     mov    al,[bx]        ;from [dx]
  4460.     xchg    bx,dx
  4461.     xchg    bx,cx
  4462.     mov    [bx],al        ;to [cx]
  4463.     xchg    bx,cx
  4464.     inc    cx
  4465.     inc    dx
  4466.     jmp    l23b8
  4467.  
  4468. l23d5:    mov    bx,cx
  4469.     mov    symtp,bx    ;new top
  4470.     mov    byte ptr [bx+3],0
  4471.     ret
  4472. ;--------------------------------
  4473. ;enter with BX > dot before label.  Exit CH = chars in label
  4474. ;returns BX > 1st char of label, DX > 1st char after label
  4475. LblChk:    inc    bx        ;skip dot symbol flag
  4476.     xor    ch,ch        ;clear length counter
  4477.     push    bx        ;save string start pntr
  4478.     mov    al,[bx]        ;get first char
  4479. ;for 1st char only:
  4480.     cmp    al,cr
  4481.     jz    LblErr
  4482.     cmp    al,'.'        ;period allowed only as 1st char
  4483.     jz    nxtcnt
  4484.     cmp    al,'$'        ;weed
  4485.     jz    nxtcnt        ;  out
  4486.     cmp    al,'9'+1    ;    digits in 1st char
  4487.     jc    LblErr
  4488. nxtcnt:    inc    bx        ;starts with 2nd char
  4489.     inc    ch        ;bump the count
  4490.     mov    al,[bx]
  4491.     cmp    al,cr        ;label ends at a CR,
  4492.     jz    endcnt
  4493.     cmp    al,','        ;  or a comma
  4494.     jz    endcnt
  4495.     cmp    al,'$'
  4496.     jz    nxtcnt
  4497.     cmp    al,'_'
  4498.     jz    nxtcnt
  4499.     cmp    al,'0'
  4500.     jb    LblErr
  4501.     cmp    al,'9'+1
  4502.     jb    nxtcnt
  4503.     cmp    al,'?'
  4504.     jae    nxtcnt
  4505.     cmp    al,'Z'+1
  4506.     jb    nxtcnt
  4507. LblErr:    call    prtstr
  4508.     db    7,cr,lf,'Period only as 1st character'
  4509.     db    cr,lf,'0-9 must not be 1st character'
  4510.     db    cr,lf,'Also allowed are  $ ? _ @',cr,lf,0
  4511.     jmp    nxcmd
  4512.  
  4513. endcnt:    mov    dx,bx        ;delimiter ptr to DX
  4514.     pop    bx        ;string start pointer
  4515.     ret
  4516. ;--------------------------------
  4517. StoreHex:
  4518.     push    ax        ;AL to 2 hex chars [BX]
  4519.     call    hexl
  4520.     mov    [bx],al
  4521.     inc    bx
  4522.     pop    ax
  4523.     call    hexr
  4524.     mov    [bx],al
  4525.     inc    bx
  4526.     ret
  4527.  
  4528. hexl:    shr    al,1        ;move hi nibble to lo nibble
  4529.     shr    al,1
  4530.     shr    al,1
  4531.     shr    al,1
  4532. hexr:    and    al,0Fh
  4533.     cmp    al,0Ah
  4534.     jb    hexrn
  4535.     add    al,7
  4536. hexrn:    add    al,'0'        ;30h, make ASCII
  4537.     ret
  4538.  
  4539. ;print AL with leading zero if 0Ah or above
  4540. xo0:    cmp    al,0A0h
  4541.     jnb    Leading0
  4542.     jmp    xo
  4543.  
  4544. Leading0:
  4545.     push    ax
  4546.     mov    al,'0'
  4547.     call    typech
  4548.     pop    ax
  4549. xo:    push    ax
  4550.     call    hexl
  4551.     call    typech
  4552.     pop    ax
  4553.     call    hexr
  4554.     jmp    typech
  4555.  
  4556. Print00BX_:            ;with leading zeros and trailing space
  4557.     mov    al,bh
  4558.     call    xo
  4559.     mov    al,bl
  4560.     call    xo
  4561. prspc:    mov    al,' '
  4562.     jmp    typech
  4563.  
  4564. ;--------------------------------
  4565. ;GET USER INPUT NUMBERS (or no. equiv of label) from cmdbuf to DX
  4566. gtval:    mov    al,[bx]
  4567.     cmp    al,'.'
  4568.     jz    GetSmbAddr
  4569.     mov    dx,0
  4570. hexbi:    mov    al,[bx]
  4571.     cmp    al,'0'        ;30h
  4572.     jnb    NumContinues
  4573. ;it's a punctuation mark, the no. has ended
  4574.     sub    dx,curorg    ;correct address for ORG (pcntr always wrt 0)
  4575.     ret            ;w/carry set if DX less than 0
  4576.  
  4577. NumContinues:
  4578.     cmp    al,'9'+1    ;3ah
  4579.     jb    cvnum
  4580.     cmp    al,'A'        ;41h
  4581.     jnb    l2468
  4582.     ret
  4583.  
  4584. l2468:    cmp    al,'G'
  4585.     jb    l246d        ;thru F it's a Hex character
  4586.     ret
  4587.  
  4588. l246d:    sub    al,7
  4589. cvnum:    sub    al,'0'        ;30h
  4590.     xchg    bx,dx
  4591.     add    bx,bx
  4592.     add    bx,bx
  4593.     add    bx,bx
  4594.     add    bx,bx
  4595.     add    al,bl
  4596.     mov    bl,al
  4597.     xchg    bx,dx
  4598.     inc    bx        ;point to next char
  4599.     jmp    hexbi        ;back near start of this routine
  4600.  
  4601. GetSmbAddr:            ;now BX > the dot before the label
  4602.     call    LblChk        ;rets w/DX > delimiter (CR or comma after lbl),
  4603.     push    dx        ;  BX > 1st char of label and CH = bytes in lbl
  4604.     call    locsym
  4605.     jnc    l2491        ;it exists
  4606.     pop    dx
  4607.     call    prtstr
  4608.     db    cr,lf,'Label not found',7,cr,lf,0
  4609.     jmp    nxcmd
  4610.  
  4611. l2491:    mov    dx,[bx]        ;symbol value
  4612.     pop    bx        ;was DX
  4613.     mov    al,[bx]        ;string terminator
  4614.     ret
  4615. ;--------------------------------
  4616. fopen:    push    bx
  4617.     mov    ah,3Dh            ;open file w/handle to AX
  4618.     mov    al,2            ;read/write
  4619.     mov    dx,offset FileString
  4620.     int    21h
  4621.     mov    Handle,ax
  4622.     mov    DTAptr,100h        ;so GetByte will first fill buffer
  4623.     pop    bx
  4624.     ret                ;w/no carry if successful
  4625.  
  4626. OpenError:
  4627.     call    prtstr
  4628.     db    tab,tab,tab,'FILE NOT FOUND',0
  4629.     stc
  4630.     ret
  4631. ;--------------------------------
  4632. ;read a byte from the buffer at old DTA, read in 128 bytes if empty
  4633. GetByte:
  4634.     push    bx
  4635.     mov    bx,DTAptr    ;was set to 100h at fopen
  4636.     test    bh,1        ;AND, tests bit 0, so NZ 1st pass
  4637.     jz    StillGotSome    ;DTAptr has NOT passed 0100h, end of buffer
  4638. ;refill the 'DTA'
  4639.     push    cx
  4640.     push    dx
  4641.     mov    cx,128        ;bytes to read
  4642.     mov    bx,Handle
  4643.     mov    dx,DefaultDTA    ;equ 80h, in the PSP
  4644.     mov    ah,3Fh        ;read w/handle
  4645.     int    21h
  4646.     jnc    CtuXX
  4647.     jmp    ReadErr
  4648. CtuXX:    or    ax,ax
  4649.     jz    mrkeof        ;EOF has been read
  4650.     pop    dx
  4651.     pop    cx
  4652.     mov    bx,DefaultDTA    ;equ 80h
  4653.  
  4654. StillGotSome:
  4655.     mov    al,[bx]
  4656.     inc    bx
  4657.     mov    DTAptr,bx
  4658.     pop    bx
  4659.     ret
  4660.  
  4661. mrkeof:    mov    bx,DefaultDTA
  4662.     mov    al,1Ah
  4663.     mov    [bx],al
  4664.     jmp    StillGotSome    ;now will RET w/AL=1Ah
  4665.  
  4666. ;--------------------------------
  4667. creatf:    push    bx
  4668.     mov    ah,3Ch            ;create file w/handle
  4669.     push    cs
  4670.     pop    ds            ;just to be sure
  4671.     mov    dx,offset FileString    ;DS:DX points to ASCIIZ string
  4672.     xor    cx,cx            ;attribute = normal file
  4673.     int    21h
  4674.     jc    CreateErr
  4675.     mov    Handle,ax
  4676.     mov    DTAptr,DefaultDTA    ;equ 80h
  4677.     pop    bx
  4678.     ret
  4679.  
  4680. CreateErr:
  4681.     push    ax
  4682.     call    prtstr
  4683.     db    cr,lf,'Error creating file: Func 3Ch, AX returned ',0
  4684.     pop    bx
  4685.     call    Print00BX_
  4686.     call    prtstr
  4687.     db    'hex',cr,lf,0
  4688.     jmp    nxcmd
  4689.  
  4690. ;--------------------------------
  4691. WriteNclose:
  4692.     mov    al,1Ah
  4693.     call    WriteChar        ;add EOF to file
  4694.     mov    cx,DTAptr        ;points 1 past the EOF char
  4695.     sub    cx,DefaultDTA        ;now cx = bytes to write
  4696.     call    DumpDTA
  4697. fclose:    push    bx
  4698.     mov    ah,3Eh            ;close file w/handle
  4699.     mov    bx,Handle
  4700.     int    21h
  4701.     pop    bx
  4702.     ret
  4703.  
  4704. CloseErr:
  4705.     call    prtstr
  4706.     db    'ERROR closing file (DOS func 3Eh)',cr,lf,0
  4707.     jmp    nxcmd
  4708.  
  4709. DiskFull:
  4710.     call    prtstr
  4711.     db    'Oh, phooey the disk is full !!',cr,lf,0
  4712.     jmp    nxcmd
  4713.  
  4714. WriteChar:
  4715.     push    cx
  4716.     push    bx
  4717.     mov    bx,DTAptr
  4718.     mov    [bx],al
  4719.     inc    bl
  4720.     mov    DTAptr,bx
  4721.     pop    bx
  4722.     mov    cx,128        ;bytes to write
  4723.     jnz    WrChRet
  4724.     call    DumpDTA        ;DTAptr just rolled past 0FFh
  4725. WrChRet:
  4726.     pop    cx
  4727.     ret
  4728.  
  4729. DumpDTA:            ;called by WriteNclose, too
  4730.     push    dx
  4731.     push    bx
  4732.     mov    bx,Handle
  4733.     mov    dx,DefaultDTA    ;equ 80h, in the PSP
  4734.     mov    ah,40h        ;write to file w/handle
  4735.     int    21h
  4736.     jc    WriteErr    ;stack is reset by NXCMD, don't worry
  4737.     cmp    ax,cx        ;bytes written - bytes requested
  4738.     jnz    DiskFull
  4739.     mov    bx,DefaultDTA    ;equ 80h
  4740.     mov    DTAptr,bx    ;reset pointer to start of DTA
  4741.     pop    bx
  4742.     pop    dx
  4743.     ret
  4744.  
  4745. WriteErr:
  4746.     push    ax
  4747.     call    prtstr
  4748.     db    cr,lf,'Error writing file: Func 40h, AX returned ',0
  4749.     pop    bx
  4750.     call    Print00BX_
  4751.     call    prtstr
  4752.     db    'hex',cr,lf,0
  4753.     jmp    nxcmd
  4754.  
  4755. ;--------------------------------
  4756. ;called after every line
  4757. NewLine:
  4758.     mov    LongFlag,0
  4759.     mov    bx,AppendPtr
  4760.     or    bx,bx
  4761.     jz    NewLine2
  4762.     call    PrtTab
  4763.     mov    ch,[bx]
  4764.     or    ch,ch        ;zero-length remark ?
  4765.     jz    NewLine2    ;if so, do nothing
  4766. PrtAppendedRem:
  4767.     inc    bx
  4768.     mov    al,[bx]
  4769.     call    typech
  4770.     dec    ch
  4771.     jnz    PrtAppendedRem
  4772. NewLine2:
  4773.     mov    AppendPtr,0
  4774. UnasmCrLf:
  4775.     mov    al,CurInstr    ;check opcode for JMP, RET, etc for blank line
  4776.     cmp    al,0C3h
  4777.     jz    SkipAline
  4778.     cmp    al,0E9h        ;2-byte jmp in segment, also used by
  4779.                 ; CALL, etc to force blank line.
  4780.     jz    SkipAline
  4781.     cmp    al,0EBh        ;jmp short
  4782.     jz    SkipAline
  4783.     cmp    al,0C2h        ;ret in seg, add immed to SP
  4784.     jz    SkipAline
  4785.     cmp    al,0CAh        ;ret far, add immed to SP
  4786.     jz    SkipAline
  4787.     cmp    al,0CBh        ;ret far
  4788.     jz    SkipAline
  4789.     cmp    al,0CFh        ;iret
  4790.     jz    SkipAline
  4791.     cmp    al,0EAh        ;jmp far
  4792.     jz    SkipAline
  4793.     cmp    al,0E2h        ;LOOP
  4794.     jz    SkipAline
  4795. CrLf:    mov    al,cr
  4796.     call    typech
  4797.     mov    al,lf
  4798.     jmp    typech
  4799.  
  4800. SkipAline:
  4801.     call    CrLf
  4802.     mov    al,' '
  4803.     mov    CurInstr,al    ;why ??
  4804.     jmp    CrLf
  4805.  
  4806. ;--------------------------------
  4807. ;GET COMMAND from the keyboard
  4808. gtcmd:    mov    UpCaseFlag,1        ;assume command is not ; or E
  4809.     mov    bx,offset segsho    ;prompt string
  4810.     mov    ch,3            ;no. of characters
  4811.     call    PrtCHbytesPerBX
  4812.     xor    dh,dh            ;clear the byte count
  4813.     mov    bx, offset cmdbuf
  4814.     inc    bx
  4815.     inc    bx            ;for compatibility, start @ cmdbuf+2
  4816. nexkey:    mov    ah,0            ;read next kbd char into AL
  4817.     int    16h
  4818.     or    al,al            ;check for non-ASCII key
  4819.     jnz    NoSpl
  4820.     jmp    splkey
  4821. ;now change lower to upper-case if reqd.  First, check for ';', comma, or '.'
  4822. NoSpl:    cmp    al,','
  4823.     jz    LoCaseOK
  4824.     cmp    al,'e'
  4825.     jz    LoCaseOK
  4826.     cmp    al,'E'
  4827.     jz    LoCaseOK
  4828.     cmp    al,';'
  4829.     jz    LoCaseOK
  4830. UpCaseIt:
  4831.     cmp    UpCaseFlag,0
  4832.     jz    uc2cmd
  4833.     call    CapitalizeAL
  4834. uc2cmd:    cmp    al,' '
  4835.     jnz    NotSpace
  4836.     cmp    byte ptr cmdbuf+2,';'
  4837.     jz    NotSpace
  4838.     jmp    BeepBeep        ;space allowed only in Remarks
  4839. NotSpace:
  4840.     mov    [bx],al            ;put char in cmdbuf
  4841.     mov    ah,0Eh            ;show on screen and move cursor
  4842.     int    10h
  4843.     cmp    al,cr            ;ENTER hit?
  4844.     jnz    noentr
  4845.     mov    byte ptr ds:[cmdbuf+1],dh ;like func 0A, byte count to 2nd byte
  4846.     jmp    CrLf            ;vector to command routines
  4847.  
  4848. CapitalizeAL:
  4849.     cmp    al,'a'
  4850.     jb    Nope
  4851.     cmp    al,'z'+1
  4852.     jnb    Nope
  4853.     and    al,5Fh            ;converts to Upper-case
  4854. Nope:    ret
  4855.  
  4856. LoCaseOK:                ;char is ; or e or E or comma
  4857.     cmp    al,','
  4858.     jz    DoComma
  4859.     or    dh,dh            ;first char E or ; ?
  4860.     jnz    UpCaseIt
  4861.     mov    UpCaseFlag,2        ;flag next comma turn off upper case
  4862.     jmp    short UpCaseIt
  4863.  
  4864. DoComma:
  4865.     cmp    UpCaseFlag,2
  4866.     jnz    UpCaseIt
  4867.     mov    UpCaseFlag,0
  4868.     jmp    short UpCaseIt
  4869.  
  4870. noentr:    cmp    al,8            ;check for backspace
  4871.     jnz    nobksp
  4872.     or    dh,dh            ;is cursor at left end of field?
  4873.     jnz    goback
  4874.     mov    al,segsho[2]        ;bksp put cursor on last of arrow
  4875.     mov    ah,0Eh            ;so replace it & move cursor back up
  4876.     int    10h
  4877.     jmp    nexkey
  4878.  
  4879. goback:    dec    dh
  4880.     jnz    NotTheFirst
  4881.     mov    UpCaseFlag,1        ;must have erased 1st char
  4882. NotTheFirst:
  4883.     dec    bx
  4884.     mov    al,' '
  4885.     mov    ah,9            ;write char at cursor, no move cursor
  4886.     mov    cx,1            ;no of reps
  4887.     push    bx            ;must save BX
  4888.     mov    bx,7            ;page=0, attrib=normal wht on blk
  4889.     int    10h
  4890.     pop    bx
  4891.     jmp    nexkey
  4892.  
  4893. nobksp:    cmp    al,'Q'            ;Quit ?
  4894.     jnz    NotQ
  4895.     cmp    byte ptr [bx-1],1Bh    ;was previous char ESC ?
  4896.     jnz    NotQ
  4897.     jmp    cmexit            ;Update/Exit w/Errorlevel 0
  4898. NotQ:    or    dh,dh            ;is this the 1st char entered ?
  4899.     jnz    NotP
  4900.     cmp    al,'P'
  4901.     jnz    NotP
  4902. ;set new d:\path\name to save to
  4903.     mov    si,offset FileString
  4904. PathLoop:
  4905.     inc    dh
  4906.     inc    bx
  4907.     lodsb
  4908.     cmp    al,'.'
  4909.     jz    ToNexKey
  4910.     or    al,al
  4911.     jz    ToNexKey
  4912.     mov    [bx],al
  4913.     mov    ah,0Eh
  4914.     int    10h            ;show on screen and move cursor
  4915.     jmp    short PathLoop
  4916.  
  4917. ToNexKey:
  4918.     jmp    nexkey
  4919.  
  4920. NotP:    cmp    al,'='
  4921.     jnz    NotEqSign
  4922.     cmp    byte ptr [bx-1],'U'    ;doing U= (set lines to Unasm) ?
  4923.     jnz    NotEqSign
  4924.     call    prtstr
  4925.     db    '(hex)',0
  4926. NotEqSign:
  4927.     inc    dh            ;bump byte counter
  4928.     inc    bx            ;bump cmdbuf pointer
  4929.     jmp    nexkey
  4930.  
  4931. ;key was non-ASCII (AL was 0, so AH holds special scan code)
  4932. splkey:    cmp    ah,51h
  4933.     jz    PgDn
  4934.     cmp    ah,50h            ;down arrow
  4935.     jnz    nodnar
  4936.     jmp    downar
  4937. nodnar:    cmp    ah,49h
  4938.     jz    PgUp
  4939.     cmp    ah,84h            ;ctrl-pgup
  4940.     jz    ctlpup
  4941.     cmp    ah,43h            ;F9 key
  4942.     jnz    notF9
  4943.     call    sav_em
  4944.     jmp    nxcmd
  4945.  
  4946. notF9:    cmp    ah,3Bh            ;F1 key
  4947.     jnz    ToNexKey
  4948.     jmp    cmhelp
  4949.  
  4950. PgDn:    cmp    hlpflg,0        ;are we in Help?
  4951.     jnz    yeshlp
  4952. ;what did we do last ?
  4953.     cmp    byte ptr cmdbuf+2,'D'    ;are we in Dump or DS ?
  4954.     jnz    to_Udown
  4955.     cmp    byte ptr cmdbuf+3,'S'    ;did we just dump sym table ?
  4956.     jz    to_Udown
  4957.     mov    byte ptr cmdbuf+3,cr    ;set up cmdump to continue last dump
  4958.     call    prtstr            ;start header at beginning of line!
  4959.     db    cr,0
  4960.     jmp    cmdump
  4961.  
  4962. to_Udown:
  4963.     jmp    Udown
  4964.  
  4965. yeshlp:    mov    al,helpno
  4966.     inc    al
  4967.     cmp    al,3            ;3 screens, no 2 is last
  4968. hlpend:    jz    BeepBeep
  4969.     mov    helpno,al
  4970.     call    CrLf            ;keeps cmd line off display
  4971.     jmp    cmhelp
  4972.  
  4973. BeepBeep:
  4974.     call    prtstr
  4975.     db    7,0            ;BEL, makes a beep
  4976. ToNexKey2:
  4977.     jmp    nexkey
  4978.  
  4979. PgUp:    cmp    hlpflg,0
  4980.     jnz    helpup
  4981.     jmp    nexkey
  4982.  
  4983. helpup:    mov    al,helpno
  4984.     dec    al
  4985.     cmp    al,0FFh            ;AL was 0
  4986.     jmp    short    hlpend
  4987.  
  4988. ctlpup:    cmp    byte ptr cmdbuf+2,'D'    ;are we in Dump?
  4989.     jnz    Ustart
  4990.     cmp    byte ptr cmdbuf+3,'S'    ;did we just DS (dump sym table) ?
  4991.     jz    Ustart
  4992.     mov    bx,dmpcnt
  4993.     mov    DumpEnd,bx        ;dump a full page
  4994.     mov    DumpStart,0        ;start at 0 + ORG
  4995.     jmp    dmphdr
  4996.  
  4997. downar:    mov    ah,byte ptr cmdbuf+2    ;find out what we last did
  4998.     cmp    ah,'A'
  4999.     jz    onelin
  5000.     cmp    ah,'B'
  5001.     jz    onelin
  5002.     cmp    ah,'U'
  5003.     jz    onelin
  5004.     cmp    ah,'D'
  5005.     jnz    ToNexKey2
  5006.     cmp    byte ptr cmdbuf+3,'S'
  5007.     jz    ToNexKey2
  5008. ;cmdbuf holds D but not DS, so Dump one more line of hex code
  5009.     add    DumpEnd,16
  5010.     call    prtstr
  5011.     db    cr,0
  5012.     jmp    cntdmp
  5013.  
  5014. onelin:    mov    al,1
  5015.     jmp    short DoALlines
  5016.  
  5017. Ustart:    call    CrLf
  5018.     mov    pcntr,0
  5019.     mov    AmodeFlag,0        ;turn off A and
  5020.     mov    BmodeFlag,0        ;  B mode
  5021. Udown:    mov    byte ptr cmdbuf+2,'U'    ;for down arrow
  5022.     mov    al,LnsPerScreen
  5023. DoALlines:
  5024.     mov    wfiflg,0        ;no write file, default for TwentyLines
  5025.     mov    LinesToGo,al
  5026.     mov    LCountFlag,al        ;do specific line count
  5027.     call    prtstr
  5028.     db    cr,0            ;so will overwrite the '══'
  5029.     jmp    TwentyLines
  5030.  
  5031. ;F9 has been hit, save the .REM, .SMB, and .CTL files
  5032. sav_em:    call    ChkNoFSpec        ;save as 'SEG_nnnn.xxx' if doing RAM
  5033.     cmp    ASMopenFlag,0
  5034.     jz    ok2sav
  5035.     jmp    ASMstillOpenErr
  5036. ok2sav:    jmp    SaveAll            ;resets ChgFlag
  5037.  
  5038. ;--------------------------------
  5039. ;Print ASCIIZ string (ends in 0) following call, to screen/both. Saves AX,BX,DX.
  5040. prtstr:    mov    wfiflg,0        ;output to screen only, not file
  5041. pstg:    pop    si            ;get RET addr (of byte past call)
  5042.     xchg    bx,si
  5043.     push    si            ;now BX points to byte after call
  5044.     push    ax
  5045. ostrlp:    mov    al,cs:[bx]
  5046.     call    typech            ;print at least one char - saves DX
  5047.     inc    bx
  5048.     mov    al,cs:[bx]
  5049.     or    al,al
  5050.     jnz    ostrlp            ;loop if not 0
  5051.     pop    ax
  5052.     inc    bx
  5053.     pop    si
  5054.     xchg    bx,si            ;BX & DX saved
  5055.     push    si            ;make RET addr the byte after the 0
  5056.     ret
  5057.  
  5058. ;--------------------------------
  5059. ;Print [AL] to screen and/or output file buffer as req'd
  5060.  
  5061. typech:    inc    strcnt        ;for ASCII lines
  5062.     push    ax
  5063.     push    cx
  5064.     push    dx
  5065.     push    bx
  5066.     mov    dl,al        ;the character to print
  5067.     push    dx
  5068.     push    es
  5069.     mov    ah,2        ;display the character in DL
  5070.     int    21h
  5071.     pop    es
  5072.     pop    dx
  5073.     mov    al,ASMopenFlag
  5074.     and    al,wfiflg
  5075.     mov    al,dl
  5076.     jz    l25d8        ;jump if both wfiflg and ASMopenFlag are 0
  5077.     call    WriteChar    ;write to file buffer
  5078. l25d8:    mov    al,dl
  5079.     cmp    al,lf
  5080.     jnz    notlf
  5081. ;character was Line Feed
  5082.     cmp    LCountFlag,0
  5083.     jz    notlf
  5084.     dec    LinesToGo
  5085. notlf:    pop    bx
  5086.     pop    dx
  5087.     pop    cx
  5088.     pop    ax
  5089.     ret
  5090. ;--------------------------------
  5091.  
  5092. ClearTables:
  5093.     mov    bx,symbas
  5094.     mov    byte ptr [bx+3],0    ;zero size byte
  5095.     mov    symtp,bx        ;top = bottom
  5096.     mov    byte ptr cmdbuf+3,0Dh    ;null command [shouldn't this be +2 ???]
  5097.     mov    cfence,'I'        ;initial mode=Instrs (cfence=ctlbas-1)
  5098.     mov    al,segsho
  5099.     mov    byte ptr ctlbas,al    ;1st byte of prompt arrow initially
  5100.     mov    word ptr ctlbas+1,0FFFFh ;end flag for addr's in .CTL table
  5101.     mov    bx,offset ctlbas+0C00h
  5102.     mov    ctltop,bx        ;max length of ctl table 3K bytes
  5103.     mov    bx,remtbl        ;set at start of pgm to REMBAS
  5104.     mov    remend,bx        ;end = start
  5105.     mov    word ptr [bx],0FFFFh    ;end marker
  5106.     mov    Direc286Flag,0
  5107.     ret
  5108.  
  5109. ;--------------------------------
  5110. ;case-INsensitive string compare, [BX] & [DX], CL=length.  Z set => match.
  5111. cmpstr:    push    bx
  5112.     push    cx
  5113. CmpStrLoop:
  5114.     xchg    bx,dx
  5115.     mov    al,[bx]        ;get [DX] byte
  5116.     call    CapitalizeAL
  5117.     mov    ah,al
  5118.     xchg    bx,dx
  5119.     mov    al,[bx]
  5120.     call    CapitalizeAL
  5121.     cmp    al,ah        ;compare w/[BX] byte
  5122.     jz    Match
  5123.     jmp    short CmpEnd    ;w/NZ
  5124.  
  5125. Match:    inc    dx
  5126.     inc    bx
  5127.     dec    cl        ;bytes to compare
  5128.     jnz    CmpStrLoop
  5129. CmpEnd:    pop    cx
  5130.     pop    bx
  5131.     ret            ;w/Z set if match
  5132.  
  5133. ;--------------------------------
  5134. BreakChk:
  5135.     push    cx
  5136.     push    dx
  5137.     push    bx
  5138.     mov    ah,0Bh        ;check for kbd input
  5139.     int    21h
  5140.     or    al,al
  5141.     jz    NeverMind    ;if no character is available, ret
  5142.     mov    ah,1        ;kbd input w/echo to screen
  5143.     int    21h
  5144.     cmp    al,3        ;ctrl-C
  5145.     jz    abort
  5146.     call    CrLf
  5147.     jmp    nxcmd
  5148.  
  5149. abort:    call    prtstr
  5150.     db    cr,lf,'ABORT Y/N ',0
  5151.     mov    ah,1        ;kbd input w/echo to screen
  5152.     int    21h
  5153.     and    al,5Fh        ;make Upper-Case
  5154.     cmp    al,'Y'
  5155.     jnz    NotExit
  5156.     mov    ah,4Ch
  5157.     mov    al,1        ;Errorlevel = 1
  5158.     int    21h        ;normal terminate
  5159.  
  5160. NotExit:
  5161.     jmp    nxcmd
  5162.  
  5163. NeverMind:
  5164.     pop    bx
  5165.     pop    dx
  5166.     pop    cx
  5167.     ret
  5168. ;--------------------------------
  5169. ;test for DB (cr, lf, 0, tab, bel, space thru 7Fh) - no carry if ASCII
  5170. ;called twice, with al=es:[bx]
  5171. IfASCII:
  5172.     cmp    al,cr
  5173.     jnz    Not0Da
  5174.     ret
  5175.  
  5176. Not0Da:    cmp    al,lf
  5177.     jnz    Not0Aa
  5178.     ret
  5179.  
  5180. Not0Aa:    or    al,al
  5181.     jnz    Not0a
  5182.     ret
  5183.  
  5184. Not0a:    cmp    al,tab
  5185.     jnz    NotTa
  5186.     ret
  5187.  
  5188. NotTa:    cmp    al,bel
  5189.     jnz    NotBel
  5190.     ret
  5191.  
  5192. NotBel:    cmp    al,' '    ;20h
  5193.     jnb    SpaceOrAbove
  5194.     ret
  5195.  
  5196. SpaceOrAbove:
  5197.     cmp    al,3Ch        ;code for CMP AL
  5198.     jnz    NotCMP
  5199.     mov    ah,es:[bx+2]
  5200.     cmp    ah,70h        ;Jxx lowest code
  5201.     jb    NotCMP
  5202.     cmp    ah,7Ah        ;Jxx highest code
  5203.     ja    NotCMP
  5204. ;char is 3Ch and 2nd char following is a Jxx instr
  5205.     stc
  5206.     ret
  5207.  
  5208. NotCMP:    push    di
  5209.     mov    ah,al
  5210.     and    ah,11110000b
  5211.     cmp    ah,01010000b
  5212.     jnz    NotPushOrPop
  5213. ;are next 4 chars also PUSH or also POP ?
  5214.     mov    ah,al
  5215.     and    ah,11111000b    ;mask for all PUSH and POP instr's
  5216.     mov    di,4
  5217. PPloop:    push    ax
  5218.     mov    al,es:[bx+di]
  5219.     and    al,11111000b
  5220.     cmp    ah,al
  5221.     pop    ax
  5222.     jnz    NotPushOrPop
  5223.     dec    di
  5224.     jnz    PPloop
  5225.     stc
  5226.     pop    di
  5227.     ret
  5228.  
  5229. NotPushOrPop:
  5230.     cmp    al,7Fh        ;thru 7Eh is ASCII
  5231.     cmc
  5232.     pop    di
  5233.     ret
  5234. ;--------------------------------
  5235.  
  5236. curorg    dw    0        ;ORG address
  5237. curpar    dw    0        ;para (segment) of target pgm loaded
  5238. segsiz    dw    0        ;bytes in current segment (not used now)
  5239. DumpStart dw    0        ;dump start addr
  5240. DumpEnd    dw    0100h        ;dump end addr
  5241. symtbl    dw    symbas        ;addr of symbol table start
  5242. symtp    dw    symbas        ;addr of symbol table end+1 (ie, 1st free byte)
  5243. pcntr    dw    0        ;true program counter for Unassemble, etc.
  5244. lastwd    dw    0100h        ;end addr for U, input by user
  5245. curadr    dw    0        ;pgm pointer during disassy
  5246. ctltbl    dw    offset ctlbas    ;control (BEHIS or W) table start addr
  5247. ctltop    dw    0        ;   and end addr
  5248. SearchPointer dw    0
  5249. fndadd    dw    0
  5250. dmpcnt    dw    0FFh
  5251. lblbuf    db    'H0XXXX'    ;used to build up label in Build Symbol Table
  5252. PgmParas dw    0        ;size of loaded pgm in paras
  5253. PgmBytes dw    0,0        ;doubleword, lo-hi
  5254. ParasRead dw    0        ;for loading files > 64K, points buffer para
  5255.  
  5256. ;This table erased by erstbl in LoadPGM (load .COM file)
  5257. cstbl    db    '  '
  5258.     dw    0,0,0,0
  5259. cofset    dw    0        ;default
  5260.     db    '  '
  5261.     dw    0,0,0,0
  5262.     dw    0        ;default
  5263.     db    '  '
  5264.     dw    0,0,0,0
  5265.     dw    0        ;default
  5266.     db    '  '
  5267.     dw    0,0,0,0
  5268.     dw    0        ;default
  5269.     db    '  '
  5270.     dw    0,0,0,0
  5271.     dw    0
  5272.     db    '  '
  5273.     dw    0,0,0,0
  5274.     dw    0
  5275.     db    '  '
  5276.     dw    0,0,0,0
  5277.     dw    0
  5278.     db    '  '
  5279.     dw    0,0,0,0
  5280.     dw    0
  5281.     db    0        ;table end flag
  5282. ;end of table erased by erstbl
  5283.  
  5284. segnam    dw    5343h        ; 'SC' for CS, etc
  5285.     dw    5344h        ; 'SD'
  5286.     dw    5345h        ; 'SE'
  5287.     dw    5353h        ; 'SS'
  5288.     dw    5831h        ; 'X1'
  5289.     dw    5832h        ; 'X2'
  5290.     dw    5833h        ; 'X3'
  5291.     dw    5834h        ; 'X4'
  5292.  
  5293. FileString    db    'D:'
  5294.         db    81 dup(0)
  5295. DotPtr        dw    0        ;pointer to the . before the EXT
  5296. Handle        dw    0        ;File Handle for load & save routines
  5297. LitRSM        db    'RSM',0        ;literals for file types
  5298. LitCOM        db    'COM',0
  5299. LitEXE        db    'EXE',0
  5300. LitSYS        db    'SYS',0
  5301. LitCTL        db    'CTL',0
  5302. LitSMB        db    'SMB',0
  5303. LitREM        db    'REM',0
  5304. LitALL        db    'ALL',0
  5305. SEG_string    db    'SEG_',cr    ;for name of saved files doing RAM
  5306.  
  5307. EXTflag    db    0            ;.EXT of loaded file, C=.COM, E=.EXE
  5308. hlpflg    db    0
  5309. helptr    dw    offset help
  5310.     dw    offset extnd_help
  5311.     dw    offset instrs
  5312. helpno    db    0    ;which help screen to display
  5313. NxLblPtr dw    0    ;stores BX in Dump Symbol table
  5314. AppendPtr dw    0    ;temp pointer to Appended remark while Unasm'ing line
  5315. Control    db    0    ;temp CTL char to insert when Attempting to find DB's
  5316. nxtctl    dw    0    ;addr of next CTL change, to end Byte & Hex lines
  5317. NxtSymAddr dw    0    ;when not at end of table, addr of next label and
  5318. NxtSymPtr dw    0    ; pointer to 1st byte of next entry in SYM table
  5319. EndSameAddr dw    0    ;in S mode, next non-Same or CTL or SMB addr
  5320. DTAptr    dw    0        ;pointer in buffer for disk read/writes
  5321. segsho    db    205,205,16    ;command prompt string '══'
  5322. UpCaseFlag db    1        ;zero permits lower-case for remarks & labels
  5323. nrsegs    db    0    ;number of segments loaded
  5324. trmflg    db    0    ;trim flag, 1= don't show ;addrs for labels
  5325. SegOvrdPfx db    0    ;segment override prefix
  5326.  
  5327. segflg    db    0    ;segment req in current command (not now used)
  5328.  
  5329. OprndType db    0    ;upper nibble = seg type, S D E C = 0 1 2 3,
  5330.             ;  lower = Undefined, Byte, Word, Dword(Qword, Spaces)
  5331. RelFlag    db    0    ;line addr or rel disp instr, don't correct for CurOrg
  5332. Direc286Flag db    0    ;1 = put '.386P' in .RSM, '186+ instrs in file
  5333. LnsPerScreen db    22    ;lines per screen of Unassembly
  5334. LinesToGo db    10    ;lines left to Unassemble on this screen
  5335. LCountFlag db    1    ;0 for U B or A,EEEE to end addr, not line count
  5336. wfiflg    db    0    ;0 means don't print to file, just screen
  5337. ASMopenFlag db    0    ;.RSM file still open, close it before writes
  5338. REMflag    db    0    ;1 => doing REM, not SMB file operation
  5339. CurInstr db    0    ;current op code during unassembly
  5340. CurModRegRM db    0    ;current Extended Address byte of instr
  5341. LongFlag db    0    ;current instr is a long '286
  5342. strcnt    db    0    ;no of chars on ASCII Byte or Hex lines
  5343. EntriesLeft db    0    ;count of displayed labels in DS and Ctl list
  5344. BytesFlag db    0    ;flag line is Bytes ASCII, not Hex
  5345. ChgFlag    db    0    ;flag change made for 'Update/Exit' in CmExit
  5346. OutsideFlag db    0    ;in .RSM hdr, flag 'Labels Outside Pgm' printed
  5347. CrLfFlag db    0    ;in ASCII strings, last byte was cr, lf, or 0
  5348. ColonFlag db    0    ;flag for colon after labels
  5349. NoCommentAddr db 0    ;flag no ;0123 after label in oprnd
  5350. AmodeFlag db    0    ; 1 => Attempt find DB's mode
  5351. BmodeFlag db    0    ; 1 => Build symbol table mode
  5352. typndx    db    0,0,0
  5353. cmdbuf:    org    offset $+336
  5354. stak    dw    0    ;machine stack top
  5355. remtbl    dw    0    ;loaded w/remark table start addr
  5356. remend    dw    0    ;  and end addr
  5357. cfence    db    0    ;this is ctlbas-1, holds BEHISW for 1st line
  5358. ctlbas    db    0    ;start of enough room for 768 items, 4 bytes each
  5359.  
  5360. start    endp
  5361. cseg    ends
  5362.     end    start
  5363.