home *** CD-ROM | disk | FTP | other *** search
/ Vectronix 2 / VECTRONIX2.iso / FILES_01 / HP_550C.LZH / DJ550DEP.S < prev    next >
Text File  |  1994-06-27  |  47KB  |  1,639 lines

  1. *************************************************************************
  2. *                                    *
  3. *                HP_DJ550.S                    *
  4. *            Modifié par Thierry Rodolfo        24/03/1994    *
  5. *************************************************************************
  6.  
  7. *************************************************************************
  8. *                                    *
  9. *    This module contains the HP PaintJet dependent portion of    *
  10. *    the assembler code for printer output.                *
  11. *                                    *
  12. *    This code has been brought up-to-date with the printer driver    *
  13. *    source received 5/31/85.                    *
  14. *    J. Shillington, Bell Northern Research                *
  15. *                                    *
  16. *    Modifications made by Theresa Estrada 4/10/91 Atari Corp.    *
  17. *                                    *
  18. *************************************************************************
  19.  
  20.     .text
  21.  
  22. *************************************************************************
  23. *                                    *
  24. *        Locally Defined Procedures and Variables        *
  25. *                                    *
  26. *************************************************************************
  27.     .globl    _set_vars    * Initial setup of printer driver vars
  28.     .globl    _getlstat
  29.     .globl    concat        * convert x-y coordinates to buffer offsets
  30.     .globl    _enter_gr    * enter graphics mode
  31.     .globl    _adv_form    * perform a form feed
  32.     .globl    _scan_out    * print contents of the rasterizing buffer
  33.     .globl    _exit_gr    * exit graphics mode
  34.     .globl    _alphaout    * print alphanumeric text
  35.  
  36.     .globl    _init_p        * initialize printer output routines
  37.      .globl    _dinit_p    * de-initialize printer output routines
  38.     .globl    printer_out    * output a string to printer
  39.     .globl    pout        * output a character to printer
  40.      .globl    _abort        * abort flag
  41.     .globl    _handle
  42.     .globl    _com_port
  43.     .globl    _sendbuff    * Send addr of buffer to app (STUB)    
  44.     .globl    _num_planes
  45.     .globl    _num_colors
  46.     .globl    _PAL_RGB
  47.     .globl    _MAP_COL
  48.     .globl    byte_out    * temporarily global for debugging only
  49.     .globl     lastplane
  50. *    .globl    _COLOR_TAB
  51.     .globl    PLANE_COLORS
  52.  
  53.     .page
  54. *************************************************************************
  55. *                                    *
  56. *            Externally Defined Labels            *
  57. *                                    *
  58. *************************************************************************
  59.  
  60.     .xref    _YS_MIN
  61.     .xref    _YS_MAX
  62.     .xref    _YW_MAX
  63.     .xref    graph_plane
  64.     .xref    slice_cnt
  65.     .xref    _vmu
  66.     .xref    _curalpha
  67.     .xref    _reqalpha
  68.     .xref    print_wires
  69.     .xref    slice_width
  70.     .xref    scan_line_offset
  71.     .xref    slice_offset
  72.     .xref    bytes_line
  73.     .xref    bytes_per_scan
  74.     .xref    _A_SLICE
  75.     .xref    _INTIN
  76.     .xref    _CONTRL
  77.     .xref    _PTSIN
  78.  
  79. *  Driver structure variables         TE 6/5/91
  80.  
  81.     .xref    NPLANES
  82.     .xref    PAGESIZE
  83.     .xref    XRES
  84.     .xref    YRES
  85.     .xref    PGSZ_TAB
  86.     .xref    _drvr_qulty
  87.  
  88.     .xref    _newbuff_ad        * TE 7/18/91
  89.  
  90.     .xref    _TOPMRGN    * TE 8/10/92
  91.     .xref    _LFTMRGN
  92.     .xref    _BOTMRGN
  93.     .xref    _RHTMRGN
  94.     .xref    TOPMRGN2    * TE 8/17/92
  95.     .xref    LFTMRGN2
  96.     .xref    BOTMRGN2
  97.     .xref    RHTMRGN2
  98.  
  99. ************************************************************************
  100. *
  101. *    Added 3/11/87 CS     Configurable variables    
  102. *
  103.  
  104.     .xref    xresmx
  105.     .xref    yresmx
  106.     .xref    xsize
  107.     .xref    ysize
  108.     .xref    num_planes
  109.     .xref    num_colors
  110. *
  111.     .xref    def_sl_cnt
  112.     .xref    def_sl_sz
  113.     .xref    def_plane_sz
  114. *
  115.     .xref    drast_sz
  116.     .xref    dlist_sz
  117.     .xref    min_free
  118.     .xref    max_list
  119.     .xref    max_rast
  120. *
  121.     .xref    _A_PAGE
  122.     .xref    _G_PAGE
  123.     .xref    _G_SLICE
  124. *    
  125.     .page
  126. *************************************************************************
  127. *                                    *
  128. *            Local Constants                    *
  129. *                                    *
  130. *************************************************************************
  131.  
  132. CR        .equ    $0D    * carriage return
  133. ESC        .equ    $1B    * escape character
  134. FORM_FEED    .equ    $0C    * form feed
  135. LF        .equ    $0A     * line feed
  136.  
  137. ALPHA_ESCAPE    .equ    $12    * alphanumeric attribute escape character
  138.  
  139. _set_vars:
  140.     move.l    #0,_newbuff_ad    * Ignore memory driver variable
  141.     move.l    _CONTRL,a0
  142.     tst.w    2(a0)
  143.     beq    use_defaults
  144.     move.l    _PTSIN,a0
  145.     move.w    (a0)+,xresmx    * Get x resolution
  146.     move.w    (a0)+,yresmx
  147.     bra    no_defs
  148. use_defaults:
  149.     move.w    PAGESIZE,d0    * index into PGSZ_TAB for first dpi available
  150.     cmp.w    #4,d0        * use user-defined xres & yres?
  151.     beq    set_xyres    * yes
  152. get_sz:
  153.     lea.l    PGSZ_TAB,a1    * table for pg. sz. values according to dpi
  154.     move.w    NPLANES,d1
  155.     cmp.w    #4,d1        * 4 planes?  (means use next dpi)
  156.     bne    first_dpi    * no
  157. next_dpi:
  158.     adda.l    #16,a1        * yes - advance to next set of dpi values 
  159. first_dpi:    
  160.     move.w    PAGESIZE,d0    * for offset into pgsz_tab
  161.     mulu.w    #4,d0        * 2xwords+2ywords=4xywords=2longs
  162.     adda.l    d0,a1        * advance correct offset into pgsz_tab
  163.     move.w    (a1)+,xresmx
  164.     move.w    (a1)+,yresmx
  165.     bra    no_defs
  166. set_xyres:
  167.     move.w    XRES,xresmx
  168.     move.w    YRES,yresmx
  169. no_defs:
  170.     lea    _DEV_TAB,a0    * Address of device table
  171.     move.w    xresmx,(a0)+    * and put in xresmx and yresmx
  172.     move.w    yresmx,(a0)+
  173.  
  174.     move.w    NPLANES,d0
  175.     cmp.w    #4,d0
  176.     blt    fewplanes
  177.     move.w    #85,xsize    * pixel size in microns for 4 planes 90dpi
  178.     move.w    #85,ysize
  179.     move.w    TOPMRGN2,d0
  180.     move.w    d0,_TOPMRGN
  181.     move.w    BOTMRGN2,d0
  182.     move.w    d0,_BOTMRGN
  183.     move.w    LFTMRGN2,d0
  184.     move.w    d0,_LFTMRGN
  185.     move.w    RHTMRGN2,d0
  186.     move.w    d0,_RHTMRGN
  187.     bra    store_pixsz
  188. fewplanes:            * pixel size in microns for 1-3 planes 180dpi
  189.     move.w    #85,xsize
  190.     move.w    #85,ysize    
  191. store_pixsz:
  192.     tst.w    (a0)+        * Get ready to set 
  193.     move.w    xsize,(a0)+    * Xsize and
  194.     move.w    ysize,(a0)    * Ysize
  195.     move.w    NPLANES,num_planes    * Number of planes
  196.     move.w    num_planes,_num_planes    * copy for C portion of code
  197.  
  198.     move.w    num_planes,d0    * index into COLOR_TAB
  199.     lea.l    PLANE_COLORS,a1    * table for # of colors according to # of planes
  200.     subq.w    #1,d0        * for dbra
  201. find_color:
  202.     move.w    (a1)+,num_colors
  203.     dbra    d0,find_color
  204.     move.w    num_colors,_num_colors    * copy for C portion of code
  205.     adda.l    #18,a0        * set ptr in DEV_TAB
  206.     move.w    num_colors,(a0)    * store color variable
  207.  
  208.     move.w    xresmx,d0    * bytes_line = (xresmx+7)/8
  209.     addq.w    #7,d0
  210.     ext.l    d0
  211.     divs    #8,d0
  212.     addq    #1,d0
  213.     and.w    #$FFFE,d0    * Assure even bytes
  214.     move.w    d0,bytes_line
  215. *
  216.     move.w    #1,print_wires    * 1 line per print pass
  217.     move.w    #1,slice_width    * # of lines per slice
  218. *
  219.     move.w    slice_width,d0    * slice_offset = slice_width*bytes_line
  220.     muls    bytes_line,d0
  221.     move.w    d0,slice_offset
  222. *
  223.     move.w    bytes_line,d0    * scan_line_offset = bytes_line
  224.     move.w    d0,scan_line_offset
  225. *
  226.     move.w    bytes_line,d0    * bytes_per_scan = slice_width*bytes_line
  227.     muls    slice_width,d0
  228.     move.w    d0,bytes_per_scan
  229. *
  230.     move.w    #2,def_sl_cnt    * default number of slices
  231. *
  232.     move.w    slice_width,d0     * def_sl_sz = def_sl_cnt*slice_width
  233.     muls    def_sl_cnt,d0
  234.     move.w    d0,def_sl_sz
  235. *
  236.     move.w    bytes_per_scan,d0 *def_plane_sz=def_sl_cnt*bytes_per_scan
  237.     muls    def_sl_cnt,d0
  238.     move.l    d0,def_plane_sz
  239. *
  240.     muls    num_planes,d0
  241.     move.l    d0,drast_sz    * FOUR PLANES FOR SIXTEEN COLORS - TE
  242. *
  243.     move.l    #$400,dlist_sz    * Internal display list buffer size
  244.     move.l    #$8000,min_free    * Minimum amount of free memory left
  245.     move.l    #$8000,max_list * Maximum display list buffer size
  246. *
  247.     move.w     yresmx,d0    * max_rast=(yresmx+1)*
  248.     addq.w    #1,d0
  249.     muls    num_planes,d0    * num_planes*bytes_line
  250.     muls    bytes_line,d0
  251.     move.l    d0,max_rast
  252. *
  253.     move.w    #63,_A_PAGE    * # of alpha text lines per page(10.5 in)
  254.     move.w    #24,_A_SLICE    * alpha text height in pixels
  255. *
  256.     move.w    yresmx,d0    * _G_PAGE = (yresmx+1)/slice_width
  257.     addq.w    #1,d0
  258.     ext.l    d0
  259.     divs    slice_width,d0
  260.     move.w    d0,_G_PAGE
  261. *
  262.     move.w    slice_width,_G_SLICE
  263.     move.w    #0,d0
  264. *
  265.     rts
  266.  
  267. _sendbuff:
  268.     rts
  269.         
  270. _getlstat:
  271.     move.w    #0,d0        * Stub in dot matrix printers
  272.     rts
  273.  
  274.     .page
  275. *************************************************************************
  276. *                                    *
  277. *    CONCAT                               *
  278. *                                    *
  279. *    This routine converts x and y-coordinates into a physical    *
  280. *    offset to a word in the rasterizing buffer and an index to    *
  281. *    the desired bit within that word.                *
  282. *                                    *
  283. *    Inputs:                                *
  284. *       d0.w = x-coordinate                        *
  285. *       d1.w = y-coordinate                        *
  286. *                                    *
  287. *    Outputs:                            *
  288. *       d0.w = word index (x mod 16)                    *
  289. *       d1.l = physical offset -- (y * bytes_line)            *
  290. *                    + (x & $FFF0) >> 3        *
  291. *                                    *
  292. *    Registers Modified:    None                    *
  293. *                                    *
  294. *************************************************************************
  295.  
  296. *
  297. *    Save the registers that get clobbered and convert the y-coordinate
  298. *    to an offset to the start of the desired scan row.
  299. *
  300. concat:
  301.     move.w    d2,-(a7)    * save the register that gets clobbered
  302.  
  303. *    sub.w    _TOPMRGN,d1    * NOT NEEDED CUZ YS_MIN IS ADJUSTED ACCORDINGLY
  304.     sub.w    _LFTMRGN,d0
  305.  
  306.     sub.w    _YS_MIN,d1    * normalize the y-coordinate to start of slice
  307.     mulu    bytes_line,d1    * compute offset to start of scan row
  308.  
  309. *
  310. *    Compute the bit offset into the desired word, save it, and remove
  311. *    these bits from the x-coordinate.
  312. *
  313.     move.w    d0,d2        * save a copy of the x-coordinate
  314.     andi.w    #$0F,d0        * convert it to bit offset into word
  315.     sub.w    d0,d2        * clear bits for offset into word
  316.  
  317. *
  318. *    Convert the adjusted x-coordinate to a word offset into the current
  319. *    scan line by dividing it by 8.  Compute the total offset into the
  320. *    buffer and restore the clobbered registers before returning.
  321. *
  322.     asr.w    #3,d2        * convert result to word offset
  323.     ext.l    d2        * convert word offset to long word
  324.     add.l    d2,d1        * compute total offset into buffer
  325.     move.w    (a7)+,d2    * restore the clobbered register
  326.     rts
  327.  
  328.  
  329. _init_p:
  330.     jsr _set_vars
  331.     rts
  332.  
  333.  
  334. _dinit_p:
  335.     rts
  336.  
  337.  
  338. *************************************************************************
  339. *                                    *
  340. *    printer_out                            *
  341. *                                    *
  342. *    This routine outputs a string of characters to the printer    *
  343. *    buffer.  The first byte in the string is a signed count of    *
  344. *    the number of characters.                    *
  345. *                                    *
  346. *    Inputs:                                *
  347. *        a0 - address of string to print                *
  348. *                                    *
  349. *    Registers Modified:    d0, d1, a0                *
  350. *                                    *
  351. *************************************************************************
  352.  
  353. *
  354. *    If something has gone wrong with the printer then abort the
  355. *    print job.
  356. *
  357. printer_out:
  358.     movem.l    d0-d7/a0-a6,-(sp)
  359.     tst.w    _abort        * check the abort flag
  360.     bne    end_ptr_out    * it's non-zero so bail out
  361.  
  362. *
  363. *    Get the length of the string.
  364. *
  365.     moveq.l    #0,d1
  366.      move.b    (a0)+,d1    * get the count
  367.     cmp.b    #1,d1
  368.     beq    end_ptr_out    * nothing to xmit if the count is 0
  369.     moveq.l    #0,d0        * clear for bios call
  370. *
  371. *    Loop buffering the characters.
  372. *
  373.  
  374. ptrout1:
  375.     move.l    a0,-(sp)
  376.     move.l    d1,-(sp)
  377.     move.w    _handle,-(sp)
  378.     move.w    #$40,-(sp)
  379.     trap    #1
  380.     adda.w    #12,sp
  381.  
  382. *    move.b    (a0)+,chr_ad1
  383. *    movem.l    d0-d1/a0,-(sp)
  384. *    move.w    chr_ad,-(sp)
  385. *    move.w    #0, -(sp)            * Ici fonction Bconout
  386. *    move.w    #3, -(sp)            * Sortie d'un car. sur
  387. *    trap    #13                    * 0=Centronics 1=R232 5=ecran
  388. *    adda.w    #6,a7
  389. *    movem.l    (sp)+,d0-d1/a0
  390. *    dbra    d1,ptrout1
  391.  
  392. end_ptr_out:
  393.     movem.l    (sp)+,d0-d7/a0-a6
  394.     rts
  395.  
  396.     .page
  397. *************************************************************************
  398. *                                    *
  399. *    pout                                *
  400. *                                    *
  401. *    This routine outputs a single character to the printer        *
  402. *    port.                                *
  403. *                                    *
  404. *    Inputs:                                *
  405. *        d0 - character to print                    *
  406. *                                    *
  407. *    Registers Modified:    d0                    *
  408. *                                    *
  409. *************************************************************************
  410.  
  411. *
  412. *    If something has gone wrong with the printer then abort the
  413. *    print job.
  414. *  
  415. pout:
  416.     movem.l    d0-d7/a0-a6,-(sp)
  417. poutb:
  418.     tst.w    _abort        * check the abort flag
  419.     bne.w    pout2        * it's non-zero so bail out
  420.     move.b    d0, chr_ad
  421.     pea    chr_ad
  422.     move.l    #1,-(sp)
  423.     move.w    _handle,-(sp)
  424.     move.w    #$40,-(sp)    * setup for gemdos write call
  425.     trap    #1
  426.     adda.l    #12,sp
  427. pout2: 
  428.     movem.l    (sp)+,d0-d7/a0-a6
  429.     rts
  430.  
  431.     .page    
  432. *************************************************************************
  433. *                                    *
  434. *    INIT_DEV                            *
  435. *                                    *
  436. *    This routine initializes the printer.  It is a no-op for    *
  437. *    the Epson printer.                        *
  438. *                                    *
  439. *    Inputs:        None                        *
  440. *                                    *
  441. *    Outputs:    None                        *
  442. *                                    *
  443. *    Registers Modified:    None                    *
  444. *                                    *
  445. *************************************************************************
  446.  
  447.  
  448.  
  449.     .page
  450. *************************************************************************
  451. *                                    *
  452. *    DINI_DEV                            *
  453. *                                    *
  454. *    This routine de-initializes the printer.  It is a no-op for    *
  455. *    the Epson printer.                        *
  456. *                                    *
  457. *    Inputs:        None                        *
  458. *                                    *
  459. *    Outputs:    None                        *
  460. *                                    *
  461. *    Registers Modified:    None                    *
  462. *                                    *
  463. *************************************************************************
  464.  
  465.  
  466.     .page
  467. *************************************************************************
  468. *                                    *
  469. *     ENTER_GR                            *
  470. *                                    *
  471. *    This routine is used to put the printer into graphics mode    *
  472. *    and to set the desired defaults.  For the HP paintjet the    *
  473. *    defaults include:  page width, dpi, number of planes,         *
  474. *    color palette, cursor position, and transmission mode.        *
  475. *                                    *
  476. *    Inputs:        None                        *
  477. *                                    *
  478. *    Outputs:    None                        *
  479. *                                    *
  480. *    Registers Modified:    None                    *
  481. *                                    *
  482. *************************************************************************
  483.  
  484. _enter_gr:
  485.     lea    width,a0                    
  486.     jsr    printer_out                        
  487.  
  488.     lea    low_dpi,a0    * default = 90 dpi (planes=4)
  489.     jsr    printer_out
  490.  
  491.     move.w    NPLANES,d1
  492.     cmp.w    #4,d1        * max. # of planes?
  493.     bne    highdpi        * no - so use 180 dpi
  494.     bra     send_numplanes    * yes - 90 dpi already set above
  495. highdpi:
  496.     tst.w    _drvr_qulty    * draft_mode?
  497.     beq    send_numplanes    * yes - lower dpi already set above
  498.     lea    high_dpi,a0    * no - use high dpi for final mode
  499.     jsr    printer_out
  500.  
  501. send_numplanes:
  502.     lea    escape_r,a0    * 1st part
  503.     jsr    printer_out
  504.     moveq    #0,d0
  505.     move.w    NPLANES,d0    * # 4 of planes on force 4 plans
  506.     jsr    convert_itoa    * 2nd part
  507.     move.b    #'U',d0        * 3rd part
  508.     jsr    pout
  509.  
  510.     clr.l    d1        
  511.     clr.l    d0        
  512. *    lea    _COLOR_TAB,a1    
  513. color_palette:
  514. cont_scan:
  515.     lea    enter_graph,a0    * start raster graphics
  516.     jsr    printer_out
  517.  
  518.     lea    transmit_mode,a0  * transmission mode (compression)
  519.     jsr    printer_out
  520.  
  521.     rts
  522.  
  523.     .page
  524. *************************************************************************
  525. *                                    *
  526. *    ADV_FORM                            *
  527. *                                    *
  528. *    This routine advances the printer to the start of the next    *
  529. *    form.                                *
  530. *                                    *
  531. *    Inputs:        None                        *
  532. *                                    *
  533. *    Outputs:                            *
  534. *       vmu - reset to 0                        *
  535. *                                    *
  536. *    Registers Modified:    d0                    *
  537. *                                    *
  538. *************************************************************************
  539.  
  540. _adv_form:
  541.     moveq    #FORM_FEED,d0    * get form feed control code
  542.     jsr    pout        * stuff it into printer transmit buffer
  543.     clr.w    _vmu        * reset the vertical motion unit counter
  544.     rts
  545.  
  546.     .page
  547. *************************************************************************
  548. *                                    *
  549. *    EXIT_GR                                *
  550. *                                    *
  551. *    This routine takes the printer out of the graphics mode.    *
  552. *                                    *
  553. *    Inputs:        None                        *
  554. *                                    *
  555. *    Outputs:    None                        *
  556. *                                    *
  557. *    Registers Modified:    a0                    *
  558. *                                    *
  559. *************************************************************************
  560.  
  561. _exit_gr:
  562.     lea    end_graph,a0        * send end graphics sequence
  563.     jsr    printer_out
  564.  
  565.     rts
  566.  
  567.     .page
  568. *************************************************************************
  569. *                                    *
  570. *    CONVERT_ITOA                            *
  571. *                                    *
  572. *    Inputs:        d0                        *
  573. *                                    *
  574. *    Outputs:    ascii value sent to printer            *
  575. *                                    *
  576. *    Registers Modified:    d0, d1, a7                *
  577. *                                    *
  578. *************************************************************************
  579.  
  580. convert_itoa:
  581.     movem.l    d0-d1,-(a7)    * save registers
  582.  
  583.     clr.l    d1        * loop cntr
  584. next_digit:
  585.     divu    #10,d0        * divide by base 10
  586.     swap    d0
  587.     add.b    #"0",d0        * convert to ascii
  588.     move.b    d0,-(a7)    * store on stack
  589.     addq.b    #1,d1    
  590.     clr.w    d0        * clear what will be high word
  591.     swap    d0
  592.     tst.w    d0
  593.     bne    next_digit
  594.     
  595.     subq.b    #1,d1        * for dbra
  596. ascii_value:
  597.     move.b    (a7)+,d0
  598.     jsr    pout
  599.     dbra    d1,ascii_value
  600.  
  601.     movem.l    (a7)+,d0-d1    * restore registers
  602.     rts
  603.  
  604.     .page
  605. *************************************************************************
  606. *                                    *
  607. *    SCAN_OUT                            *
  608. *                                    *
  609. *    Scan the contents of the rasterizing buffer.  Discard any    *
  610. *    trailing blanks.  If there is any data to send to the        *
  611. *    printer then convert it to printer dependent format, and     *
  612. *    send it.                            *
  613. *                                    *
  614. *    Inputs:        None                        *
  615. *                                    *
  616. *    Outputs:    None                        *
  617. *                                    *
  618. *    Registers Modified:    d0, d1, d2, a0, a1, a2            *
  619. *                                    *
  620. *************************************************************************
  621.  
  622. *
  623. *    Save the registers that get clobbered and determine how many
  624. *    slices of graphic data are in the rasterizing buffer.
  625. *
  626. _scan_out:
  627.     movem.l    d1-d7/a3-a6,-(a7)    * save the registers used by C
  628.  
  629.     move.w    _YW_MAX,d7    * get upper limit of window
  630.     cmp.w    _YS_MAX,d7    * does this slice extend beyond the window?
  631.     blt    calc_cnt    * yes - determine how many slices to print
  632.      move.w    slice_cnt,d7    * nope - get # of slices in buffer
  633.     bra    scan_parms
  634. calc_cnt:
  635.     sub.w    _YS_MIN,d7    * get # of scans - 1 in buffer
  636.     move.w    slice_width,d6    * get # of scans in a slice
  637.     add.w    d6,d7        * add it to # of scans - 1 for rounding
  638.     ext.l    d7        * make result a 32-bit quantity
  639.     divs    d6,d7        * compute # of slices to draw
  640.  
  641. *
  642. *    Get the address of the rasterizing buffer, initalize some additional
  643. *    parameters, and loop drawing slices of the buffer's contents to 
  644. *    the necessary planes.
  645. *
  646. scan_parms:
  647.     movea.l    graph_plane,a2    * get address of rasterizing buffer
  648.     movea.w    bytes_line,a6    * get length of a single scan line
  649.     move.w    scan_line_offset,a5    * get length of two scan lines
  650.     subq.w    #1,d7        * convert # of slices to loop counter
  651. *
  652. *    Analyse and output data for each color, one scan line at a time.
  653. *
  654.     moveq.l    #1,d1        * initialize plane counter
  655.     clr.b    lastplane
  656.     move.l    a2,plane_top    * Point to 1st plane, this slice
  657.  
  658. scan_next_slice:
  659.     jsr    back_scan    * eliminate trailing blanks in the line
  660.     tst.w    d3        * any non-blank bytes left?
  661.     bmi    no_data        * no
  662.     jsr    byte_out    * yes - print data for current color index
  663.     tst.b    lastplane    * last color plane?
  664.     bne    check_qulty_mode
  665.     addq.w    #1,d1        * no - increment plane counter
  666.  
  667.     cmp.w    num_planes,d1    * last color plane?
  668.     bne    next_plane    * no
  669.     st    lastplane    * yes-set variable for special escape seq.
  670.     bra    next_plane
  671. no_data:
  672.     lea    empty_plane,a0    * no data for this color plane
  673.     tst.b    lastplane    * last color plane?
  674.     beq    not_last    * no
  675.     lea    last_empty,a0    * yes - requires special escape seq.
  676. not_last:
  677.     jsr    printer_out
  678.     addq.w    #1,d1        * increment plane counter
  679.     cmp.w    num_planes,d1    * last color plane?
  680.     bmi    next_plane    * no - continue with next plane
  681.     bgt    check_qulty_mode
  682.     st    lastplane    * no - one more plane to go so set variable
  683. next_plane:
  684.     adda.l    plane_sz,a2    * advance ptr to next plane
  685.     bra    scan_next_slice    * scan same slice in next plane
  686.  
  687. *
  688. *    Skip every other line for draft mode.
  689. *
  690.  
  691. check_qulty_mode:
  692.     tst.w    _drvr_qulty        * final mode?
  693.     bne    setup_next_scan_line    * yes - so go on and print every line
  694. *                         * no-so skip next line only if in low dpi
  695.     move.w    NPLANES,d1
  696.     cmp.w    #4,d1            * max. # of planes? (AND draft mode)
  697.     beq    setup_next_scan_line    * yes - so go on and print every line
  698. *                    * no - (180dpi & draft mode) so skip line    
  699.     movea.l    plane_top,a2    * restore top of plane
  700.     adda.w    slice_offset,a2    * advance pointer to next slice
  701.     move.l    a2,plane_top    * Point to 1st plane at new slice
  702.     move.w    #1,d1        * initialize plane cntr for next slice
  703.     clr.b    lastplane
  704.     dbra    d7,setup_next_scan_line    * print every other line
  705.     bra    done            * no more lines to process
  706.  
  707. *    Advance the rasterizing buffer pointer to the start of the
  708. *    next slice and loop until all the slices are drawn.
  709. *
  710. setup_next_scan_line:
  711.     movea.l    plane_top,a2    * restore top of plane
  712.     adda.w    slice_offset,a2    * advance pointer to next slice
  713.     move.l    a2,plane_top    * Point to 1st plane at new slice
  714.     move.w    #1,d1        * initialize plane cntr for next slice
  715.     clr.b    lastplane
  716.     dbra    d7,scan_next_slice    * loop until all slices drawn
  717.  
  718. done:
  719.     movem.l    (a7)+,d1-d7/a3-a6    * restore all registers used by C
  720.     rts
  721.  
  722.     .page
  723. *************************************************************************
  724. *                                    *
  725. *    BACK_SCAN                            *
  726. *                                    *
  727. *    This routine determines the number of non-blank bytes in    *
  728. *    the next 8 even or odd numbered scan lines.  Trailing        *
  729. *    blanks are discarded before the data is sent to the printer.    *
  730. *                                    *
  731. *    Inputs:                                *
  732. *       a2.l - address of start of first scan line to check        *
  733. *       a5.w - offset to next even/odd scan line            *
  734. *       a6.w - # of bytes in a scan line                *
  735. *                                    *
  736. *    Outputs:                            *
  737. *       d3.w - # of non-blank bytes in each scan line        *
  738. *                                    *
  739. *    Registers Modified:    d3, d4, a3, a4                *
  740. *                                    *
  741. *************************************************************************
  742.  
  743. *
  744. *    Set up the loop counter for examining a single scan and initialize
  745. *    the master buffer pointer to the last byte in the first scan.
  746. *
  747. back_scan:
  748.     move.w    bytes_line,d3    * get # of bytes in a scan line
  749.     subq.w    #1,d3        * adjust for dbra loop
  750.     movea.l    a2,a3        * get start address of scan line
  751.     adda.w    a6,a3        * bump pointer to end of scan line
  752.  
  753. *
  754. *    Set up the loop counter for the number of scan lines to check,
  755. *    get a temporary copy of the master pointer for checking the current
  756. *    column of bytes, and bump the master pointer to the previous column.
  757. *
  758. check_next_column:
  759.     subq.w    #1,a3        * bump master pointer to next column
  760.  
  761. nxt_byte:
  762.     tst.b    (a3)        * is current byte non-blank?
  763.     bne    found_non_blank    * yes - done
  764.     dbra    d3,check_next_column    * loop until all columns are checked
  765. found_non_blank:
  766.     rts
  767.  
  768.     .page
  769. *************************************************************************
  770. *                                    *
  771. *    BYTE_OUT                            *
  772. *                                    *
  773. *    This routine extracts the data from the 8 even/odd scans    *
  774. *    of a slice and sends it to the printer.                *
  775. *                                    *
  776. *    Inputs:                                *
  777. *       d3.w - # of bytes -1 to print                *
  778. *       a3.l - address of start of first scan line in slice        *
  779. *       a5.w - offset to next even/odd scan line            *
  780. *                                    *
  781. *    Outputs:    None                        *
  782. *                                    *
  783. *    Registers Modified:    d0, d1, d2, a0, a3            *
  784. *                                    *
  785. *************************************************************************
  786. *    d1.w - loop counter
  787. *    d2.w - total count for bytes in row to send
  788. *    d3.w - # bytes in row to print (computed by back_scan routine)
  789. *    d4.w - temp variable for bytes_line
  790. *    d6.b - count for no. of similar bytes in block (same)
  791. *    a3.l - current byte
  792. *     a4.l - next byte
  793.  
  794. *
  795. *    Determine the number of columns of graphic data to send and prepare
  796. *    the printer to receive them.
  797. *
  798. byte_out:
  799.     movem.l    d1-d7/a2-a6,-(sp)
  800.     clr.l    d7        
  801.     move.w    _drvr_qulty,d7    * store quality mode
  802.  
  803.     move.w    NPLANES,d1
  804.     cmp.w    #4,d1        * max. # of planes? 
  805.     bne    initialization    * no
  806. *                  yes - so now check quality mode
  807.     tst.w    _drvr_qulty    * draft mode? (AND 4 planes)
  808.     bne    initialization    * no
  809.  
  810.     move.w    #1,d0        * change mode to final if already in low dpi
  811.     move.w    d0,_drvr_qulty    * and user requested draft mode
  812.  
  813. initialization:
  814.     clr.l    d2        * next=0
  815.     clr.l    d5        * total=0
  816.     clr.l    d4        * counter=0
  817.     clr.l    d6        * same=0
  818.     move.w    d3,d4        * use temp variable
  819.     movea.l a2,a3        * get ptr to start of 1st row of data
  820.     addq.l    #1,a3        * advance ptr 
  821.     movea.l    a3,a4        * store next ptr
  822.     movea.l a2,a3        * get ptr to start of 1st row of data
  823.  
  824. * special case - one byte row
  825.     tst.w    d4        * does row have only one byte?
  826.     beq    end1        * yes - account for 1 data byte & 1 cnt byte
  827.     subq.w    #1,d4        * no: 2 bytes = 1 comparison
  828.  
  829.     tst.w    _drvr_qulty
  830.     bne    next1
  831.  
  832. * testing
  833.     addq.w    #1,d4
  834. *    subq.w    #1,d4        * no: 2bytes= 1comparison (draft=> 4bytes=1comp)
  835.         move.b  (a3)+,d1                * d1 = first byte
  836.  
  837. * Get every other bit of first byte
  838.  
  839.         clr.l   d0                      * clear out work register
  840.         add.b   d1,d1                   * shift out bit 7 of data byte
  841.         addx.b  d0,d0                   * shift into bit 0 of work register
  842.         add.b   d1,d1                   * shift out bit 5
  843.         add.b   d1,d1
  844.         addx.b  d0,d0
  845.         add.b   d1,d1                   * shift out bit 3
  846.         add.b   d1,d1
  847.         addx.b  d0,d0
  848.         add.b   d1,d1                   * shift out bit 1
  849.         add.b   d1,d1
  850.         addx.b  d0,d0
  851.  
  852. * Get every other bit of second byte
  853.  
  854.         subq.w  #1,d4                   * decrement raster loop counter
  855.     tst.w    d4            * ended on odd byte?
  856.     bge    not_odd1
  857.     move.b    d0,d1            * set to d1 in case there is no 2nd byte
  858.     rol.b    #4,d1            * make last nibble blank(2nd byte blank)
  859.     blt    end1            * yes
  860. not_odd1:
  861.         move.b  (a3)+,d1                * d1 = second byte
  862.  
  863.         add.b   d1,d1                   * shift out bit 7 of data byte
  864.         addx.b  d0,d0                   * shift into bit 0 of work register
  865.         add.b   d1,d1                   * shift out bit 5
  866.         add.b   d1,d1
  867.         addx.b  d0,d0
  868.         add.b   d1,d1                   * shift out bit 3
  869.         add.b   d1,d1
  870.         addx.b  d0,d0
  871.         add.b   d1,d1                   * shift out bit 1
  872.         add.b   d1,d1
  873.         addx.b  d0,d0
  874.  
  875. *        move.b  d0,d1                   * d1 = combined byte to output
  876.         move.b  d0,d2                   * d2 = combined byte to output
  877.  
  878.         subq.w  #1,d4                   * decrement raster loop counter
  879.     tst.w    d4
  880.     blt    end1
  881. next1_mask:    
  882.     move.b    d2,d1        * curr = next
  883.         move.b  (a3)+,d2                * d2 = first byte
  884.  
  885. * Get every other bit of first byte
  886.  
  887.         clr.l   d0                      * clear out work register
  888.         add.b   d2,d2                   * shift out bit 7 of data byte
  889.         addx.b  d0,d0                   * shift into bit 0 of work register
  890.         add.b   d2,d2                   * shift out bit 5
  891.         add.b   d2,d2
  892.         addx.b  d0,d0
  893.         add.b   d2,d2                   * shift out bit 3
  894.         add.b   d2,d2
  895.         addx.b  d0,d0
  896.         add.b   d2,d2                   * shift out bit 1
  897.         add.b   d2,d2
  898.         addx.b  d0,d0
  899.  
  900. * Get every other bit of second byte
  901.  
  902.         subq.w  #1,d4                   * decrement raster loop counter
  903.     tst.w    d4
  904.     bge    even1_byte
  905.  
  906.     move.b    d0,d2            * set to d2 in case there is no 2nd byte
  907.     rol.b    #4,d2            * make last nibble blank(2nd byte blank)
  908.     bra    next1_dft        * yes
  909.  
  910. even1_byte:    
  911.         move.b  (a3)+,d2                * d2 = second byte
  912.  
  913.         add.b   d2,d2                   * shift out bit 7 of data byte
  914.         addx.b  d0,d0                   * shift into bit 0 of work register
  915.         add.b   d2,d2                   * shift out bit 5
  916.         add.b   d2,d2
  917.         addx.b  d0,d0
  918.         add.b   d2,d2                   * shift out bit 3
  919.         add.b   d2,d2
  920.         addx.b  d0,d0
  921.         add.b   d2,d2                   * shift out bit 1
  922.         add.b   d2,d2
  923.         addx.b  d0,d0
  924.  
  925.         move.b  d0,d2                   * d2 = combined byte to output
  926.  
  927. next1_dft:
  928.     cmp.b    d1,d2
  929.     bne    dif1
  930.     tst.b    d6
  931.     bgt    same1
  932.     bra    sim_blk1
  933.     
  934. * first pass - analyse row of data
  935. next1:
  936.     cmpm.b    (a3)+,(a4)+    * compare consecutive bytes
  937.     bne    dif1        * dealing w/ dissimilar consecutive bytes
  938.     tst.b    d6
  939.     bgt    same1        * if same>0 continue within similar block
  940. sim_blk1:            * else if same=0 begin similar block
  941.     addq.b    #1,d6        * same++
  942. total:    addq.w    #2,d5        * 1 for byte cnt & 1 for data byte
  943.     bra    cont1
  944. same1:        
  945.     cmpi.b    #127,d6        * maximum transfer reached?
  946.     bge    lg_same1    * yes
  947.     addq.b    #1,d6        * no - same++
  948.     bra     cont1        * continue to next byte
  949. lg_same1:
  950.     clr.b    d6        * same=0; initialize variable to begin new block
  951.     bra    sim_blk1    * require new block
  952. dif1:                * transition from old block to new block
  953.     tst.b    d6
  954.     beq    total        * new dissimilar block encountered
  955.     clr.b    d6        * transition from similar to dissimilar block
  956.  
  957. cont1:    tst.w    _drvr_qulty
  958.     bne    cont1_fnl
  959.     tst.w    d4
  960.     blt    dft_1backup
  961.     dbra    d4, next1_mask    * next = new
  962.     bra    dft_1backup
  963. cont1_fnl:
  964.     dbra    d4,next1    * compare next pair of bytes
  965.     bra    fnl_1backup
  966. dft_1backup:
  967.     cmp.b    d1,d2
  968.     beq    sameblk1
  969.     bra    end1
  970. fnl_1backup:
  971. * back up and account for last byte
  972.     subq.l    #1,a3        * move pointer back by one
  973.     subq.l    #1,a4        * move pointer back by one
  974.     cmpm.b    (a3)+,(a4)+
  975.     beq    sameblk1    * last 2 bytes are same
  976.     bra    end1        * last 2 bytes are different
  977. sameblk1:
  978.     cmpi.b    #127,d6        * maximum transfer reached?
  979.     bge    end1        * yes
  980.     bra    done1        * don't increment d6 cuz cnt must be one fewer
  981. end1:
  982.     addq.w    #2,d5        * new block for last byte
  983. done1:    
  984.     lea    send_cnt,a0    * send next part of transfer sequence
  985.     jsr    printer_out    
  986.     move.l    d5,d0        * get total cnt that needs to be sent in ascii    
  987.  
  988.     jsr    convert_itoa
  989.  
  990. * send 3rd part of trnsfr sequence
  991.     move.b    #'V',d0        * trnsfr seq. for color plane
  992.     tst.b    lastplane    * last plane?
  993.     beq    out        * no
  994.     move.b    #'W',d0        * yes - trnsfr seq. for last color plane
  995. out:    jsr    pout
  996.  
  997. * second pass to send out data
  998. * initialization
  999.     clr.l    d2        * next=0
  1000.     clr.l    d4        * counter=0
  1001.     clr.l    d6        * same=0; reset variable for second pass
  1002.     move.w    d3,d4        * use temp variable
  1003.     movea.l a2,a3        * get ptr to start of 1st row of data
  1004.     addq.l    #1,a3        * advance ptr
  1005.     movea.l    a3,a4        * next ptr
  1006.     movea.l a2,a3        * current ptr
  1007.     
  1008.  
  1009.     tst.w    d4        * does row have only one byte?
  1010.     bne    manybytes
  1011.  
  1012. * special case - one byte row
  1013.     tst.w    _drvr_qulty
  1014.     bne    fnl_onebyte
  1015. dft_onebyte:
  1016. *    move.b    (a3),d1
  1017.     move.b    (a3),d2
  1018.     bra    end2
  1019. fnl_onebyte:
  1020. *    addq.l    #1,a3
  1021.     bra    end2
  1022. manybytes:
  1023.     subq.w    #1,d4        * i.e. 2 bytes = 1 comparison
  1024.  
  1025.  
  1026.     tst.w    _drvr_qulty
  1027.     bne    next2
  1028.  
  1029. * testing
  1030.     addq.w    #1,d4
  1031. *    subq.w    #1,d4        * no: 2bytes= 1comparison (draft=> 4bytes=1comp)
  1032.  
  1033.         move.b  (a3)+,d1                * d1 = first byte
  1034.  
  1035. * Get every other bit of first byte
  1036.  
  1037.         clr.l   d0                      * clear out work register
  1038.         add.b   d1,d1                   * shift out bit 7 of data byte
  1039.         addx.b  d0,d0                   * shift into bit 0 of work register
  1040.         add.b   d1,d1                   * shift out bit 5
  1041.         add.b   d1,d1
  1042.         addx.b  d0,d0
  1043.         add.b   d1,d1                   * shift out bit 3
  1044.         add.b   d1,d1
  1045.         addx.b  d0,d0
  1046.         add.b   d1,d1                   * shift out bit 1
  1047.         add.b   d1,d1
  1048.         addx.b  d0,d0
  1049.  
  1050. * Get every other bit of second byte
  1051.  
  1052.         subq.w  #1,d4                   * decrement raster loop counter
  1053.     tst.w    d4
  1054.     bge    not_odd2
  1055.     move.b    d0,d1            * set to d1 in case there is no 2nd byte
  1056.     rol.b    #4,d1            * make last nibble blank(2nd byte blank)
  1057.     blt    end2            * yes
  1058. not_odd2:
  1059.         move.b  (a3)+,d1                * d1 = second byte
  1060.  
  1061.         add.b   d1,d1                   * shift out bit 7 of data byte
  1062.         addx.b  d0,d0                   * shift into bit 0 of work register
  1063.         add.b   d1,d1                   * shift out bit 5
  1064.         add.b   d1,d1
  1065.         addx.b  d0,d0
  1066.         add.b   d1,d1                   * shift out bit 3
  1067.         add.b   d1,d1
  1068.         addx.b  d0,d0
  1069.         add.b   d1,d1                   * shift out bit 1
  1070.         add.b   d1,d1
  1071.         addx.b  d0,d0
  1072.  
  1073. *        move.b  d0,d1                   * d1 = combined byte to output
  1074.         move.b  d0,d2                   * d2 = combined byte to output
  1075.     subq.l    #1,d4
  1076.     tst.w    d4
  1077.     blt    end2
  1078. next2_mask:            
  1079.     move.b    d2,d1
  1080.         move.b  (a3)+,d2                * d2 = first byte
  1081.  
  1082. * Get every other bit of first byte
  1083.  
  1084.         clr.l   d0                      * clear out work register
  1085.         add.b   d2,d2                   * shift out bit 7 of data byte
  1086.         addx.b  d0,d0                   * shift into bit 0 of work register
  1087.         add.b   d2,d2                   * shift out bit 5
  1088.         add.b   d2,d2
  1089.         addx.b  d0,d0
  1090.         add.b   d2,d2                   * shift out bit 3
  1091.         add.b   d2,d2
  1092.         addx.b  d0,d0
  1093.         add.b   d2,d2                   * shift out bit 1
  1094.         add.b   d2,d2
  1095.         addx.b  d0,d0
  1096.  
  1097. * Get every other bit of second byte
  1098.  
  1099.         subq.w  #1,d4                   * decrement raster loop counter
  1100.     tst.w    d4            * ended on odd byte?
  1101.     bge    even2_byte
  1102.  
  1103.     move.b    d0,d2            * set to d2 in case there is no 2nd byte
  1104.     rol.b    #4,d2            * make last nibble blank(2nd byte blank)
  1105.     bra    next2_dft        * yes
  1106.  
  1107. even2_byte:    
  1108.         move.b  (a3)+,d2                * d2 = second byte
  1109.  
  1110.         add.b   d2,d2                   * shift out bit 7 of data byte
  1111.         addx.b  d0,d0                   * shift into bit 0 of work register
  1112.         add.b   d2,d2                   * shift out bit 5
  1113.         add.b   d2,d2
  1114.         addx.b  d0,d0
  1115.         add.b   d2,d2                   * shift out bit 3
  1116.         add.b   d2,d2
  1117.         addx.b  d0,d0
  1118.         add.b   d2,d2                   * shift out bit 1
  1119.         add.b   d2,d2
  1120.         addx.b  d0,d0
  1121.  
  1122.         move.b  d0,d2                   * d2 = combined byte to output
  1123.  
  1124. next2_dft:
  1125.     cmp.b    d1,d2
  1126.     bne    dif2
  1127.     tst.b    d6
  1128.     bgt    same2
  1129.     bra    sim_blk2
  1130. next2:
  1131.     cmpm.b    (a3)+,(a4)+    * compare consecutive bytes
  1132.     bne    dif2         * dealing w/ dissimilar consecutive bytes
  1133.     tst.b    d6        * same=?
  1134.     bgt    same2        * same>0; continue within similar block
  1135. sim_blk2:
  1136.     addq.b    #1,d6        * same==0; begin similar block; same++
  1137.     bra    cont2
  1138. same2:
  1139.     cmpi.b    #127,d6        * maximum transfer reached?
  1140.     bge    lg_same2    * yes
  1141.     addq.b    #1,d6        * no - same++
  1142.     bra     cont2        * continue to next byte
  1143. lg_same2:
  1144.     subq.b    #1,d6        * byte always printed at least once
  1145.     move.b    d6,d0        * send repeat count to printer
  1146.     jsr    pout
  1147.  
  1148.     tst.w    _drvr_qulty
  1149.     bne    sendbyte_fnl
  1150.     move.b    d1,d0
  1151.     jsr    pout    
  1152. sendbyte_fnl:
  1153.     move.b    (a3),d0        * get repeated data byte to output
  1154.     jsr    pout
  1155.     clr.b    d6        * same=0; reset variable for new block
  1156.     bra    sim_blk2    * require new block
  1157. dif2:                * transition from old block to new block
  1158.     tst.b    d6        
  1159.     beq    no_prev_blk    
  1160.     move.b    d6,d0        * send repeat count to printer
  1161.     jsr    pout
  1162.     tst.w    _drvr_qulty
  1163.     bne    dif2_fnl
  1164.     move.b    d1,d0
  1165.     jsr    pout
  1166.     clr.b    d6
  1167.     bra    cont2
  1168. dif2_fnl:
  1169.     subq.l    #1,a3        * move current ptr back
  1170.     move.b    (a3),d0        * get repeated data byte to output
  1171.     jsr    pout
  1172.     addq.l    #1,a3        * restore current ptr
  1173.     clr.b    d6        * same=0; clear var for next block
  1174.     bra     cont2
  1175. no_prev_blk:
  1176.     clr.b    d0        * else if same=0 send one dissimilar data byte
  1177.     jsr    pout
  1178.     tst.w    _drvr_qulty
  1179.     bne    fnl_no_prev_blk
  1180.     move.b    d1,d0
  1181.     jsr    pout
  1182.     clr.b    d6
  1183.     bra    cont2
  1184. fnl_no_prev_blk:
  1185.     subq.l    #1,a3        * move current ptr back
  1186.     move.b    (a3),d0        * get data byte to output
  1187.     jsr    pout
  1188.     addq.l    #1,a3        * restore current ptr
  1189.     clr.b    d6        * same=0; clear var for next block
  1190.     bra    cont2
  1191.  
  1192. cont2:    tst.w    _drvr_qulty
  1193.     bne    cont2_fnl
  1194.     tst.w    d4
  1195.     blt    dft_2backup
  1196.     dbra    d4, next2_mask    * next = new
  1197.     bra    dft_2backup
  1198. cont2_fnl:
  1199.     dbra    d4,next2    * compare next pair of bytes
  1200.     bra    fnl_2backup
  1201. dft_2backup:
  1202.     cmp.b    d1,d2
  1203.     beq    sameblk2
  1204.     bra    last_byte    
  1205. fnl_2backup:
  1206. * back up and account for last byte
  1207.     subq.l    #1,a3        * move pointer back by one
  1208.     subq.l    #1,a4        * move pointer back by one
  1209.     cmpm.b    (a3)+,(a4)+
  1210.     beq    sameblk2
  1211.     bra    last_byte    * else send dissimilar block
  1212. sameblk2:
  1213.     cmpi.b    #127,d6        * maximum transfer reached?
  1214.     bge    done2        * yes
  1215. end2:
  1216.     tst.b    d6        * check if there exists a prev block to send
  1217.     beq    last_byte
  1218.     move.b    d6,d0        
  1219.     jsr    pout        * send repeat count to printer
  1220.     tst.w    _drvr_qulty
  1221.     bne    end2_fnl
  1222.     move.b    d2,d0
  1223.     jsr    pout
  1224.     bra    end_byte_out
  1225. end2_fnl:
  1226.     subq.l    #1,a3        * move current ptr back
  1227.     move.b    (a3),d0        * get repeated data byte to output
  1228.     jsr    pout
  1229.     addq.l    #1,a3        * restore current ptr
  1230.     bra    end_byte_out    * done with second pass of one row
  1231. last_byte:
  1232.     clr.b    d0        * zero cnt means one data byte
  1233.     jsr    pout
  1234.     tst.w    _drvr_qulty
  1235.     bne    fnl_last_byte:
  1236.     move.b    d2,d0
  1237.     jsr    pout
  1238.     bra    end_byte_out
  1239. fnl_last_byte:
  1240.     move.b    (a3),d0        * get data byte to output
  1241.     jsr    pout
  1242.     bra    end_byte_out    * done with second pass of one row
  1243. done2:                * send maximum transfer of 127 bytes
  1244.     subq.b    #1,d6        * byte always printed at least once
  1245.     move.b    d6,d0        * send repeat count to printer
  1246.     jsr    pout
  1247.     tst.w    _drvr_qulty
  1248.     bne    done2_fnl
  1249.     move.b    d1,d0
  1250.     jsr    pout
  1251.     bra    end2
  1252. done2_fnl:
  1253.     move.b    (a3),d0        * get repeated data byte to output
  1254.     jsr    pout
  1255.     bra    end2        * print last byte (byte #128)
  1256. end_byte_out:            * done with second pass of one row
  1257.     move.w    d7,_drvr_qulty    * restore value if changed above
  1258.     movem.l    (sp)+,d1-d7/a2-a6
  1259.     rts    
  1260.     .page
  1261. *************************************************************************
  1262. *                                    *
  1263. *    ALPHAOUT                            *
  1264. *                                    *
  1265. *    This routine prints alphanumeric text.  It also handles        *
  1266. *    escape sequences for setting/clearing alphanumeric text        *
  1267. *    attributes.  The accepted escape sequences are:            *
  1268. *       DC2 0 - begin bold                        *
  1269. *       DC2 1 - end bold                        *
  1270. *       DC2 2 - begin italic                        *
  1271. *       DC2 3 - end italic                        *
  1272. *       DC2 4 - begin underline                    *
  1273. *       DC2 5 - end underline                    *
  1274. *                                    *
  1275. *    Inputs:                                *
  1276. *       INTIN - alphanumeric text string                *
  1277. *       CONTRL[3] - # of characters in the text string        *
  1278. *                                    *
  1279. *    Outputs:    None                        *
  1280. *                                       *
  1281. *    Registers Modified:    d0, d1, d2, a0, a1, a2            *
  1282. *                                    *
  1283. *************************************************************************
  1284.  
  1285. *
  1286. *    Before printing the alphanumeric text we must do the following
  1287. *    tasks.
  1288. *       1) Ensure that the output will occur on a character line.
  1289. *       2) Ensure that alphanumeric attributes are properly set.
  1290. *       3) Set up the pointer and counter for for the character loop.
  1291. *
  1292. _alphaout:
  1293.     movem.l    d3-d5/a3,-(a7)    * save the registers used by C
  1294.     jsr    vmu_sync    * align the paper to a printer character line
  1295.     jsr    alphaenv    * make sure that attributes are set correctly
  1296.     movea.l    _CONTRL,a0    * get address of CONTRL array
  1297.     move.w    6(a0),d2    * get the # of characters to print
  1298.     subq.w    #1,d2        * convert it to a loop counter
  1299.     movea.l    _INTIN,a2    * get address of character string
  1300.  
  1301. *
  1302. *    Check the next two characters in the string to determine if they form
  1303. *    an attribute escape sequence.  A valid escape sequence starts with a
  1304. *    DC2 and is terminated with an ASCII 0 through 5.
  1305. *
  1306. alpha_loop:
  1307.     move.w    (a2)+,d0    * get the next character
  1308.     cmpi.b    #ALPHA_ESCAPE,d0    * do we have an escape sequence?
  1309.     bne    not_escape        * nope
  1310.     tst.w    d2        * is this the last character?
  1311.     beq    not_escape        * yes - no escape sequence
  1312.     move.w    (a2),d1        * get the next character
  1313.     subi.b    #'0',d1        * ASCII 0 or greater?
  1314.     bmi    not_escape        * nope
  1315.     cmpi.b    #5,d1        * ASCII 5 or less?
  1316.     bgt    not_escape        * nope
  1317.  
  1318. *
  1319. *    We have found an attribute escape sequence.  Update the requested
  1320. *    attributes flags and send the appropriate escape sequence to the
  1321. *    printer.
  1322. *
  1323.     subq.w    #1,d2        * decrement the character count for the DC2
  1324.     addq.w    #2,a2        * bump the pointer to the next character
  1325.     lsr.w    #1,d1        * convert attribute code to bit index
  1326.     bcs    clr_bit        * branch if code was odd
  1327.     bset.b    d1,_reqalpha    * set bit if code was even
  1328.     bra    set_att        * send escape sequence to printer
  1329. clr_bit:
  1330.     bclr.b    d1,_reqalpha    * clear bit if code was odd
  1331. set_att:
  1332.     jsr    alphaenv    * send the escape sequence to the printer
  1333.     bra    next_alpha_loop    * test if done with string yet
  1334.  
  1335. *
  1336. *    If the current character is a line feed then add the number
  1337. *    of steps in an alphanumeric character to the vmu count.
  1338. *
  1339. not_escape:
  1340.     jsr    pout        * send the character to the printer
  1341.  
  1342. *    If the current character is a form feed or line then reset the vmu count.
  1343.  
  1344.     cmpi.b    #LF,d0        * current character a line feed?
  1345.     bne    vme_check_ff        * nope
  1346.     move.w    _A_SLICE,d1    * yes - get height of alpha text in pixels
  1347.     add.w    d1,_vmu        * add # of scans in character to count
  1348.     bra    next_alpha_loop    * test if done with string yet
  1349.  
  1350. vme_check_ff:
  1351.     cmpi.b    #FORM_FEED,d0    * current character a form feed?
  1352.     bne    next_alpha_loop    * nope
  1353.     clr.w    _vmu        * yes - reset the count
  1354.  
  1355. *
  1356. *    Send the current character to the printer and loop until done with
  1357. *    the character string.
  1358. *
  1359. next_alpha_loop:
  1360.     dbra    d2,alpha_loop    * loop until done with character string
  1361.     movem.l    (a7)+,d3-d5/a3    * restore the registers used by C
  1362.     rts
  1363.  
  1364.     .page
  1365. *************************************************************************
  1366. *                                    *
  1367. *    VMU_SYNC                            *
  1368. *                                    *
  1369. *    This routine will advance the paper so that alphanumeric    *
  1370. *    text is aligned to printer character lines.            *
  1371. *                                    *
  1372. *    Inputs:        None                        *
  1373. *                                    *
  1374. *    Outputs:    None                        *
  1375. *                                    *
  1376. *    Registers Modified:    d0, d1, a0                *
  1377. *                                    *
  1378. *************************************************************************
  1379.  
  1380. *
  1381. *    Determine whether the paper is aligned to a printer character
  1382. *    line.  If not then determine the number of vertical motion units
  1383. *    to advance the paper, align it, and update the vmu count.
  1384. *
  1385. vmu_sync:
  1386.     moveq.l    #0, d0
  1387.     move.w    _vmu, d0    * get the current vmu count
  1388.     move.w    _A_SLICE, d1    * get the number of pixels in a character
  1389.     divs    d1, d0        * get vmu count modulo # of pixels in character
  1390.     swap    d0        * get the remainder
  1391.     cmp.w    #0, d0        * if there is no remainder we
  1392.     beq    vs_out        * we are currently aligned
  1393.     sub.w    d0, d1        * compute add'l # of vmu units needed
  1394.     add.w    d1, _vmu    * adjust vmu to next line
  1395.  
  1396. * The d1 register now contains the number of pixels to be advanced.  However,
  1397. * the Epson command uses 1/216 inch increments.  For high resolution, the
  1398. * number of pixels needs to be multiplied by 1.5.  For low resolution, the
  1399. * number of pixels needs to be multiplied by 3.
  1400.  
  1401. *    move.w    d1, d0        * get a copy of the amount
  1402. *    asr.w    #1, d0        * divide it by 2
  1403. *    add.w    d0, d1        * multiply amount by 1.5 to get # of steps
  1404.     move.b    d1,slf_cnt    * store # of printer steps in escape sequence
  1405.     lea    sized_lf,a0    * advance paper the desired # of steps
  1406.     jsr    printer_out
  1407. vs_out:
  1408.     rts
  1409.  
  1410.     .page
  1411. *************************************************************************
  1412. *                                    *
  1413. *    ALPHAENV                            *
  1414. *                                    *
  1415. *    This routine compares the requested alphanumeric text        *
  1416. *    attributes with the current values.  If they are different    *
  1417. *    the current attributes are updated and the appropriate        *
  1418. *    escape sequences are sent to the printer.            *
  1419. *                                    *
  1420. *    Inputs:                                *
  1421. *       reqalpha - requested attributes for alphanumeric text    *
  1422. *       curalpha - current attributes for alphanumeric text        *
  1423. *                                    *
  1424. *    Outputs:                            *
  1425. *       curalpha - updated with new attributes            *
  1426. *                                    *
  1427. *    Registers Modified:    d0, d3, d4, d5, a0, a3            *
  1428. *                                    *
  1429. *************************************************************************
  1430.  
  1431. *
  1432. *    Determine if there has been any change in the attributes for
  1433. *    alphanumeric text.  If not then do nothing.
  1434. *
  1435. alphaenv:
  1436.     move.b    _curalpha,d3    * get the current attributes
  1437.     move.b    _reqalpha,d4    * get the requested attributes
  1438.     eor.b    d4,d3        * any change?
  1439.     beq    end_alfaenv    * nope - just go away
  1440.  
  1441. *
  1442. *    At least one of the attributes has changed.  Initialize the
  1443. *    pointer and counter needed to determine which escape sequence(s)
  1444. *    must be sent to the printer.
  1445. *
  1446.     moveq.l    #2,d5        * get the loop counter (only 3 attributes)
  1447.     lea.l    com_add,a3    * get the address of the table
  1448.  
  1449. *
  1450. *    Loop checking the current attribute to see if it has changed.  If it
  1451. *    has then send an escape sequence to the printer to set/clear the
  1452. *    attribute.
  1453. *
  1454. alfaenv_loop:
  1455.     asr.b    #1,d3        * has the current attribute changed?
  1456.     beq    next_alfaenv_loop    * nope
  1457.     clr.w    d0        * yes - preset table index to set attribute
  1458.     asr.b    #1,d4        * get state for the current attribute
  1459.     roxl.w    #2,d0        * turn it into an offset of 0 or 2
  1460.     move.w    0(a3,d0.w),d0    * get the offset to the escape sequence
  1461.     lea    com_add(pc,d0.w),a0    * get address of the escape sequence
  1462.     jsr    printer_out    * send it to the printer
  1463. next_alfaenv_loop:
  1464.     addq.w    #4,a3        * update the pointer into the table
  1465.     dbra    d5,alfaenv_loop    * loop until all attributes checked
  1466. end_alfaenv:
  1467.     rts
  1468.  
  1469.  
  1470.  
  1471. *************************************************************************
  1472. *                                    *
  1473. *    Address offset table for escape sequences used to set/clear    *
  1474. *    alphanumeric text attributes                    *
  1475. *                                    *
  1476. *************************************************************************
  1477.  
  1478. com_add        dc.w    end_bold-com_add    * end bold attribute
  1479.         dc.w    begin_bold-com_add    * begin bold attribute
  1480.         dc.w    end_italic-com_add    * end italic attribute
  1481.         dc.w    begin_italic-com_add    * begin italic attribute
  1482.         dc.w    end_under-com_add    * end underscore attribute
  1483.         dc.w    begin_under-com_add    * begin underscore attribute
  1484.  
  1485.  
  1486.  
  1487. *************************************************************************
  1488. *                                    *
  1489. *    Printer Escape Sequences for Alphanumeric Text Attributes    *
  1490. *                                    *
  1491. *************************************************************************
  1492.  
  1493. end_bold    dc.b    2,ESC,'F'
  1494. begin_bold    dc.b    2,ESC,'E'
  1495. end_italic    dc.b    2,ESC,'5'
  1496. begin_italic    dc.b    2,ESC,'4'
  1497. end_under    dc.b    3,ESC,'-','0'
  1498. begin_under    dc.b    3,ESC,'-','1'
  1499.  
  1500.     .page
  1501. *************************************************************************
  1502. *                                    *
  1503. *            Local Variable Definitions                *
  1504. *                                    *
  1505. *************************************************************************
  1506. *    Default RGB values for color pallette
  1507. PLANE_COLORS
  1508.         dc.w    2    * 2 colors = 1 plane
  1509.         dc.w    4    * 4 colors = 2 planes
  1510.         dc.w    8    * 8 colors = 3 planes
  1511.         dc.w    16    * 16 colors = 4 planes
  1512.  
  1513.     .data
  1514.  
  1515. _MAP_COL
  1516.         dc.w    0    * white
  1517.         dc.w    1    * black
  1518.         dc.w    12    * red
  1519.         dc.w    10  * green
  1520.         dc.w    6    * blue
  1521.         dc.w    2    * cyan
  1522.         dc.w    8    * yellow
  1523.         dc.w    4    * magenta
  1524.         dc.w    3    * white
  1525.         dc.w    5    * black
  1526.         dc.w    7    * light red
  1527.         dc.w    9    * light green
  1528.         dc.w    11    * light blue
  1529.         dc.w    13    * light cyan 
  1530.         dc.w    14    * light yellow
  1531.         dc.w    15    * light magenta
  1532.  
  1533. _PAL_RGB
  1534.         dc.w    1000,1000,1000
  1535.         dc.w    0,0,0
  1536.         dc.w    1000,0,0
  1537.         dc.w    0,1000,0
  1538.         dc.w    0,0,1000
  1539.         dc.w    0,1000,1000
  1540.         dc.w    1000,1000,0
  1541.         dc.w    1000,0,1000
  1542.         dc.w    0,0,0
  1543.         dc.w    0,0,0
  1544.         dc.w    0,0,0
  1545.         dc.w    0,0,0
  1546.         dc.w    0,0,0
  1547.         dc.w    0,0,0
  1548.         dc.w    0,0,0
  1549.         dc.w    0,0,0
  1550.         
  1551. *
  1552. *    Enter High Resolution 300 DPI Graphics Mode
  1553. *  
  1554. enter_graph    dc.b    5,ESC,'*','r','0','A'    * start raster graphics
  1555.  
  1556. *
  1557. *    Initialisation de l'imprimante!
  1558. *
  1559. width        dc.b    13,ESC,'E',ESC,38,108,50,54,65,ESC,38,108,48,76
  1560.  
  1561. *
  1562. *    Low DPI = 150 dpi used for NPLANES = 4 or draft mode
  1563. *
  1564. low_dpi        dc.b     12,ESC,'*','t','3','0','0','R',ESC,'*','o','1','Q'
  1565.  
  1566. *
  1567. *    High DPI = 300 dpi used for NPLANES = 1,2 or 3
  1568. *
  1569. high_dpi    dc.b     12,ESC,'*','t','3','0','0','R',ESC,'*','o','1','Q'
  1570.  
  1571. *
  1572. *    First part of escape sequence for number of planes to process
  1573. *
  1574. escape_r    dc.b    4,ESC,'*','r','-'
  1575.  
  1576. *
  1577. *    Part of escape sequence for color palette customizing.
  1578. * Ca sert plus a rien.
  1579. * rgb_escape    dc.b    1,' '
  1580.  
  1581. *
  1582. *    Transmission Mode - unencoded or 'run-length' encoded data
  1583. *
  1584. transmit_mode     dc.b    5,ESC,'*','b','1','M'    * run-length encoded
  1585.  
  1586. *
  1587. *    Send empty plane escape sequence
  1588. *
  1589.  
  1590. empty_plane    dc.b    5,ESC,'*','b','0','V'
  1591.  
  1592. *
  1593. *    Send empty plane escape sequence for last available color
  1594. *
  1595. last_empty    dc.b    5,ESC,'*','b','0','W'
  1596.  
  1597. *
  1598. *    Part of necessary transfer sequence for compression method #2
  1599. *
  1600. send_cnt    dc.b    3,ESC,'*','b'
  1601.  
  1602. *
  1603. *    End Graphics Mode 
  1604. end_graph    dc.b    5,ESC,'*','r','b','C'    * end raster graphics
  1605.  
  1606. *
  1607. *    Copy of ptr to current slice of the first plane in scan_out
  1608. *
  1609. plane_top    ds.l    1
  1610.  
  1611. *
  1612. *    Variable for checking if current plane is the last in multi-plane seq.
  1613. *
  1614. lastplane    ds.b    1
  1615.  
  1616. *
  1617. *    Printer Spacing Command
  1618. *
  1619. sized_lf    dc.b    3,ESC,'J'
  1620. slf_cnt        ds.b    1
  1621.  
  1622. _abort        dc.w    0    * abort flag
  1623. _handle        dc.w    0    * handle returned from open of aux port
  1624. chr_ad        dc.b    0    * byte to hold character
  1625. chr_ad1        dc.b    0    * second byte
  1626.  
  1627. *
  1628. *    Copy of num_colors to be used by 'C' routine
  1629. *
  1630. _num_colors    dc.w    1
  1631.  
  1632. *
  1633. *    Copy of num_planes to be used by 'C' routine
  1634. *
  1635. _num_planes     dc.w    1
  1636.  
  1637.         .end
  1638.