Annotation of ntddk/src/video/displays/vga/i386/vgastrps.asm, revision 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.