Annotation of ntddk/src/video/displays/vga/i386/vgastrps.asm, revision 1.1.1.1

1.1       root        1: ;---------------------------Module-Header------------------------------;
                      2: ; Module Name: vgastrps.asm
                      3: ;
                      4: ; Routines used by line code to draw strips of pixels.
                      5: ;
                      6: ; Copyright (c) 1992 Microsoft Corporation
                      7: ;-----------------------------------------------------------------------;
                      8: 
                      9:         .386
                     10: 
                     11:         .model  small,c
                     12: 
                     13:         assume cs:FLAT,ds:FLAT,es:FLAT,ss:FLAT
                     14:         assume fs:nothing,gs:nothing
                     15: 
                     16: ; Set LOOP_UNROLL_SHIFT to the log2 of the number of times you want loops in
                     17: ; this module unrolled. For example, LOOP_UNROLL_SHIFT of 3 yields 2**3 = 8
                     18: ; times unrolling. This is the only thing you need to change to control
                     19: ; unrolling.
                     20: 
                     21: LOOP_UNROLL_SHIFT equ 2
                     22: 
                     23:         .xlist
                     24:         include stdcall.inc             ;calling convention cmacros
                     25:         include i386\egavga.inc
                     26:         include i386\strucs.inc
                     27:         include i386\lines.inc
                     28:         include i386\unroll.inc
                     29:         .list
                     30: 
                     31:         .code
                     32: 
                     33: _TEXT$04   SEGMENT DWORD USE32 PUBLIC 'CODE'
                     34:            ASSUME  CS:FLAT, DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
                     35: 
                     36: ;---------------------------Public-Routine------------------------------;
                     37: ; vSetStrips
                     38: ;
                     39: ; Set the VGA into the appropriate mode for line drawing.
                     40: ;
                     41: ;-----------------------------------------------------------------------;
                     42: 
                     43: cProc   vSetStrips,8,<     \
                     44:         clr:    dword,     \
                     45:         mode:   dword      >
                     46: 
                     47:         mov     edx, VGA_BASE + GRAF_ADDR
                     48: 
                     49:         mov     al, GRAF_SET_RESET
                     50:         mov     ah, byte ptr clr
                     51:         out     dx, ax
                     52: 
                     53:         cmp     mode, DR_SET
                     54:         je      @F
                     55: 
                     56:         mov     al, GRAF_DATA_ROT
                     57:         mov     ah, byte ptr mode
                     58:         out     dx, ax
                     59: 
                     60: @@:
                     61:        mov     eax, GRAF_MODE + ((M_AND_WRITE + M_COLOR_READ) SHL 8)
                     62:        out     dx, ax                  ;write mode 3 so we can do the masking
                     63:                                        ; without OUTs, read mode 1 so we can
                     64:                                        ; read 0xFF from memory always, for
                     65:                                        ; ANDing (because Color Don't Care is
                     66:                                        ; all zeros)
                     67:         cRet    vSetStrips
                     68: 
                     69: endProc vSetStrips
                     70: 
                     71: ;---------------------------Public-Routine------------------------------;
                     72: ; vClearStrips
                     73: ;
                     74: ; Restore the VGA to its default state.
                     75: ;
                     76: ;-----------------------------------------------------------------------;
                     77: 
                     78: cProc   vClearStrips,4,< \
                     79:         oldmode: dword   >
                     80: 
                     81: ; Restore the EGA/VGA to its default state:
                     82: 
                     83:         mov     edx, VGA_BASE + GRAF_ADDR
                     84: 
                     85:         cmp     oldmode, DR_SET
                     86:         je      @F
                     87:         mov     eax, (DR_SET shl 8) + GRAF_DATA_ROT
                     88:         out     dx, ax
                     89: 
                     90: @@:
                     91:        mov     eax, GRAF_MODE + ((M_PROC_WRITE + M_DATA_READ) SHL 8)
                     92:        out     dx, ax                  ;restore read mode 0 and write mode 0
                     93: 
                     94:         cRet    vClearStrips
                     95: 
                     96: endProc vClearStrips
                     97: 
                     98: ;--------------------------Private-Routine------------------------------;
                     99: ; vStripSolidDiagonalHorizontal
                    100: ;
                    101: ;   Draw an x-major near-diagonal strip left-to-right
                    102: ;
                    103: ;-----------------------------------------------------------------------;
                    104: 
                    105: cProc   vStripSolidDiagonalHorizontal,12,< \
                    106:         uses        esi edi ebx,   \
                    107:         pStrips:    ptr STRIPS,    \
                    108:         pls:        ptr LINESTATE, \
                    109:         plStripEnd: ptr >
                    110: 
                    111:         mov     esi, pStrips
                    112:         push    ebp
                    113:         mov     ebp, plStripEnd
                    114:         mov     ecx, [esi].ST_lNextScan
                    115:         mov     al,  [esi].ST_jBitMask
                    116:         mov     edi, [esi].ST_pjScreen
                    117:         add     esi, offset ST_alStrips
                    118: 
                    119: ;                   al  = bit mask
                    120: ;                   ebx = pixel count
                    121: ;                   ecx = delta
                    122: ;                   edx = port #
                    123: ;                   esi = strip pointer
                    124: ;                   edi = memory pointer
                    125: ;                   ebp = end of strips pointer
                    126: 
                    127: next_diagonal:
                    128:         mov     ebx, [esi]
                    129:         add     esi, 4
                    130: 
                    131:         align   4
                    132: diagonal_loop:
                    133:         and     [edi], al
                    134:         ror     al, 1
                    135:         adc     edi, ecx
                    136:         dec     ebx
                    137:         jnz     short diagonal_loop
                    138: 
                    139:         sub     edi, ecx                        ; side step
                    140:         cmp     esi, ebp
                    141:         jl      short next_diagonal
                    142: 
                    143:         pop     ebp
                    144:         mov     esi, pStrips
                    145:         mov     [esi].ST_pjScreen, edi
                    146:         mov     [esi].ST_jBitmask, al
                    147:         cRet    vStripSolidDiagonalHorizontal
                    148: 
                    149: endProc vStripSolidDiagonalHorizontal
                    150: 
                    151: ;--------------------------Private-Routine------------------------------;
                    152: ; vStripSolidDiagonalVertical
                    153: ;
                    154: ;   Draw a y-major near-diagonal strip left-to-right
                    155: ;
                    156: ;-----------------------------------------------------------------------;
                    157: 
                    158: cProc   vStripSolidDiagonalVertical,12,< \
                    159:         uses        esi edi ebx,   \
                    160:         pStrips:    ptr STRIPS,    \
                    161:         pls:        ptr LINESTATE, \
                    162:         plStripEnd: ptr >
                    163: 
                    164:         mov     esi, pStrips
                    165:         push    ebp
                    166:         mov     ebp, plStripEnd
                    167:         mov     ecx, [esi].ST_lNextScan
                    168:         mov     al,  [esi].ST_jBitMask
                    169:         mov     edi, [esi].ST_pjScreen
                    170:         add     esi, offset ST_alStrips
                    171: 
                    172: ;                   al  = bit mask
                    173: ;                   ebx = pixel count
                    174: ;                   ecx = delta
                    175: ;                   edx = port #
                    176: ;                   esi = strip pointer
                    177: ;                   edi = memory pointer
                    178: ;                   ebp = end of strips pointer
                    179: 
                    180: next_diagonal:
                    181:         mov     ebx, [esi]
                    182:         add     esi, 4
                    183: 
                    184:         align   4
                    185: diagonal_loop:
                    186:         and      [edi], al
                    187:         ror     al, 1
                    188:         adc     edi, ecx
                    189:         dec     ebx
                    190:         jnz     short diagonal_loop
                    191: 
                    192:         rol     al, 1                           ; side step
                    193:         sbb     edi, 0
                    194:         cmp     esi, ebp
                    195:         jl      short next_diagonal
                    196: 
                    197:         pop     ebp
                    198:         mov     esi, pStrips
                    199:         mov     [esi].ST_pjScreen, edi
                    200:         mov     [esi].ST_jBitmask, al
                    201:         cRet    vStripSolidDiagonalVertical
                    202: 
                    203: endProc vStripSolidDiagonalVertical
                    204: 
                    205: ;--------------------------Private-Routine------------------------------;
                    206: ; vStripSolidHorizontal
                    207: ;
                    208: ;   Draw a horizontal strip left to right
                    209: ;
                    210: ;-----------------------------------------------------------------------;
                    211: 
                    212: cProc   vStripSolidHorizontal,12,< \
                    213:         uses        esi edi ebx,   \
                    214:         pStrips:    ptr STRIPS,    \
                    215:         pls:        ptr LINESTATE, \
                    216:         plStripEnd: ptr >
                    217: 
                    218: ; Do some initializing:
                    219: 
                    220:         mov     esi, pStrips
                    221:         push    ebp
                    222:         mov     ebp, plStripEnd
                    223:         mov     edx, [esi].ST_lNextScan
                    224:         mov     al,  [esi].ST_jBitMask
                    225:         mov     edi, [esi].ST_pjScreen
                    226:         add     esi, offset ST_alStrips
                    227: 
                    228: ;       (al)  = rotating bit
                    229: ;       (bl)  = current mask
                    230: ;       (ecx) = pixel count
                    231: ;       (edx) = delta
                    232: ;       (esi) = strip pointer
                    233: ;       (edi) = display pointer
                    234: ;       (ebp) = end of strips pointer
                    235: 
                    236: next_horizontal:
                    237:         mov     ecx, [esi]
                    238:         add     esi, 4
                    239: 
                    240:         lea     ebx, [2 * eax - 1]      ; bl = start mask
                    241:         ror     al, cl                  ; rotate bit
                    242:         shr     ecx, 3                  ; compute # bytes to lay down
                    243:         cmp     bl, al                  ; we have to adjust for wrap
                    244:         adc     ecx, 0
                    245:         jnz     short extends_out_of_first_byte
                    246: 
                    247:         sub     bl, al                  ; zero out end bits
                    248:         sub     bl, al
                    249:         inc     bl
                    250:         and     [edi], bl               ; write result
                    251:         add     edi, edx                ; increment to next scan
                    252:         cmp     esi, ebp                ; see if done strips
                    253:         jb      short next_horizontal
                    254: 
                    255:         pop     ebp                     ; we're done
                    256:         mov     esi, pStrips
                    257:         mov     [esi].ST_pjScreen, edi
                    258:         mov     [esi].ST_jBitmask, al
                    259:         cRet    vStripSolidHorizontal
                    260: 
                    261: extends_out_of_first_byte:
                    262: 
                    263: ; This part gets called when the current strip doesn't fit entirely
                    264: ; into one byte:
                    265: 
                    266:         and     [edi], bl               ; output with start mask
                    267:         inc     edi                     ; go on to next byte
                    268: 
                    269:         dec     ecx                     ; see if there's any bytes in
                    270:         jnz     short output_bunch      ;    between start and end byte
                    271: 
                    272: last_byte:
                    273:         lea     ebx, [2 * eax - 1]      ; compute end mask
                    274:         not     bl
                    275:         and     [edi], bl               ; write result
                    276:         add     edi, edx                ; increment to next scan
                    277:         cmp     esi, ebp                ; see if done strips
                    278:         jb      short next_horizontal
                    279: 
                    280:         pop     ebp                     ; we're done
                    281:         mov     esi, pStrips
                    282:         mov     [esi].ST_pjScreen, edi
                    283:         mov     [esi].ST_jBitmask, al
                    284:         cRet    vStripSolidHorizontal
                    285: 
                    286: output_bunch:
                    287: 
                    288: ; We have a bunch of complete bytes to lay down.
                    289: 
                    290:         mov     ebx, esi                ; we're gonna overwrite esi
                    291:         mov     esi, edi
                    292:         rep     movsb                   ; Write the bytes.  Mask is 0ffh because
                    293:                                         ; we're in read mode 1, reading 0ffh,
                    294:                                         ; which becomes the write mode 3 mask.
                    295: 
                    296:         mov     esi, ebx                ; restore esi
                    297: 
                    298:         jmp     short last_byte         ; do last byte in scan
                    299: 
                    300: endProc vStripSolidHorizontal
                    301: 
                    302: ;--------------------------Private-Routine------------------------------;
                    303: ; vStripSolidHorizontalSet
                    304: ;
                    305: ;   Draw horizontal strips left to right for SRCCOPY lines.
                    306: ;
                    307: ;-----------------------------------------------------------------------;
                    308: 
                    309: cProc   vStripSolidHorizontalSet,12,< \
                    310:         uses        esi edi ebx,   \
                    311:         pStrips:    ptr STRIPS,    \
                    312:         pls:        ptr LINESTATE, \
                    313:         plStripEnd: ptr >
                    314: 
                    315: ; Do some initializing:
                    316: 
                    317:         mov     esi, pStrips
                    318:         push    ebp
                    319:         mov     ebp, plStripEnd
                    320:         mov     edx, [esi].ST_lNextScan
                    321:         mov     al,  [esi].ST_jBitMask
                    322:         mov     edi, [esi].ST_pjScreen
                    323:         add     esi, offset ST_alStrips
                    324: 
                    325: ;       (al)  = rotating bit
                    326: ;       (bl)  = current mask
                    327: ;       (ecx) = pixel count
                    328: ;       (edx) = delta
                    329: ;       (esi) = strip pointer
                    330: ;       (edi) = display pointer
                    331: ;       (ebp) = end of strips pointer
                    332: 
                    333: next_horizontal:
                    334:         mov     ecx, [esi]
                    335:         add     esi, 4
                    336: 
                    337:         lea     ebx, [2 * eax - 1]      ; bl = start mask
                    338:         ror     al, cl                  ; rotate bit
                    339:         shr     ecx, 3                  ; compute # bytes to lay down
                    340:         cmp     bl, al                  ; we have to adjust for wrap
                    341:         adc     ecx, 0
                    342:         jnz     short extends_out_of_first_byte
                    343: 
                    344:         sub     bl, al                  ; zero out end bits
                    345:         sub     bl, al
                    346:         inc     bl
                    347:         and     [edi], bl               ; write result
                    348:         add     edi, edx                ; increment to next scan
                    349:         cmp     esi, ebp                ; see if done strips
                    350:         jb      short next_horizontal
                    351: 
                    352:         pop     ebp                     ; we're done
                    353:         mov     esi, pStrips
                    354:         mov     [esi].ST_pjScreen, edi
                    355:         mov     [esi].ST_jBitmask, al
                    356:         cRet    vStripSolidHorizontalSet
                    357: 
                    358: extends_out_of_first_byte:
                    359: 
                    360: ; This part gets called when the current strip doesn't fit entirely
                    361: ; into one byte:
                    362: 
                    363:         and     [edi], bl               ; output with start mask
                    364:         inc     edi                     ; go on to next byte
                    365: 
                    366:         dec     ecx                     ; see if there's any bytes in
                    367:         jnz     short output_bunch      ;    between start and end byte
                    368: 
                    369: last_byte:
                    370:         lea     ebx, [2 * eax - 1]      ; compute end mask
                    371:         not     bl
                    372:         and     [edi], bl               ; write result
                    373:         add     edi, edx                ; increment to next scan
                    374:         cmp     esi, ebp                ; see if done strips
                    375:         jb      short next_horizontal
                    376: 
                    377:         pop     ebp                     ; we're done
                    378:         mov     esi, pStrips
                    379:         mov     [esi].ST_pjScreen, edi
                    380:         mov     [esi].ST_jBitmask, al
                    381:         cRet    vStripSolidHorizontalSet
                    382: 
                    383: output_bunch:
                    384: 
                    385: ; We have a bunch of complete bytes to lay down.  Since we're doing
                    386: ; the interior of the line and we have a SRCCOPY ROP, we don't have
                    387: ; to worry about loading the latches properly, so we can do this
                    388: ; without reading the VGA memory.  We also use 16 bit writes since
                    389: ; on some devices it's faster to write a single word than to write
                    390: ; two bytes -- doing so means we must be word-aligned.
                    391: 
                    392:         test    edi, 1
                    393:         jz      now_aligned
                    394:         mov     byte ptr [edi], 0ffh    ; write a byte to get alignment right
                    395:         inc     edi
                    396:         dec     ecx
                    397:         jz      short last_byte         ; maybe that was only byte we had to do
                    398: 
                    399: now_aligned:
                    400:         shr     ecx, 1                  ; divide by 2 to determine the number
                    401:                                         ; of words to write
                    402:                                         ; NOTE: We check the carry later on!
                    403: 
                    404:         jz      short last_byte_in_bunch ; small optimization: skip word stuff
                    405:                                          ; if we've only got a single byte
                    406: 
                    407:         mov     ebx, eax                ; save eax
                    408:         mov     eax, 0ffffh             ; prepare ax
                    409:         rep     stosw                   ; lay those words down
                    410:         mov     eax, ebx                ; restore eax
                    411:         jnc     short last_byte         ; NOTE: NOW we're checking the carry!
                    412: 
                    413: last_byte_in_bunch:
                    414:         mov     byte ptr [edi], 0ffh    ; write that last byte
                    415:         inc     edi
                    416:         jmp     short last_byte
                    417: 
                    418: endProc vStripSolidHorizontalSet
                    419: 
                    420: 
                    421: ;--------------------------Private-Routine------------------------------;
                    422: ; vStripSolidVertical
                    423: ;
                    424: ;   Draw a vertical strip left to right
                    425: ;
                    426: ;-----------------------------------------------------------------------;
                    427: 
                    428: cProc   vStripSolidVertical,12,<   \
                    429:         uses        esi edi ebx,   \
                    430:         pStrips:    ptr STRIPS,    \
                    431:         pls:        ptr LINESTATE, \
                    432:         plStripEnd: ptr >
                    433: 
                    434: ; So some initialization:
                    435: 
                    436:         mov     esi, pStrips
                    437:         mov     edx, plStripEnd
                    438:         mov     ecx, [esi].ST_lNextScan
                    439:         mov     al,  [esi].ST_jBitmask
                    440:         mov     edi, [esi].ST_pjScreen
                    441:         add     esi, offset ST_alStrips
                    442:         mov     [edx], ebp              ; save ebp
                    443: 
                    444:         align   4
                    445: next_vertical:
                    446:         mov     ebx, [esi]              ; ebx = # bits to set
                    447:         add     esi, 4
                    448: 
                    449:         SET_UP_UNROLL_VARS ebx,ebp,ebx,pfnWriteVerticalStripEntry, \
                    450:                                 LOOP_UNROLL_SHIFT
                    451:         jmp     ebp
                    452: 
                    453: ; Table of entry points for writing a vertical strip scan:
                    454: 
                    455:         UNROLL_LOOP_ENTRY_TABLE pfnWriteVerticalStripEntry,VERTICAL_STRIP, \
                    456:                                 LOOP_UNROLL_COUNT
                    457: 
                    458: ; Unrolled loop for writing a single vertical strip scan:
                    459: 
                    460: WRITE_VERTICAL_STRIP macro ENTRY_LABEL,ENTRY_INDEX
                    461: &ENTRY_LABEL&ENTRY_INDEX&:
                    462:         and     [edi], al               ; write the byte
                    463:         add     edi, ecx                ; go to next scan
                    464:         endm    ;-----------------------------;
                    465: 
                    466:         align   4
                    467: vertical_strip_loop:
                    468: 
                    469: ; Now we're going to paste the bytes to the screen.
                    470: ;
                    471: ;       (al)  = rotating bit
                    472: ;       (ebx) = # of complete unrolled loops to do
                    473: ;       (ecx) = minor add
                    474: ;       (edx) = end of strips pointer
                    475: ;       (esi) = strip pointer
                    476: ;       (edi) = address of byte to write
                    477: ;       (ebp) = garbage
                    478: 
                    479:         UNROLL_LOOP WRITE_VERTICAL_STRIP,VERTICAL_STRIP,LOOP_UNROLL_COUNT
                    480:         dec     ebx
                    481:         jnz     vertical_strip_loop
                    482: 
                    483: ; Adjust address and rotating bit for sidestep:
                    484: 
                    485:         ror     al, 1                   ; one to the right
                    486:         adc     edi, 0
                    487: 
                    488:         cmp     esi, edx
                    489:         jl      short next_vertical     ; hit end of array?
                    490: 
                    491: ; Remember where we left off, for next time:
                    492: 
                    493:         mov     ebp, [edx]              ; restore ebp
                    494:         mov     esi, pStrips
                    495:         mov     [esi].ST_pjScreen, edi
                    496:         mov     [esi].ST_jBitmask, al
                    497:         cRet    vStripSolidVertical
                    498: 
                    499: endProc vStripSolidVertical
                    500: 
                    501: ;--------------------------Private-Routine------------------------------;
                    502: ; vStripStyledHorizontal
                    503: ;
                    504: ;   Draws an arbitrarily styled horizontal strip left-to-right.
                    505: ;
                    506: ;-----------------------------------------------------------------------;
                    507: 
                    508: cProc   vStripStyledHorizontal,12,< \
                    509:         uses        esi edi ebx,    \
                    510:         pStrips:    ptr STRIPS,     \
                    511:         pls:        ptr LINESTATE,  \
                    512:         plStripEnd: ptr >
                    513: 
                    514:         local   aEnd:dword              ; end of length array
                    515:         local   minoradd:dword
                    516:         local   spToGo:dword
                    517: 
                    518: ; So some initialization:
                    519: 
                    520:         mov     esi, pStrips
                    521:         mov     eax, plStripEnd
                    522:         mov     aEnd, eax
                    523: 
                    524:         mov     eax, [esi].ST_lNextScan
                    525:         mov     bl,  [esi].ST_jBitmask
                    526:         mov     edi, [esi].ST_pjScreen
                    527:         mov     minoradd, eax
                    528: 
                    529: ; Initialize styling:
                    530: 
                    531:         mov     eax, [esi].ST_spRemaining
                    532:         mov     bh,  [esi].ST_jStyleMask
                    533:         mov     spToGo, eax
                    534:         add     esi, offset ST_alStrips
                    535: 
                    536: Strip_loop:
                    537:         mov     ecx, [esi]              ; ecx = # bits to write
                    538:         add     esi, 4
                    539: 
                    540: ; Now we're going to paste the bytes to the screen
                    541: ;
                    542: ;       (al)  = used to accumulate the mask
                    543: ;       (bl)  = rotating bit
                    544: ;       (bh)  = jStyleMask
                    545: ;       (ecx) = # of bits to write
                    546: ;       (edx) =
                    547: ;       (esi) = ptr to spot in ST_alStrips
                    548: ;       (edi) = address of byte to write
                    549: 
                    550:         xor     al, al                  ; clear style mask
                    551: 
                    552: Strip_count:
                    553:         xor     al, bh                  ; set bit in output mask if style bit 0
                    554:         or      al, bl
                    555:         xor     al, bh
                    556: 
                    557:         dec     spToGo
                    558:         jz      short Next_style_entry
                    559: 
                    560: Next_bit:
                    561:         ror     bl, 1
                    562:         jc      short Output_byte
                    563:         dec     ecx
                    564:         jnz     short Strip_count
                    565: 
                    566: ; Do sidestep
                    567: 
                    568: Side_step:
                    569:         and     byte ptr [edi], al
                    570:         add     edi, minoradd
                    571: 
                    572:         cmp     esi, aEnd
                    573:         jl      short Strip_loop
                    574: 
                    575:        mov     esi, pStrips
                    576:        mov     [esi].ST_pjScreen, edi
                    577:        mov     [esi].ST_jBitmask, bl
                    578:         mov     [esi].ST_jStyleMask, bh
                    579:         mov     eax, spToGo
                    580:         mov     [esi].ST_spRemaining, eax
                    581: 
                    582:        cRet    vStripStyledHorizontal
                    583: 
                    584: Output_byte:
                    585:         and     byte ptr [edi], al
                    586:         xor     al, al
                    587:         inc     edi                     ; Moved one byte to right on screen
                    588:         dec     ecx
                    589:         jnz     short Strip_count
                    590:         jz      short Side_step
                    591: 
                    592: ; We're on to a new entry in the style array:
                    593: 
                    594: Next_style_entry:
                    595:         push    eax
                    596:         mov     edx, pStrips
                    597:        mov     eax, [edx].ST_psp
                    598:         add     eax, 4
                    599:        cmp     [edx].ST_pspEnd, eax
                    600:         jae     short @F
                    601:        mov     eax, [edx].ST_pspStart  ; Go back to start of array
                    602: @@:
                    603:        mov     [edx].ST_psp, eax
                    604:         mov     edx, [eax]              ; Load up new style entry
                    605: 
                    606:         add     spToGo, edx
                    607:         not     bh                      ; jStyleMask = !jStyleMask
                    608: 
                    609:         pop     eax
                    610:         jmp     short Next_bit
                    611: 
                    612: endProc vStripStyledHorizontal
                    613: 
                    614: 
                    615: ;--------------------------Private-Routine------------------------------;
                    616: ; vStripStyledVertical
                    617: ;
                    618: ;   Draw an arbitrarily styled vertical strip left-to-right.
                    619: ;
                    620: ;-----------------------------------------------------------------------;
                    621: 
                    622: cProc   vStripStyledVertical,12,<  \
                    623:         uses        esi edi ebx,   \
                    624:         pStrips:    ptr STRIPS,    \
                    625:         pls:        ptr LINESTATE, \
                    626:         plStripEnd: ptr >
                    627: 
                    628:         local   aEnd:dword              ; end of length array
                    629:         local   minoradd:dword
                    630:         local   spToGo:dword
                    631: 
                    632: ; So some initialization:
                    633: 
                    634:         mov     esi, pStrips
                    635:         mov     eax, plStripEnd
                    636:         mov     aEnd, eax
                    637: 
                    638:         mov     ecx, [esi].ST_lNextScan
                    639:         mov     al,  [esi].ST_jBitmask
                    640:         mov     edi, [esi].ST_pjScreen
                    641:         mov     minoradd, ecx
                    642: 
                    643: ; Initialize styling:
                    644: 
                    645:         mov     ebx, [esi].ST_spRemaining
                    646:         mov     ah,  [esi].ST_jStyleMask
                    647:         mov     spToGo, ebx
                    648:         add     esi, offset ST_alStrips
                    649: 
                    650: Strip_loop:
                    651:         mov     ebx, [esi]              ; ebx = # bits to set
                    652:         add     esi, 4
                    653: 
                    654: ; Now we're going to paste the bytes to the screen
                    655: ;
                    656: ;       (al)  = rotating bit
                    657: ;       (ah)  = jStyleMask
                    658: ;       (ebx) = # of bits to write
                    659: ;       (ecx) = minor add
                    660: ;       (edx) =
                    661: ;       (esi) = ptr to spot in ST_alStrips
                    662: ;       (edi) = address of byte to write
                    663: 
                    664: Strip_count:
                    665:         or      ah, ah
                    666:         jnz     short @F                ; Don't output pixel if in a gap
                    667:         and     [edi], al
                    668: @@:
                    669:         dec     spToGo
                    670:         jz      short Next_style_entry
                    671: 
                    672: Minor_add:
                    673:        add     edi, ecx
                    674:        dec     ebx
                    675:        jnz     short Strip_count
                    676: 
                    677: ; Adjust address and rotating bit for sidestep
                    678: 
                    679:         ror     al, 1                   ; one to the right
                    680:         adc     edi, 0
                    681: 
                    682:         cmp     esi, aEnd
                    683:         jl      short Strip_loop        ; hit end of array?
                    684: 
                    685:        mov     esi, pStrips
                    686:        mov     [esi].ST_pjScreen, edi
                    687:        mov     [esi].ST_jBitmask, al
                    688:         mov     [esi].ST_jStyleMask, ah
                    689:         mov     eax, spToGo
                    690:         mov     [esi].ST_spRemaining, eax
                    691: 
                    692:        cRet    vStripStyledVertical
                    693: 
                    694: Next_style_entry:
                    695:         mov     edx, pStrips
                    696:        mov     ecx, [edx].ST_psp
                    697:         add     ecx, 4
                    698:        cmp     [edx].ST_pspEnd, ecx
                    699:         jae     short @F
                    700:        mov     ecx, [edx].ST_pspStart  ; Go back to start of array
                    701: @@:
                    702:        mov     [edx].ST_psp, ecx       ; Save our pointer
                    703:         mov     edx, [ecx]              ; Load up new style entry
                    704:         add     spToGo, edx
                    705:         not     ah                      ; jStyleMask = !jStyleMask
                    706: 
                    707: ; Restore the registers we used:
                    708: 
                    709:         mov     ecx, minoradd
                    710:         jmp     short Minor_add
                    711: 
                    712: endProc vStripStyledVertical
                    713: 
                    714: 
                    715: ;--------------------------Private-Routine------------------------------;
                    716: ; vStripMaskedHorizontal
                    717: ;
                    718: ;   Draws a mask-styled horizontal strip left to right.
                    719: ;
                    720: ;-----------------------------------------------------------------------;
                    721: 
                    722: cProc   vStripMaskedHorizontal,12,< \
                    723:         uses        esi edi ebx,    \
                    724:         pStrips:    ptr STRIPS,     \
                    725:         pls:        ptr LINESTATE,  \
                    726:         plStripEnd: ptr >
                    727: 
                    728:         local   aEnd:dword              ; end of length array
                    729:         local   minoradd:dword
                    730:         local   density:dword
                    731: 
                    732: ; So some initialization:
                    733: 
                    734:         mov     esi, pStrips
                    735:         mov     eax, plStripEnd
                    736:         mov     aEnd, eax
                    737:         mov     eax, [esi].ST_lNextScan
                    738:         mov     bl,  [esi].ST_jBitmask
                    739:         mov     edi, [esi].ST_pjScreen
                    740:         mov     minoradd, eax
                    741: 
                    742: ; Initialize styling:
                    743: 
                    744:         mov     ecx,          [esi].ST_xyDensity
                    745:         mov     ah,  byte ptr [esi].ST_spRemaining
                    746:         mov     bh,           [esi].ST_jStyleMask
                    747:         mov     density, ecx
                    748:         add     esi, offset ST_alStrips
                    749: 
                    750: Strip_loop:
                    751:         mov     ecx, [esi]              ; ecx = # bits to write
                    752:         add     esi, 4
                    753: 
                    754: ; Now we're going to paste the bytes to the screen
                    755: ;
                    756: ;       (al)  = used to accumulate style mask
                    757: ;       (ah)  = # pixels left in style
                    758: ;       (bl)  = rotating bit
                    759: ;       (bh)  = style mask
                    760: ;       (ecx) = # of bits to write
                    761: ;       (esi) = ptr to spot in ST_alStrips
                    762: ;       (edi) = address of byte to write
                    763: 
                    764:         xor     al, al                  ; clear output mask
                    765: 
                    766: Strip_count:
                    767:         xor     al, bh                  ; set bit in output mask if style bit 0
                    768:         or      al, bl
                    769:         xor     al, bh
                    770: 
                    771:         dec     ah
                    772:         jnz     short @F
                    773:         rol     bh, 1
                    774:         mov     ah, byte ptr density
                    775: @@:     ror     bh, 1
                    776:         ror     bl, 1
                    777:         jc      short Output_byte
                    778:         dec     ecx
                    779:         jnz     short Strip_count
                    780: 
                    781: ; Do sidestep
                    782: 
                    783: Side_step:
                    784:         and     byte ptr [edi], al
                    785:         add     edi, minoradd
                    786: 
                    787:         cmp     esi, aEnd
                    788:         jl      short Strip_loop
                    789: 
                    790:         mov     esi, pStrips
                    791: 
                    792:         mov              [esi].ST_pjScreen, edi
                    793:         mov              [esi].ST_jBitmask, bl
                    794:         mov              [esi].ST_jStyleMask, bh
                    795:         mov     byte ptr [esi].ST_spRemaining, ah
                    796: 
                    797:         cRet    vStripMaskedHorizontal
                    798: 
                    799: Output_byte:
                    800:         and     byte ptr [edi], al
                    801:         xor     al, al
                    802:         inc     edi
                    803:         dec     ecx
                    804:         jnz     short Strip_count
                    805:         jz      short Side_step
                    806: 
                    807: endProc vStripMaskedHorizontal
                    808: 
                    809: ;--------------------------Private-Routine------------------------------;
                    810: ; vStripMaskedVertical
                    811: ;
                    812: ;   Draw a mask-styled vertical strip left to right.
                    813: ;
                    814: ;-----------------------------------------------------------------------;
                    815: 
                    816: cProc   vStripMaskedVertical,12,<  \
                    817:         uses        esi edi ebx,   \
                    818:         pStrips:    ptr STRIPS,    \
                    819:         pls:        ptr LINESTATE, \
                    820:         plStripEnd: ptr >
                    821: 
                    822:         local   aEnd:dword              ; end of length array
                    823:         local   minoradd:dword
                    824:         local   density:dword
                    825: 
                    826: ; So some initialization:
                    827: 
                    828:         mov     esi, pStrips
                    829:         mov     al,  [esi].ST_jBitmask
                    830:         mov     edi, [esi].ST_pjScreen
                    831:         mov     ebx, [esi].ST_lNextScan
                    832:         mov     ecx, plStripEnd
                    833:         mov     minoradd, ebx
                    834:         mov     aEnd, ecx
                    835: 
                    836: ; Initialize styling:
                    837: 
                    838:         mov     ecx,          [esi].ST_xyDensity
                    839:         mov     ah,  byte ptr [esi].ST_spRemaining
                    840:         mov     bh,           [esi].ST_jStyleMask
                    841:         mov     density, ecx
                    842:         add     esi, offset ST_alStrips
                    843: 
                    844: Strip_loop:
                    845:         mov     ecx, [esi]              ; ecx = # bits to set
                    846:         add     esi, 4
                    847: 
                    848: ; Now we're going to paste the bytes to the screen
                    849: ;       (al) = rotating bit
                    850: ;       (ah) = # pixels left in style
                    851: ;       (bh) = style mask
                    852: ;       (ecx) = # bits to write
                    853: ;       (dx) = io address of mask register
                    854: ;       (esi) = ptr to spot in ST_alStrips
                    855: ;       (edi) = address of byte to write
                    856: 
                    857: Strip_count:
                    858:         test    bh, al
                    859:         jnz     short @F                ; don't output pixel if style bit is 1
                    860:         and     [edi], al
                    861: @@:
                    862:         dec     ah                      ; we've advanced 1 pel in the style
                    863:         jnz     short @F
                    864:         mov     ah, byte ptr density
                    865:         rol     bh, 1
                    866: @@:
                    867:         add     edi, minoradd
                    868: 
                    869:         dec     ecx
                    870:         jnz     short Strip_count
                    871: 
                    872: ; Adjust address, style mask and rotating bit for sidestep:
                    873: 
                    874:         ror     bh, 1                   ; rotate style mask to stay in sync
                    875:         ror     al, 1                   ; move rotating bit one to the right
                    876:         adc     edi, 0
                    877: 
                    878:         cmp     esi, aEnd
                    879:         jl      short Strip_loop        ; hit end of array?
                    880: 
                    881:         mov     esi, pStrips
                    882: 
                    883:         mov              [esi].ST_pjScreen, edi
                    884:         mov              [esi].ST_jBitmask, al
                    885:         mov              [esi].ST_jStyleMask, bh
                    886:         mov     byte ptr [esi].ST_spRemaining, ah
                    887: 
                    888:         cRet    vStripMaskedVertical
                    889: 
                    890: endProc vStripMaskedVertical
                    891: 
                    892: _TEXT$04   ends
                    893: 
                    894:         end

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.