home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol165 / lohd.asm < prev    next >
Encoding:
Assembly Source File  |  1984-07-09  |  10.3 KB  |  549 lines

  1.  
  2.  
  3. ;    ------------------------------------------------------------
  4. ;    LOHD.ASM is a revision of Digital Research's LOAD.COM, which
  5. ;    is evidently a PL/M program. The revision has reduced its
  6. ;    volume by 2/3, but its execution is disk-bound to the point
  7. ;    that the speed difference is not outwardly apparent. Other
  8. ;    changes include:
  9. ;        1. An origin below 0100H - CP/M's transient origin - no
  10. ;      longer produces an error condition if it is 0000H. Thus a
  11. ;      file assembled to origin 0000 can be passed from .HEX to
  12. ;      .COM, such as if it were the code for a self-relocating
  13. ;      program such as DDT.
  14. ;        2. The .COM buffer is zeroed before each use, so that
  15. ;      gaps in the code sequence, the result of a <ds> or of an
  16. ;      <org>, are filled with zeroes rather than being left to
  17. ;      gather whatever trash is in the buffer as they are found.
  18. ;      The .COM code is passed through a one-page window, so that
  19. ;      any origin redefined below that range will draw an error
  20. ;      message, as in LOAD.COM.
  21. ;
  22. ;    [Harold V. McIntosh, 22 September 1983]
  23. ;    ------------------------------------------------------------
  24.  
  25.  
  26. BDOS    equ    0005H
  27. TFCB    equ    005CH
  28. TSIZ    equ    0080H
  29. TORG    equ    0100H
  30. CSIZ    equ    0100H    ;size of .COM buffer
  31. HSIZ    equ    0400H    ;size of hexfile buffer
  32.  
  33. LF    equ    0AH
  34. CR    equ    0DH
  35.  
  36. ;    -------------
  37.     org    0100H
  38. ;    -------------
  39.  
  40. begn:    lxi    h,0000
  41.     dad    sp
  42.     shld    stak    ;save sp
  43.     lxi    sp,stak    ;stackend
  44.     lxi    h,CSIZ
  45.     shld    cinx    ;.COM index
  46.     call    cbuz    ;clear CBUF
  47.     lxi    h,HSIZ
  48.     shld    hinx    ;hexfile index
  49.     lda    TFCB+1
  50.     cpi    ' '
  51.     jnz    nnul
  52.     lxi    d,logo
  53.     call    mssg
  54.     lxi    d,tuto
  55.     call    mssg
  56.     jmp    gbye    ;normal exit
  57.  
  58. nnul:    mvi    c,021H    ;count
  59.     lxi    d,TFCB    ;source
  60.     lxi    h,HFCB    ;.HEX FCB = destination
  61.     call    miuc
  62.  
  63.     mvi    c,4    ;count
  64.     lxi    d,X01F7    ;'hex' = source
  65.     lxi    h,HFCB+9;.HEX ext = destination
  66.     call    miuc
  67.  
  68.     lxi    d,HFCB    ;.HEX FCB
  69.     mvi    c,15    ;(0F) open file
  70.     call    BDOS
  71.     cpi    0FFH
  72.     lxi    d,X01FB    ;'can''t open source'
  73.     jz    tema    ;type err mess w/addr
  74.  
  75.     mvi    c,3    ;count
  76.     lxi    d,X020E    ;'COM' = source
  77.     lxi    h,TFCB+9;destination
  78.     call    miuc
  79.  
  80.     lxi    d,TFCB
  81.     mvi    c,19    ;(13) delete file
  82.     call    BDOS
  83.  
  84.     lxi    d,TFCB
  85.     mvi    c,22    ;(16) create file
  86.     call    BDOS
  87.  
  88.     lxi    d,TFCB
  89.     mvi    c,15    ;(0F) open file
  90.     call    BDOS
  91.     cpi    0FFH
  92.     lxi    d,X0211    ;'no more directory'
  93.     jz    tema    ;type err mess w/addr
  94.  
  95.     call    hefi    ;process the .HEX file
  96.  
  97.     lxi    d,TFCB
  98.     mvi    c,16    ;(10) close file
  99.     call    BDOS
  100.     cpi    0FFH
  101.     lxi    d,X0229    ;'can''t close file'
  102.     jz    tema    ;type err mess w/addr
  103.  
  104. fini:    call    crlf    ;CR,LF
  105. gbye:    lhld    stak    ;save sp
  106.     sphl
  107.     ret
  108.  
  109. ;    Type CR, LF.
  110.  
  111. crlf:    mvi    a,CR
  112.     call    cona    ;console from A
  113.     mvi    a,LF
  114.     jmp    cona    ;console from A
  115.  
  116. word:    mov    a,h
  117.     call    byte    ;type A as two nibbles
  118.     mov    a,l
  119. byte:    push    psw
  120.     rar
  121.     rar
  122.     rar
  123.     rar
  124.     call    nibl    ;type A as hex
  125.     pop    psw
  126. nibl:    ani    0FH
  127.     adi    90H
  128.     daa
  129.     aci    40H
  130.     daa
  131. cona:    push    h
  132.     push    d
  133.     mov    e,a
  134.     mvi    c,2    ;(02) write console
  135.     call    BDOS
  136.     pop    d
  137.     pop    h
  138.     ret
  139.  
  140. ;    Type message at (DE).
  141.  
  142. mssg:    call    crlf    ;CR,LF
  143. mess:    mvi    c,9    ;(09) type buffer
  144.     jmp    BDOS
  145.  
  146. ;    Type error message with address.
  147.  
  148. tema:    push    d
  149.     lxi    d,X0129    ;'error'
  150.     call    mssg    ;type CRLF, mssg
  151.     pop    d
  152.     call    mess    ;type mess at (DE)
  153.     lxi    d,X0131    ;'load address'
  154.     call    mess    ;type mess at (DE)
  155.     lhld    cinx    ;.COM index
  156.     call    word    ;type HL in four nibbles
  157.     jmp    gbye    ;normal exit
  158.  
  159. ;    Block move.
  160.  
  161. miuc:    ldax    d
  162.     mov    m,a
  163.     inx    h
  164.     inx    d
  165.     dcr    c
  166.     jnz    miuc
  167.     ret
  168.  
  169. ;    Get next hexfile element.
  170.  
  171. nxhx:    lhld    hinx    ;hexfile index
  172.     inx    h
  173.     lxi    d,HSIZ
  174.     mov    a,l
  175.     sub    e
  176.     mov    a,h
  177.     sbb    d
  178.     jc    nxhv    ;byte available
  179.     lxi    h,0000
  180. nxhy:    shld    hinx    ;hexfile index
  181.     lxi    d,HSIZ
  182.     mov    a,l
  183.     sub    e
  184.     mov    a,h
  185.     sbb    d
  186.     jnc    nxhu    ;reset hexfile, read 1st element
  187.     lxi    d,HBUF
  188.     dad    d
  189.     xchg
  190.     mvi    c,26    ;(1A) set DMA address
  191.     call    BDOS
  192.     lxi    d,HFCB    ;.HEX FCB
  193.     mvi    c,20    ;(14) read one record
  194.     call    BDOS
  195.     cpi    000H
  196.     jz    nxhz    ;add record to hexfile
  197.     cpi    001H
  198.     lxi    d,X0141    ;'disk read'
  199.     jnz    tema    ;type err mess w/addr
  200.     lhld    hinx    ;hexfile index
  201.     lxi    d,HBUF    ;hexfile buffer
  202.     dad    d
  203.     mvi    m,01AH    ;^Z
  204.     lxi    h,HSIZ-1
  205.     shld    hinx    ;hexfile index
  206. nxhz:    lhld    hinx    ;hexfile index
  207.     lxi    d,TSIZ
  208.     dad    d
  209.     jmp    nxhy    ;no more refills
  210.  
  211. nxhu:    lxi    h,0000
  212. nxhv:    shld    hinx    ;hexfile index
  213.     lxi    d,HBUF    ;hexfile buffer
  214.     dad    d
  215.     mov    a,m
  216.     ret
  217.  
  218. ;    Start reading the .HEX file, and keep going.
  219.  
  220. hefi:    lxi    h,0FFFFH
  221.     shld    mina    ;minimum address
  222.     lxi    h,0000
  223.     shld    maxa    ;maximum address
  224.     shld    byco    ;byte counter
  225.     xra    a
  226.     sta    reco    ;record counter
  227.     lxi    h,TORG
  228.     shld    ladr    ;load address
  229.     shld    rbrk    ;record breakpoint
  230.     shld    cinx    ;.COM index
  231.     lxi    h,HBUF    ;hexfile buffer
  232.     mvi    m,01AH    ;^Z
  233. inhx:    call    nxhx    ;next hexfile element
  234.     sui    ':'
  235.     jnz    inhx    ;advance to ":"
  236.     mov    d,a    ;checksum in D
  237.     call    hexb    ;assemble byte, augment checksum
  238.     mov    e,a    ;bytecount in E
  239.     cpi    00H
  240.     jnz    nlin    ;this isn't "end" line
  241.     lhld    cinx    ;.COM index
  242.     xchg
  243. elin:    lhld    rbrk    ;record breakpoint
  244.     mov    a,l    ;cmp(HL,DE)
  245.     sub    e
  246.     mov    a,h
  247.     sbb    d
  248.     jnc    stat    ;type statistics
  249.     xra    a
  250.     call    comb    ;insert byte in .COM buffer
  251.     jmp    elin    ;fill out buffer with zeroes
  252.  
  253. nlin:    lhld    byco    ;byte counter
  254.     push    d
  255.     mvi    d,00
  256.     dad    d
  257.     pop    d
  258.     shld    byco    ;byte counter
  259.     call    hexb    ;assemble byte, augment checksum
  260.     push    psw
  261.     call    hexb    ;assemble byte, augment checksum
  262.     pop    h
  263.     mov    l,a
  264.     ora    h
  265.     jnz    horg    ;high (non-zero) origin
  266.     shld    rbrk    ;record breakpoint
  267. horg:    shld    ladr    ;load address
  268.     shld    cinx    ;.COM index
  269.     lhld    mina    ;minimum address
  270.     inx    h
  271.     mov    a,h
  272.     ora    l
  273.     jnz    nmin
  274.     lhld    cinx    ;.COM index
  275.     shld    mina    ;minimum address
  276. nmin:    call    hexb    ;assemble byte, augment checksum
  277. ihli:    call    hexb    ;assemble byte, augment checksum
  278.     call    comb    ;insert byte in .COM buffer
  279.     dcr    e
  280.     jnz    ihli
  281.     push    d
  282.     lhld    maxa    ;maximum address
  283.     xchg
  284.     lhld    cinx    ;.COM index
  285.     mov    a,e
  286.     sub    l
  287.     mov    a,d
  288.     sbb    h
  289.     jnc    nmax
  290.     dcx    h
  291.     shld    maxa    ;maximum address
  292. nmax:    pop    d
  293.     call    hexb    ;assemble byte, augment checksum
  294.     mov    a,d
  295.     cpi    00H
  296.     jz    inhx    ;on to next line
  297.     lxi    d,X01A8    ;'check sum error'
  298.     call    mssg    ;type CRLF, mssg
  299.     jmp    erst    ;type error statistics
  300.  
  301. ;    Type summary of statistics.
  302.  
  303. stat:    lxi    d,X01B9    ;'first address'
  304.     call    mssg    ;type CRLF, mssg
  305.     lhld    mina    ;minimum address
  306.     call    word    ;type HL in four nibbles
  307.     lxi    d,X01C8    ;'last address'
  308.     call    mssg    ;type CRLF, mssg
  309.     lhld    maxa    ;maximum address
  310.     call    word    ;type HL in four nibbles
  311.     lxi    d,X01D7    ;'bytes read'
  312.     call    mssg    ;type CRLF, mssg
  313.     lhld    byco    ;byte counter
  314.     call    word    ;type HL in four nibbles
  315.     lxi    d,X01E6    ;'records written'
  316.     call    mssg    ;type CRLF, mssg
  317.     lda    reco    ;record counter
  318.     call    byte    ;type A as two nibbles
  319.     jmp    crlf    ;CR,LF
  320.  
  321. ;    Insert byte in .COM buffer.
  322.  
  323. comb:    push    d
  324.     push    psw
  325.     lhld    rbrk    ;record breakpoint
  326.     xchg
  327.     lhld    cinx    ;.COM index
  328.     mov    a,l    ;cmp(HL,DE)
  329.     sub    e
  330.     mov    a,h
  331.     sbb    d
  332.     lxi    d,X014B    ;'inverted load address'
  333.     jc    tema    ;type err mess w/addr
  334.     lxi    d,CSIZ    ;nc means 'rbrk .le. index'
  335.     lhld    rbrk    ;record breakpoint
  336.     dad    d
  337.     xchg
  338.     lhld    cinx    ;.COM index
  339.     mov    a,l    ;cmp(HL,DE)
  340.     sub    e
  341.     mov    a,h
  342.     sbb    d
  343.     cnc    budi    ;send CBUF to disk
  344.     lxi    d,CBUF    ;.COM buffer
  345.     mvi    h,00
  346.     dad    d
  347.     pop    psw
  348.     mov    m,a
  349.     lhld    cinx    ;.COM index
  350.     inx    h
  351.     shld    cinx    ;.COM index
  352.     pop    d
  353.     ret
  354.  
  355. ;    Send CBUF to disk.
  356.  
  357. budi:    push    h
  358.     call    budj
  359.     pop    h
  360.     ret
  361.  
  362. budj:    mvi    c,26    ;(1A) set DMA address
  363.     lxi    d,CBUF
  364.     call    BDOS
  365.  
  366.     call    budk    ;record to disk
  367.  
  368.     lxi    d,CBUF+TSIZ
  369.     mvi    c,26    ;(1A) set DMA address
  370.     call    BDOS
  371.  
  372.     call    budk    ;record to disk
  373.  
  374. ;    Fill CBUF with zeroes.
  375.  
  376. cbuz:    xra    a
  377.     mvi    b,2    ;CBUF holds 2 records
  378.     lxi    h,CBUF
  379. cbuy:    mvi    c,TSIZ
  380. cbux:    mov    m,a
  381.     inx    h
  382.     dcr    c
  383.     jnz    cbux
  384.     dcr    b
  385.     jnz    cbuy
  386.     ret
  387.  
  388. budk:    lhld    rbrk    ;record breakpoint
  389.     lxi    d,TSIZ
  390.     dad    d
  391.     shld    rbrk    ;record breakpoint
  392.     lxi    h,reco    ;record counter
  393.     inr    m
  394.  
  395.     lxi    d,TFCB
  396.     mvi    c,21    ;(15) write one record
  397.     call    BDOS
  398.     cpi    00H
  399.     lxi    d,X0161    ;'disk write'
  400.     jnz    tema    ;type err mess w/addr
  401.     ret
  402.  
  403. ;    Type error statistics.
  404.  
  405. erst:    lxi    d,X016C    ;'load address'
  406.     call    mssg    ;type CRLF, mssg
  407.     lhld    ladr    ;load address
  408.     call    word    ;type HL in four nibbles
  409.     lxi    d,X017B    ;'error address'
  410.     call    mssg    ;type CRLF, mssg
  411.     lhld    cinx    ;.COM index
  412.     call    word    ;type HL in four nibbles
  413.     lxi    d,X018A    ;'bytes read'
  414.     call    mssg    ;type CRLF, mssg
  415.     call    tyla    ;type load address:
  416. ersu:    lhld    cinx    ;.COM index
  417.     xchg
  418.     lhld    ladr    ;load address
  419.     mov    a,l
  420.     sub    e
  421.     mov    a,h
  422.     sbb    d
  423.     jnc    fini    ;CR,LF,exit
  424.     lhld    ladr    ;load address
  425.     mov    a,l
  426.     ani    00FH
  427.     cpi    000H
  428.     jnz    ersv
  429.     call    tyla    ;type load address:
  430. ersv:    lhld    rbrk    ;record breakpoint
  431.     xchg
  432.     lhld    ladr    ;load address
  433.     mov    a,l
  434.     sub    e
  435.     mov    l,a
  436.     mov    a,h
  437.     sbb    d
  438.     mov    h,a
  439.     lxi    b,CBUF    ;.COM buffer
  440.     dad    b
  441.     mov    a,m
  442.     call    byte    ;type A as two nibbles
  443.     lhld    ladr    ;load address
  444.     inx    h
  445.     shld    ladr    ;load address
  446.     mvi    a,' '
  447.     call    cona    ;console from A
  448.     jmp    ersu
  449.  
  450. ;    Type <load address>:.
  451.  
  452. tyla:    call    crlf    ;CR,LF
  453.     lhld    ladr    ;load address
  454.     call    word    ;type HL in four nibbles
  455.     mvi    a,':'
  456.     call    cona    ;console from A
  457.     mvi    a,' '
  458.     jmp    cona    ;console from A
  459.  
  460. ;    Make up general hexdigit.
  461.  
  462. hexn:    call    nxhx    ;next hexfile element
  463.     sui    '0'
  464.     cpi    10    ;ten
  465.     rc
  466.     sui    7    ;seven
  467.     cpi    10    ;ten
  468.     jc    nhex
  469.     cpi    16    ;sixteen
  470.     rc
  471. nhex:    lxi    d,X0196    ;'invalid hex digit'
  472.     call    mssg    ;type CRLF, mssg
  473.     jmp    erst    ;type error statistics
  474.  
  475. ;    Join hexinhx nibbles to form byte.
  476.  
  477. hexb:    push    b
  478.     push    h
  479.     push    d
  480.     call    hexn    ;general hexdigit
  481.     add    a
  482.     add    a
  483.     add    a
  484.     add    a
  485.     push    psw
  486.     call    hexn    ;general hexdigit
  487.     pop    b
  488.     ora    b
  489.     mov    b,a
  490.     pop    d
  491.     add    d
  492.     mov    d,a
  493.     mov    a,b
  494.     pop    h
  495.     pop    b
  496.     ret
  497.  
  498. logo:    db    '          LOHD/ICUAP',CR,LF
  499.     db    'Universidad Autonoma de Puebla',CR,LF
  500.     db    '      September 22, 1983',CR,LF,'$'
  501.  
  502. tuto:    db    'LOHD.ASM is a variant of Digital Research''s LOAD.COM',CR,LF
  503.     db    'which was reduced to 2/3 its original volume by using',CR,LF
  504.     db    'machine language rather than PL/M. It accepts 0000H as',CR,LF
  505.     db    'an origin lower than 0100H, facilitating the generation',CR,LF
  506.     db    'of the master file for a self-relocating program. Gaps',CR,LF
  507.     db    'caused by <ds> or <org> are filled with zeroes rather',CR,LF
  508.     db    'than trash from the memory.',CR,LF
  509.     db    CR,LF
  510.     db    '    LOHD [X:]FILE[.QQQ]',CR,LF
  511.     db    CR,LF
  512.     db    'will read [X:]FILE.HEX to produce [X:]FILE.COM.',CR,LF
  513.     db    '$'
  514. X0129:    db    'error: $'
  515. X0131:    db    ', load address $'
  516. X0141:    db    'Disk read$'
  517. X014B:    db    'Load address cannot be accomodated'
  518. X0161:    db    'Disk write$'
  519. X016C:    db    'Load  address $'
  520. X017B:    db    'Error address $'
  521. X018A:    db    'Bytes read:$'
  522. X0196:    db    'Invalid hex digit$'
  523. X01A8:    db    'Check sum error $'
  524. X01B9:    db    'First address $'
  525. X01C8:    db    'Last  address $'
  526. X01D7:    db    'Bytes read    $'
  527. X01E6:    db    'Records written $'
  528. X01F7:    db    'HEX',00
  529. X01FB:    db    'Can''t open source$'
  530. X020E:    db    'COM'
  531. X0211:    db    'Disk or Directory full$'
  532. X0229:    db    'Cannot close file$'
  533.  
  534. HFCB:    ds    21H    ;.HEX FCB
  535. HBUF:    ds    HSIZ+1    ;hexfile buffer (400H)
  536. hinx:    ds    2    ;hexfile index
  537. cinx:    ds    2    ;.COM index
  538. ladr:    ds    2    ;load address
  539. mina:    ds    2    ;minimum address
  540. maxa:    ds    2    ;maximum address
  541. byco:    ds    2    ;byte counter
  542. CBUF:    ds    100H    ;.COM buffer
  543. reco:    ds    1    ;record counter
  544. rbrk:    ds    2    ;record breakpoint
  545.     ds    20H
  546. stak:    ds    2    ;stackend
  547.  
  548.     end
  549.