COMMENT~

PROGRAM: PUTPIXEL.ASM
 AUTHOR: Denis Boyles

RELEASE: Public Domain (pd) Dec 24, 1996
VERSION: 1.00a

COMPILE: Arrowsoft Assembler (MASM v3.0)
     OS: MS-DOS (v6.20)

PURPOSE: my attempt at a `fast' `PutPixel' routine :)
  NOTES: PutPixel args are left->right, make sure ES=A000 if using in HLL :)

A few things if you want to use this with something, make sure that
ES=A000 when you call PutPixel, or put it in the procedure.

The procedure is a near one, and the arguments are pushed from
left->right. Lastly the table should be in the default DS segment so you
can load up the offsets.

~

PRG SEGMENT                            ;default program segment(s)
    ASSUME CS:PRG,DS:PRG
    ORG 100h

MAIN:
    mov     AX,13h                     ;BIOS video, set MCGA video mode
    int     10h

    mov     AX,0A000h                  ;setup ES with video RAM segment for
    mov     ES,AX                      ;our PutPixel procedure

    mov     CX,199                     ;outer Y for loop, 200 x (0-199)

LoopY:
    push    CX                         ;save current Y count to stack
    mov     DX,CX                      ;save it again to CX?
    mov     CX,319                     ;inner X for loop, 320 x (0-319)

LoopX:
    push    CX                         ;push X value onto stack
    push    DX                         ;push Y value onto stack
    push    DX                         ;push color onto stack (Y)
    call    PutPixel                   ;call PutPixel to plot pixel :)
    loop    LoopX                      ;keep looping until X=0

    pop     CX                         ;restore our saved Y counter
    loop    LoopY                      ;keep looping until Y=0

    mov     AH,02h                     ;DOS print a character
    mov     DL,07h                     ;bell character (BEEP!)
    int     21h                        ;beep the PC so we we're done :)

    xor     AH,AH                      ;BIOS keyboard wait for keypress
    int     16h                        ;call BIOS and wait for a keypress

    mov     AX,03h                     ;BIOS video, set 80x25x16 text mode
    int     10h
    ret                                ;a quick return back to DOS

PutPixel proc                          ;PutPixel( x, y, color ) (left->right)
    push    BP                         ;save BP register on stack so we can
    mov     BP,SP                      ;load it with SP for indexing

    mov     BX,[BP+6]                  ;BX = Y
    add     BX,BX                      ;BX = BX + BX ( BX = BX * 2 :)
    mov     BX,ytable[BX]              ;get the offset value from table
    add     BX,[BP+8]                  ;BX = BX + X
    mov     AX,[BP+4]                  ;AX = color
    mov     ES:[BX],AL                 ;plot pixel to screen

    pop     BP                         ;restore BP
    ret     6                          ;return and discard X,Y,color
PutPixel endp

ytable LABEL word                       ;MCGA Y offset lookup table

dw 00000h,00140h,00280h,003C0h,00500h,00640h,00780h,008C0h,00A00h,00B40h
dw 00C80h,00DC0h,00F00h,01040h,01180h,012C0h,01400h,01540h,01680h,017C0h
dw 01900h,01A40h,01B80h,01CC0h,01E00h,01F40h,02080h,021C0h,02300h,02440h
dw 02580h,026C0h,02800h,02940h,02A80h,02BC0h,02D00h,02E40h,02F80h,030C0h
dw 03200h,03340h,03480h,035C0h,03700h,03840h,03980h,03AC0h,03C00h,03D40h
dw 03E80h,03FC0h,04100h,04240h,04380h,044C0h,04600h,04740h,04880h,049C0h
dw 04B00h,04C40h,04D80h,04EC0h,05000h,05140h,05280h,053C0h,05500h,05640h
dw 05780h,058C0h,05A00h,05B40h,05C80h,05DC0h,05F00h,06040h,06180h,062C0h
dw 06400h,06540h,06680h,067C0h,06900h,06A40h,06B80h,06CC0h,06E00h,06F40h
dw 07080h,071C0h,07300h,07440h,07580h,076C0h,07800h,07940h,07A80h,07BC0h
dw 07D00h,07E40h,07F80h,080C0h,08200h,08340h,08480h,085C0h,08700h,08840h
dw 08980h,08AC0h,08C00h,08D40h,08E80h,08FC0h,09100h,09240h,09380h,094C0h
dw 09600h,09740h,09880h,099C0h,09B00h,09C40h,09D80h,09EC0h,0A000h,0A140h
dw 0A280h,0A3C0h,0A500h,0A640h,0A780h,0A8C0h,0AA00h,0AB40h,0AC80h,0ADC0h
dw 0AF00h,0B040h,0B180h,0B2C0h,0B400h,0B540h,0B680h,0B7C0h,0B900h,0BA40h
dw 0BB80h,0BCC0h,0BE00h,0BF40h,0C080h,0C1C0h,0C300h,0C440h,0C580h,0C6C0h
dw 0C800h,0C940h,0CA80h,0CBC0h,0CD00h,0CE40h,0CF80h,0D0C0h,0D200h,0D340h
dw 0D480h,0D5C0h,0D700h,0D840h,0D980h,0DAC0h,0DC00h,0DD40h,0DE80h,0DFC0h
dw 0E100h,0E240h,0E380h,0E4C0h,0E600h,0E740h,0E880h,0E9C0h,0EB00h,0EC40h
dw 0ED80h,0EEC0h,0F000h,0F140h,0F280h,0F3C0h,0F500h,0F640h,0F780h,0F8C0h

PRG ENDS
END MAIN
