home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PROGRAMS / UTILS / MOUSE / GPIBLPT.ZIP / LPPLOT.ASM < prev    next >
Encoding:
Assembly Source File  |  1990-10-18  |  6.9 KB  |  351 lines

  1.     page    ,132
  2.     title    LpPlot - Disguise Plotter as LPT3
  3.  
  4. ;*    Terminate-and-stay-resident program to drive an HP plotter
  5. ;    with a GPIB interface as LPT3.
  6. ;
  7. ;    Copyright 1990, Sydex.    All Rights Reserved.
  8. ;
  9. ;    Consult the accompanying documentation for specific licensing
  10. ;    rights and descriptive information.
  11. ;
  12.  
  13.     .model     small,c
  14.  
  15. ;    The following needs to be changed if your printer card differs.
  16.  
  17. Base_Port    equ    0278h    ; where our GPIB printer card located.
  18.  
  19. ;    GPIB talker-listener addresses.
  20.  
  21. Plotter equ    5        ; plotter address
  22. Us    equ    15        ; our address
  23.  
  24. ;    Interrupts.
  25.  
  26. dosint    equ    21h        ; DOS interrupt
  27. lpint    equ    17h        ; BIOS lp server interrupt
  28.  
  29. ;    Characters.
  30.  
  31. cr    equ    13        ; ascii return
  32. lf    equ    10        ; ascii linefeed
  33.  
  34.     .data
  35.  
  36.     extrn    Last_Memory:word    ; highest memory location used
  37.     extrn    Stack_Buf:word        ; where we put the stack
  38.  
  39. AlreadyInMess    db    cr,lf,'LPT3 GPIB driver already present',cr,lf,'$'
  40.  
  41. Plot_Init    db    0        ; Plotter initialized
  42.  
  43. High_Para    dw    0        ; for DOS function 31 - highest memory
  44.  
  45.     .code
  46.  
  47. ;*    The following calls are available to us:
  48. ;
  49. ;    int GPIB_Init( int io_port, int our_address)
  50. ;    int GPIB_Send( int listen, char what)
  51. ;    int GPIB_PutStr( int listen, char *string, int count)
  52. ;    int GPIB_Stat(void);
  53. ;    int GPIB_Get( int listen)
  54. ;    int GPIB_GetStr( int listen, char *buf)
  55. ;    int GPIB_SerPoll( int listen)
  56. ;    int GPIB_PutAdd( char what)
  57. ;    int GPIB_PutData( char what)
  58. ;    int GPIB_GetData();
  59.  
  60. ;    The following calls are used:
  61.  
  62.     extrn    GPIB_Init:near
  63.     extrn    GPIB_PutAdd:near
  64.     extrn    GPIB_PutData:near
  65.     extrn    GPIB_Stat:near
  66.  
  67. ;*    The following doubleword hold the address of the original
  68. ;    BIOS print servicer.  We keep this in the code segment for
  69. ;    simplicity.
  70. ;
  71.  
  72. PrtVector    label    dword
  73. PrtOff        dw    (?)        ; offset to native driver
  74. PrtSeg        dw    (?)        ; segment to native driver
  75.  
  76. ;*    Main routine.
  77. ;
  78. ;
  79.  
  80. Start    proc    near
  81.  
  82. ;    Before we clobber DS, figure out how many paragraphs of memory
  83. ;    this thing will take for the TSR call later.
  84.  
  85.     mov    dx,seg @Data
  86.     mov    ax,ds            ; PSP area
  87.     sub    dx,ax            ; figure segment difference
  88.     lea    ax,@Data:Last_Memory
  89.     add    ax,15            ; round up highest data offset
  90.     shr    ax,1
  91.     shr    ax,1
  92.     shr    ax,1
  93.     shr    ax,1
  94.     add    dx,ax            ; total paragraphs needed
  95.  
  96. ;    Set up segments.
  97.  
  98.     mov    ax,seg @Data        ; data segment
  99.     mov    es,ax
  100.     mov    ds,ax
  101.     mov    ss,ax
  102.     lea    sp,@Data:Stack_Buf    ; set stack up
  103.     mov    bp,sp
  104.     mov    High_Para,dx        ; save high paragraphs
  105.  
  106. ;    Next, see if we're already in--issue function call F1 to the
  107. ;    BIOS printer interface.     If we're already in, we'll get AL = FF.
  108.  
  109. Start2:
  110.     mov    ax,0F100h
  111.     mov    dx,2        ; lpt2
  112.     int    lpint        ; see if already in
  113.     cmp    al,0ffh        ; says we're in
  114.     jne    Start4
  115.  
  116.     lea    dx,@Data:AlreadyInMess
  117.     mov    ah,9
  118.     int    dosint        ; issue error message
  119.     mov    ax,4c01h    ; terminate with error
  120.     int    dosint
  121.  
  122. ;    Initialize the parallel interface.
  123.  
  124. Start4:
  125.     mov    ax,Us
  126.     push    ax
  127.     mov    ax,Base_Port
  128.     push    ax
  129.     call    GPIB_Init    ; initialize
  130.     mov    sp,bp        ; clear stack
  131.  
  132.     mov    Plot_Init,0     ; say not initialized
  133.  
  134. ;    Now "hook" interrupt 17h.
  135.  
  136.     push    es
  137.     mov    ax,3500h+lpint
  138.     int    dosint            ; get vector
  139.     mov    PrtSeg,es
  140.     mov    PrtOff,bx        ; set segment/offset
  141.     pop    es
  142.     push    ds
  143.     mov    ax,cs
  144.     mov    ds,ax
  145.     lea    dx,ServLpt        ; new entry
  146.     mov    ax,2500h+lpint
  147.     int    dosint            ; set vector
  148.     pop    ds
  149.     mov    dx,High_Para        ; total paragraphs
  150.     mov    ax,3100h        ; Advanced TSR
  151.     int    dosint            ; do it
  152.  
  153. Start    endp
  154.  
  155.     subttl    LPT3 Servicer Code.
  156.     page
  157.  
  158. ;*    Servicer Code for LPT3.
  159. ;
  160. ;    This is entered when a call is made to the BIOS to output
  161. ;    a character to LPT3.
  162. ;
  163.  
  164. ServLpt proc    near
  165.     sti
  166.     cmp    dl,2
  167.     je    ServLpt4        ; if LPT3
  168. ServLpt2:
  169.     jmp    PrtVector        ; go handle non-LPT3 with original
  170.  
  171. ;    Got LPT3, now figure what's going on...First off, set up our
  172. ;    working segments and a stack.
  173.  
  174. ServLpt4:
  175.     push    ds
  176.     push    es
  177.     push    ax
  178.     mov    ax,seg @Data
  179.     mov    ds,ax
  180.     mov    es,ax
  181.     pop    ax
  182.     mov    Stack_Buf,ss
  183.     mov    Stack_Buf-2,sp
  184.     push    ds
  185.     cli
  186.     pop    ss
  187.     lea    sp,@Data:Stack_Buf-4    ; set the stack up
  188.     sti
  189.     cmp    ah,0
  190.     jne    ServLpt6        ; if not write
  191.     call    WriteLpt        ; write
  192.     jmp    short ServLpt20        ; exit...
  193.  
  194. ServLpt6:
  195.     cmp    ah,1
  196.     jne    ServLpt8        ; if not initialize
  197.     call    InitLpt            ; if initialize
  198.     jmp    short ServLpt20        ; exit...
  199.  
  200. ServLpt8:
  201.     cmp    ah,2
  202.     jne    ServLpt10        ; if not status
  203.     call    InitLpt            ; status--same as init
  204.     jmp    short ServLpt20
  205.  
  206. ServLpt10:
  207.     cmp    ah,0f1h
  208.     stc                ; signal error
  209.     jne    ServLpt12        ; if not test of who's in
  210.     mov    al,255            ; say we are
  211.     jmp    short ServLpt20        ; exit...
  212.  
  213. ServLpt12:
  214.     mov    ah,1
  215.     stc
  216.     jmp    short ServLpt20        ; exit with error
  217.  
  218.  
  219. ;    Restore segments, exit, preserving flags.
  220.  
  221. ServLpt20:
  222.     cli
  223.     mov    ss,Stack_Buf
  224.     mov    sp,Stack_Buf-2
  225.     sti
  226.     pop    es
  227.     pop    ds
  228.     retf    2
  229. ServLpt endp
  230.  
  231.  
  232. ;*    Write to printer - Make sure plotter is initialized...
  233. ;
  234. ;
  235.  
  236. WriteLpt    proc    near
  237.     test    Plot_Init,-1
  238.     jnz    WriteLpt2        ; if initialized already
  239.     call    SendAddress
  240.     jc    WriteLpt4        ; if error, skip
  241. WriteLpt2:
  242.     push    ax            ; the data byte
  243.     call    GPIB_PutData        ; write it
  244.     add    sp,2            ; unstack
  245.     cmp    ax,-1
  246.     je    WriteLpt4        ; if error
  247.     call    GetStatus
  248.     ret                ; exit with status
  249.  
  250. ;    Error -- set for re-initialize.
  251.  
  252. WriteLpt4:
  253.     mov    Plot_Init,0        ; say not initialized
  254.     push    ax            ; save data
  255.     mov    ax,Us
  256.     push    ax
  257.     mov    ax,Base_Port
  258.     push    ax
  259.     call    GPIB_Init        ; re-initialize
  260.     add    sp,4            ; unstack
  261.     pop    ax            ; restore data
  262.     mov    ah,11010001b        ; say timeout
  263.     stc
  264.     ret            ; exit...
  265. WriteLpt    endp
  266.  
  267. ;*    InitLpt - Initialize/Status Plotter.
  268. ;
  269. ;    We initialize only the first time in.
  270. ;
  271.  
  272. InitLpt proc    near
  273.     test    Plot_Init,-1
  274.     jnz    InitLpt2    ; if initialized already
  275.     call    SendAddress
  276.     jc    InitLpt4       ; if error
  277. InitLpt2:
  278.     call    GetStatus    ; get printer status
  279.     ret            ; return with flags
  280.  
  281. ;    Error return.
  282.  
  283. InitLpt4:
  284.     mov    Plot_Init,0        ; say not initialized
  285.     mov    ax,Us
  286.     push    ax
  287.     mov    ax,Base_Port
  288.     push    ax
  289.     call    GPIB_Init        ; re-initialize
  290.     add    sp,4            ; unstack
  291.     mov    ah,11010001b        ; say timeout
  292.     stc
  293.     ret            ; exit...
  294. InitLpt endp
  295.  
  296.  
  297. ;*    SendAddress - Send talk/listen addresses to interface.
  298. ;
  299. ;    Pretty much straightforward.    We do preserve (ax), however.
  300. ;
  301.  
  302. SendAddress    proc    near    ; send address out to plotter
  303.     push    ax
  304.     mov    ax,'?'
  305.     push    ax
  306.     call    GPIB_PutAdd    ; send an unlisten
  307.     add    sp,2        ; clean off stack
  308.     cmp    ax,-1
  309.     je    SendAddress2    ; if error
  310.  
  311.     mov    ax,Us+40h    ; talker is us
  312.     push    ax
  313.     call    GPIB_PutAdd    ; send talker address
  314.     add    sp,2        ; unstack
  315.     cmp    ax,-1
  316.     je    SendAddress2    ; if error
  317.  
  318.     mov    ax,Plotter+20h
  319.     push    ax
  320.     call    GPIB_PutAdd    ; send listener address
  321.     add    sp,2        ; unstack
  322.     cmp    ax,-1
  323.     je    SendAddress2    ; if error
  324.     mov    Plot_Init,-1    ; say we did it
  325.     stc
  326. SendAddress2:            ; error exit...
  327.     cmc            ; set carry if error
  328.     pop    ax
  329.     ret
  330. SendAddress    endp
  331.  
  332. ;*    GetStatus -- Simulate printer status from GPIB status.
  333. ;
  334. ;    A fake--only returns ready/not ready.
  335. ;
  336.  
  337. GetStatus    proc    near    ; read status
  338.     call    GPIB_Stat
  339.     mov    ah,11010000b    ; normal status
  340.     test    al,100b        ; see if NRFD set
  341.     jz    GetStatus2    ; if not...
  342.     and    ah,7fh        ; say not ready
  343.     stc
  344. GetStatus2:
  345.     ret            ; exit...
  346. GetStatus    endp
  347.  
  348. EndMem    label    byte
  349.  
  350.     end    Start
  351.