home *** CD-ROM | disk | FTP | other *** search
/ ftp.update.uu.se / ftp.update.uu.se.2014.03.zip / ftp.update.uu.se / pub / rainbow / msdos / decus / RB140 / grlib03a.arj / RWCELL.ASM < prev    next >
Assembly Source File  |  1988-12-08  |  12KB  |  518 lines

  1. TITLE RWCELL.ASM
  2. PAGE ,132
  3.  
  4. include asmc.h
  5.  
  6.     SEGEND  CODE
  7.     SEGDEF  DATA
  8. include asmd.h
  9.     SEGEND  DATA
  10.     SEGDEF  CODE
  11.  
  12.     PUBLIC    rd_cell
  13.     PUBLIC    wr_cell
  14.  
  15.     IF    @BIGMODEL
  16.     EXTRN    a_fgbg:FAR, a_alups:FAR, a_gbmsk:FAR, a_mode:FAR
  17.     EXTRN    cxy2cp:FAR, free:FAR, gdc_nb:FAR, malloc:FAR
  18.     ELSE
  19.     EXTRN    a_fgbg:NEAR, a_alups:NEAR, a_gbmsk:NEAR, a_mode:NEAR
  20.     EXTRN    cxy2cp:NEAR, free:NEAR, gdc_nb:NEAR, malloc:NEAR
  21.     ENDIF
  22.  
  23. ;******************************************************************************
  24. ;*                                                                            *
  25. ;*    F U N C T I O N   rd_cell(strctr)                          *
  26. ;*            struct g_cell *strctr;                      *
  27. ;*                                          *
  28. ;*    purpose:    Read one plane of the 'cell' (specified as 'bottom left'      *
  29. ;*        'top right') into an array. The structure will be filled      *
  30. ;*        in appropriately if successful and a value of '1' will be     *
  31. ;*        returned. If memory could not be allocated, a 'NULL' is          *
  32. ;*        returned.                              *
  33. ;*        'strctr' is defined in graph.h and is of the form:          *
  34. ;*                                          *
  35. ;*        struct g_cell {                              *
  36. ;*            int c_corner[4],                      *
  37. ;*                c_plane,                          *
  38. ;*                c_rows,                          *
  39. ;*                c_bytes;                          *
  40. ;*            unsigned char *c_segment,                  *
  41. ;*                      c_offset[];                  *
  42. ;*        };                                  *
  43. ;*                                          *
  44. ;*        Before calling rw_cell(), fill in the c_corner[] array with   *
  45. ;*        the bottom-right & top-left 'xy' co-ordinates and set c_plane *
  46. ;*        to the plane number you want to read. (0 to 1 or 3, depending *
  47. ;*        on high or medium resolution workstation type.)              *
  48. ;*        'c_segment' would not normally be used explicitly by the user *
  49. ;*        unless the whole bitmap needs to be read. If the function is  *
  50. ;*        called with 'c_segment' = 0, memory will be automatically     *
  51. ;*        requested and the current data seg will be used.          *
  52. ;*                                          *
  53. ;*    ******************************************************************    *
  54. ;*    *******    REMEMBER TO 'free(strctr->c_offset)' IT AFTERWARDS *******    *
  55. ;*    ******************************************************************    *
  56. ;*                                          *
  57. ;*        To set up an external area, use the msdos get memory function *
  58. ;*                                          *
  59. ;*        The bytes in the array at c_offset will be bit aligned.       *
  60. ;*        Any particular bit may then be accessed/changed eg.          *
  61. ;*                                          *
  62. ;*            r = strctr->c_rows - 1;                      *
  63. ;*            b = strctr->c_bytes;                      *
  64. ;*            strctr->c_offset[(r * b) + b] |= 128;              *
  65. ;*                                          *
  66. ;*        Will set the first bit in the last byte of the last row of    *
  67. ;*        the plane read, as long as the array is in your current data  *
  68. ;*        segment. If not, you will need to play around moving chunks   *
  69. ;*        into your DS, change it, then move it back again.          *
  70. ;*                                          *
  71. ;******************************************************************************
  72.  
  73. ;LOCAL READ SUBROUTINE
  74. Lrd_bytes PROC  NEAR
  75.     in    al,56H            ;byte ready to be read?
  76.         test    al,01H
  77.         jz      Lrd_bytes       ;jump if not.
  78.         in    al,57H            ;read the byte.
  79.         stosb
  80.         loop    Lrd_bytes
  81.     ret
  82. Lrd_bytes ENDP
  83.  
  84.  
  85.     PROCDEF rd_cell
  86.     push    si
  87.     push    di
  88.     push    bp
  89.     mov    bp,sp
  90.     sub    sp,8            ; -2[bp] alups reg.
  91.                     ; -4[bp] No. of pixels.
  92.                     ; -6[bp] No. of bytes per row.
  93.                     ; -8[bp] No. of rows.
  94.  
  95.     mov    ax,cs:eseg_sav    ;just in case!
  96.     mov    es,ax
  97.     cld                     ;make the coming stosb instruction increment di.
  98.     mov    si,WORD PTR 8[bp]    ;get pointer to the structure.
  99.     mov    ax,WORD PTR 4[si]    ;top right 'x'
  100.     sub    ax,WORD PTR [si]    ;minus bottom left 'x'
  101.     inc    ax            ;equals No. of pixels.
  102.     mov    WORD PTR -4[bp],ax
  103.     add    ax,7
  104.     mov    cl,3
  105.     shr    ax,cl            ;number of bytes in one array element.
  106.     mov    WORD PTR -6[bp],ax
  107.     mov    cx,ax
  108.     mov    ax,WORD PTR 6[si]    ;top right 'y'
  109.     sub    ax,WORD PTR 2[si]    ;minus bottom left 'y'
  110.     inc    ax            ;equals No. of rows.
  111.     mov    WORD PTR -8[bp],ax
  112.     mul    cx            ;bytes * rows.
  113.     cmp    WORD PTR 14[si],0000H    ;any segment defined ?
  114.     jnz    L2
  115.     push    si
  116.     push    ax
  117.     call    malloc            ;allocate space in our Data seg.
  118.     add    sp,2
  119.     pop    si
  120.     or    ax,ax            ;did it work ?
  121.     jnz    L1a
  122.     jmp    Lexit            ;quit on failure.
  123.  
  124. L1a:    mov    WORD PTR 16[si],ax    ;update the structure's c_offset
  125.     mov    ax,ds            ;and c_seg info.
  126.     mov    WORD PTR 14[si],ax
  127. L2:    mov    di,si            ;point DI to strctr.c_rows.
  128.     add    di,000AH
  129.     mov    ax,WORD PTR -8[bp]
  130.     stosw                ;number of rows.
  131.     mov    ax,WORD PTR -6[bp]
  132.     stosw                ;number of bytes per row.
  133.  
  134.     mov    al,alups        ;save old alups on the stack.
  135.     mov    WORD PTR -2[bp],ax
  136.     mov    alups,0fH        ;disable all writes.
  137.     call    gdc_nb
  138.     call    a_alups
  139.  
  140.     mov    ax,WORD PTR 8[si]    ;juggle mode for the specified plane.
  141.     and    al,3
  142.     shl    al,1
  143.     shl    al,1
  144.     and    gbmod,0a1H
  145.     or    gbmod,al
  146.     call    a_mode
  147.  
  148.     mov    ax,ymax        ;convert 'y' co-ord to top left origin.
  149.     sub    ax,WORD PTR 2[si]
  150.     mov    y_start,ax
  151.     mov    ax,WORD PTR [si]    ;set up the starting 'x' co-ordinate.
  152.     mov    bx,ax
  153.     and    ax,0fff0H        ;make 'x' a word address.
  154.     mov    x_start,ax
  155.  
  156.     mov    ax,bx            ;get 'x' address
  157.     and    ax,07H            ;x % 8
  158.     add    ax,WORD PTR -4[bp]    ;add the number of pixels.
  159.     add    ax,7            ;is last byte an odd address?
  160. Lrd1:    mov    cl,03H
  161.     shr    ax,cl
  162.     mov    cx,ax            ;CX = total bytes to read.
  163.  
  164.     mov    dl,0            ;if first byte is on an odd address
  165.     test    bl,08H            ; DL = 1 and we need to throw away the
  166.     jz    Lrd2            ; first byte read in.
  167.     inc    dl
  168.     inc    ax
  169. Lrd2:    test    al,01H            ;still an odd number of bytes ?
  170.     jz    Lrd3            ;jump if not.
  171.     inc    ax
  172. Lrd3:    shr    ax,1            ;AX = number of words to read.
  173.     mov    WORD PTR nmritl,ax
  174.  
  175.     mov    ax,WORD PTR [di]    ;get the es seg
  176.     mov    di,WORD PTR 2[di]    ;and offset.
  177. Lrd4:    push    dx
  178.     push    cx
  179.     push    di
  180.     push    ax
  181.  
  182.     call    cxy2cp
  183.         lea     di,gp_buff            ;DI register points to gp_buff_.
  184.  
  185.     mov    al,4aH                ;set all bits in gdc mask.
  186.         out    57H,al
  187.         mov    al,0ffH
  188.         out    56H,al
  189.         out    56H,al
  190.         mov    al,4cH            ;assert the figs command.
  191.         out    57H,al
  192.         mov    al,2            ;direction is to the right.
  193.         out    56H,al
  194.     mov    ax,WORD PTR nmritl
  195.         out    56H,al
  196.         mov    al,ah
  197.         out    56H,al
  198.         mov    al,0a0H            ;start the read operation now.
  199.         out    57H,al
  200.  
  201.     or    dl,dl            ;is first byte on an odd address ?
  202.     jz    Lrd5
  203.     push    cx            ;read first byte and throw it away.
  204.     mov    cx,1
  205.     call    Lrd_bytes
  206.     pop    cx
  207.     dec    di
  208. Lrd5:    call    Lrd_bytes
  209.  
  210.     pop    ax
  211.     mov    es,ax
  212.     pop    di
  213.     lea    si,gp_buff        ;point SI to the bytes read.
  214.     mov    ax,bx            ;'x' start
  215.     and    al,07
  216.     mov    cl,08
  217.     sub    cl,al
  218.     mov    dx,WORD PTR -6[BP]    ;get bytes/row
  219. Lrd6:    lodsw
  220.     xchg    ah,al
  221.     shr    ax,cl
  222.     stosb
  223.     dec    si
  224.     dec    dx
  225.     jnz    Lrd6
  226.  
  227.     push    es
  228.     mov    ax,ds
  229.     mov    es,ax
  230.     pop    ax
  231.     pop    cx
  232.     pop    dx
  233.     dec    WORD PTR -8[bp]        ;decrement 'row' count
  234.     jz    Lrd7
  235.     dec    y_start        ;point to next screen line.
  236.     jmp    Lrd4
  237.  
  238. Lrd7:    mov    al,6fH             ;send a 'do nothing' to turn the fifo round.
  239.     out    57H,al
  240.  
  241.     or    gbmod,10H    ;The following chunk of code is included
  242.     call    a_mode        ;because the GDC has a problem writing to
  243.     mov    al,4cH        ;the bitmap after a read sequence has been
  244.     out    57H,al        ;completed.
  245.     xor    al,al
  246.     out    56H,al
  247.     out    56H,al
  248.     out    56H,al
  249.     mov    al,22H
  250.     out    57H,al
  251.     mov    al,0ffH
  252.     out    56H,al
  253.     out    56H,al
  254.  
  255.     mov    ax,WORD PTR -2[bp]
  256.     mov    alups,al
  257.     call    gdc_nb
  258.     call    a_alups
  259.  
  260.     mov    ax,1
  261. Lexit:    mov    sp,bp
  262.     pop    bp
  263.     pop    di
  264.     pop    si
  265.         ret
  266.  
  267.     PROCEND rd_cell
  268. ;******************************************************************************
  269. ;*                                                                            *
  270. ;*    F U N C T I O N   wr_cell(strctr)                          *
  271. ;*            struct g_cell *strctr;                      *
  272. ;*                                          *
  273. ;******************************************************************************
  274.  
  275. ;LOCAL WRITE SUBROUTINE
  276. ; Enters with :    BX = number of bytes to write.
  277. ;        CH = number of bits displayed in left-hand byte.
  278. ;        DH = number of bits in the right-hand byte.
  279. ;        DL = 0 - first byte is EVEN, last byte is ODD.
  280. ;             1 - first byte is ODD.
  281. ;             2 - last byte is EVEN.
  282. ;             3 - first byte is ODD, last byte is EVEN.
  283.  
  284. Lwrite  PROC    NEAR
  285.     call    cxy2cp
  286.     lea    si,gp_buff
  287.     mov    ax,0ffffH
  288.     test    dl,01H            ;is first byte ODD ?
  289.     jnz    Lwr4            ;jump if it is.
  290.     inc    al            ;AX = 0xff00
  291. Lwr4:
  292.     xchg    cl,ch            ;make the left hand mask.
  293.     shl    ax,cl
  294.     mov    WORD PTR gbmskl,ax
  295.     mov    WORD PTR nmritl,0000H    ;one word to be written.
  296.     mov    cx,0002H         ;first bytes always on a word boundary.
  297.     sub    bx,cx
  298.     jnz    Lwr4b
  299.     push    bx
  300.     mov    bx,0ffffH
  301.     mov    cl,dh
  302.     test    dl,02H
  303.     jnz    Lwr4a
  304.     inc    bh
  305. Lwr4a:    shr    bx,cl
  306.     or    ax,bx
  307.     pop    bx
  308. Lwr4b:    mov    WORD PTR gbmskl,ax
  309.     call    Lrit
  310.     or    bx,bx
  311.     jnz    Lwr4c
  312.     ret
  313. Lwr4c:
  314.     mov    WORD PTR gbmskl,0000H    ;set mask and count for 'words'.
  315.     mov    WORD PTR nmritl,0007H
  316. Lwr5:                    ;Loop to write 16 bytes at a time.
  317.     mov    cx,0010H
  318.     sub    bx,cx
  319.     js    Lwr6
  320.     call    Lrit
  321.     jmp    Lwr5
  322. Lwr6:
  323.     add    bx,0010H
  324.     cmp    bx,02H
  325.     jz    Lwr8
  326.     sub    bx,02H
  327.  
  328.     mov    cl,bl
  329.     shr    bx,01
  330.     dec    bx
  331.     mov    WORD PTR nmritl,bx
  332.     call    Lrit
  333. Lwr8:                    ;Write the last byte[s].
  334.     mov    WORD PTR nmritl,0000H
  335.     mov    ax,0ffffH
  336.     mov    cl,dh
  337.     test    dl,02H
  338.     jnz    Lwr9
  339.     mov    ah,00H
  340. Lwr9:    shr    ax,cl
  341.     mov    WORD PTR gbmskl,ax
  342.     mov    cl,02H
  343.  
  344. Lrit:
  345.     call    gdc_nb
  346.     mov    al,0feH            ;select the write buffer.
  347.     out    53H,al
  348.     out    51H,al            ;zero the counter.
  349.  
  350. Lrit0:
  351.     lodsb
  352.     out    52H,al
  353.     loop    Lrit0
  354.  
  355.     mov    al,0feH            ;reset the counter to zero.
  356.     out    53H,al
  357.     out    51H,al
  358.  
  359.     call    a_gbmsk
  360.     mov    al,4aH            ;set the GDC mask to enable:
  361.     out    57H,al
  362.     mov    al,0FFH
  363.     out    56H,al
  364.     out    56H,al
  365.  
  366.         mov    al,4cH            ;assert the figs command.
  367.         out    57H,al
  368.         mov    al,02H            ;direction is to the right.
  369.         out    56H,al
  370.     mov    ax,WORD PTR nmritl    ;number of words to write.
  371.         out    56H,al
  372.     mov    al,ah
  373.         out    56H,al
  374.  
  375.     mov    al,22H            ;start the write operation now.
  376.     out    57H,al
  377.     mov    al,0ffH
  378.     out    56H,al
  379.     out    56H,al
  380.  
  381.     ret
  382. Lwrite  ENDP
  383.  
  384.     PROCDEF wr_cell
  385.     push    si
  386.     push    di
  387.     push    bp
  388.     mov    bp,sp
  389.     sub    sp,6            ; -2[bp] alups reg.
  390.                     ; -4[bp] number of rows.
  391.                     ; -6[bp] number of bytes per row.
  392.  
  393.     mov    ax,cs:eseg_sav        ;just in case!
  394.     mov    es,ax
  395.     cld                         ;make the coming stosb instruction
  396.                     ;increment di.
  397.     mov    al,alups        ;save old alups on the stack.
  398.     mov    WORD PTR -2[bp],ax
  399.  
  400.     mov    si,WORD PTR 8[bp]    ;get structure pointer.
  401.     mov    ax,ymax        ;convert 'y' co-ord to top left origin.
  402.     sub    ax,WORD PTR 2[si]
  403.     mov    y_start,ax
  404.     mov    ax,WORD PTR [si]    ;set up the starting 'x' co-ordinate.
  405.     mov    bx,ax
  406.     and    ax,0fff0H        ;make 'x' a word address.
  407.     mov    x_start,ax
  408.  
  409.     mov    dx,WORD PTR 4[si]
  410.     sub    dx,WORD PTR [si]    ;number of pixels to write.
  411.     inc    dx
  412.     mov    ax,bx
  413.     and    bx,000fH
  414.     add    bx,dx
  415.     push    dx
  416.     mov    cl,03H
  417.     test    bx,0007H
  418.     jz    Lw1
  419.     add    bx,0008H
  420. Lw1:    shr    bx,cl
  421.     test    bx,0001H
  422.     jz    Lw1a
  423.     inc    bx
  424. Lw1a:
  425.     mov    ch,al
  426.     xor    dl,dl
  427.     test    ch,08H
  428.     jz    Lw2
  429.     inc    dl
  430. Lw2:    and    ch,07H
  431.  
  432.     pop    di
  433.     add    ax,di
  434.     dec    ax
  435.     mov    dh,al
  436.     test    ax,08H
  437.     jnz    Lw3
  438.     or    dl,02H
  439. Lw3:    and    dh,07H
  440.     inc    dh
  441.     mov    cl,08H
  442.     sub    cl,ch
  443.     xchg    cl,ch
  444.  
  445.         add     si,0008H        ;SI register points to the stucture.
  446.     push    cx
  447.     mov    cx,WORD PTR [si]    ;get plane # and adjust alups to only
  448.     mov    al,01H            ; write to this one.
  449.     shl    al,cl
  450.     xor    al,0fH
  451.     and    BYTE PTR alups, 0F0H
  452.     or    alups,al
  453.     mov    fgbg,0FH        ;enable foreground writes.
  454.     call    gdc_nb
  455.     call    a_fgbg
  456.     call    a_alups
  457.     and    gbmod,0FDh        ;set mode to WORD writes.
  458.     or    gbmod,8H
  459.     call    a_mode
  460.     pop    cx
  461.  
  462.     mov    ax,WORD PTR 2[si]    ;number of rows.
  463.     mov    WORD PTR -4[bp],ax
  464.     mov    ax,WORD PTR 4[si]    ;bytes per row.
  465.     mov    WORD PTR -6[bp],ax
  466.     mov    si,WORD PTR 8[si]    ;array offset.
  467. Lw4:    push    si
  468.     lea    di,gp_buff    ;gp_buff will hold the word aligned bit pattern
  469.     test    dl,1
  470.     jz    Lw4a
  471.     inc    di
  472. Lw4a:    push    ds
  473.     push    bx
  474.     mov    bx,WORD PTR 8[bp]
  475.     mov    ax,WORD PTR 14[bx]
  476.     mov    ds,ax
  477.     pop    bx
  478.     push    bx
  479. Lw5:                ;loop to bit align 'array' on a word boundary
  480.     lodsb            ;at gp_buff.
  481.     ror    ax,cl
  482.     stosb
  483.     xchg    cl,ch
  484.     ror    ax,cl
  485.     xchg    cl,ch
  486.     dec    bx
  487.     jnz    Lw5
  488.     pop    bx
  489.     pop    ds
  490.  
  491.     push    bx
  492.     push    cx
  493.     call    Lwrite        ;WRITE one line.
  494.     pop    cx
  495.     pop    bx
  496.     pop    si
  497.     add    si,WORD PTR -6[bp]
  498.  
  499.     dec    WORD PTR -4[bp]
  500.     jz    Lw6
  501.     dec    y_start
  502.     jmp    Lw4
  503. Lw6:
  504.     mov    ax,WORD PTR -2[bp]
  505.     mov    alups,al
  506.     call    gdc_nb
  507.     call    a_alups
  508.  
  509.     mov    sp,bp
  510.     pop    bp
  511.     pop    di
  512.     pop    si
  513.         ret
  514.     PROCEND wr_cell
  515. include epilogue.h
  516.     END
  517. 
  518.