home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sys.ibm.pc.hardware
- Path: sparky!uunet!utcsri!torn!maccs!mcshub!csx.cciw.ca!hcp
- From: hcp@csx.cciw.ca (H.C. Pulley)
- Subject: Re: CGA 160x100x16
- Organization: Canada Centre for Inland Waters
- Date: Sun, 13 Sep 1992 16:19:27 GMT
- Message-ID: <1992Sep13.161927.19097@csx.cciw.ca>
- References: <1992Sep11.120323.16528@nuscc.nus.sg>
- Lines: 485
-
- In article <1992Sep11.120323.16528@nuscc.nus.sg> isc30108@nusunix3.nus.sg (AMBAT SASI S/O PALISSERY P) writes:
- >can some1 please post some code (c/asm/pas)
- >describing how to arrive at this simulated "graphics"
- >mode with 16 colors 160x100 resolution.
- >thanks.
- >
- >sasi.
- ><last request posted expired>
-
- Alright, but you asked for it!
-
- Like I said before, it doesn't work properly.
-
- Please don't give me any comments on my assembly style. This was an
- experimental program only.
-
- If you manage to get it to work properly, please send me the modified source.
-
- This program simply goes into 160x100x16 mode (or tries to anyways) and draws
- 200 lines changing colors as it goes.
-
- --- CUT HERE ---
-
- ; This program goes into text/graphics mode (160*100) in 16 colors
- ; It draws 200 lines and then exits
- ; By Harry C. Pulley, IV. MAR92.
-
- .MODEL small
-
- .STACK 200h
-
- .DATA
- Current_pos_x DW 159 ; to hold current pixel x value
- Current_pos_y DW 0 ; to hold current pixel y value
- Last_pos_x DW 0 ; to hold last pixel x value
- Last_pos_y DW 99 ; to hold last pixel y value
- Saved_video_mode DB ? ; to hold the old video mode for return to DOS
- Set_video_mode DB 5 ; new video mode=5
- Plot_mode DB 0 ; plot mode: pixel color
- signed_rise DW ? ; signed rise
- signed_run DW ? ; signed run
- rise_sign DB ? ; rise + | -
- run_sign DB ? ; run + | -
- Hold_x DW ? ; starting x value
- Hold_y DW ? ; starting y value
-
- .CODE
- Start: ; start of program
- mov ax,@data ; set up ds to point to .DATA segment
- mov ds,ax ; use ax since mov ds,@data is illegal
-
- mov ah,0fh ; video function to get video parameters
- int 10h ; video interrupt
- mov [Saved_video_mode],al ; save video mode in variable for later
-
- sub al,al ; set al to zero
- mov dx,3d8h ; cga mode control register
-
- out dx,al ; disable display
-
- mov dx,3d4h
-
- out dx,al ; set CRTC reg 0
-
- mov al,83
- mov dx,3d5h
-
- out dx,al ; set horizontal total to 83
-
- mov al,1
- mov dx,3d4h
-
- out dx,al ; set CRTC reg 1
-
- mov al,80
- mov dx,3d5h
-
- out dx,al ; set horizontal displayed to 80
-
- mov al,2
- mov dx,3d4h
-
- out dx,al ; set CRTC reg 2
-
- mov al,81
- mov dx,3d5h
-
- out dx,al ; set horizontal sync to 81
-
- mov al,3
- mov dx,3d4h
-
- out dx,al ; set CRTC reg 3
-
- mov al,1
- mov dx,3d5h
-
- out dx,al ; set horizontal sync width 1
-
- mov al,4
- mov dx,3d4h
-
- out dx,al ; set CRTC reg 4
-
- mov al,107
- mov dx,3d5h
-
- out dx,al ; set vertical total to 107
-
- mov al,5
- mov dx,3d4h
-
- out dx,al ; set CRTC reg 5
-
- sub al,al ; al=0
- mov dx,3d5h
-
- out dx,al ; set vertical adjust 0
-
- mov al,6
- mov dx,3d4h
-
- out dx,al ; set CRTC reg 6
-
- mov al,107
- mov dx,3d5h
-
- out dx,al ; set vertical displayed 107
-
- mov al,7
- mov dx,3d4h
-
- out dx,al ; set CRTC reg 7
-
- mov al,100
- mov dx,3d5h
-
- out dx,al ; set vertical sync 100
-
- mov al,8
- mov dx,3d4h
-
- out dx,al ; set CRTC reg 8
-
- mov al,2
- mov dx,3d5h
-
- out dx,al ; set interlace 2
-
- mov al,9
- mov dx,3d4h
-
- out dx,al ; set CRTC reg 9
-
- mov al,7
- mov dx,3d5h
-
- out dx,al ; set max scan 7
-
- mov al,10
- mov dx,3d4h
-
- out dx,al ; set CRTC reg 10
-
- mov al,6
- mov dx,3d5h
-
- out dx,al ; set cursor start 6
-
- mov al,11
- mov dx,3d4h
-
- out dx,al ; set CRTC reg 11
-
- mov al,7
- mov dx,3d5h
-
- out dx,al ; set cursor end 7
-
- mov al,12
- mov dx,3d4h
-
- out dx,al ; set CRTC reg 12
-
- sub al,al
- mov dx,3d5h
-
- out dx,al ; set high start addr 0
-
- mov al,13
- mov dx,3d4h
-
- out dx,al ; set CRTC reg 13
-
- sub al,al
- mov dx,3d5h
-
- out dx,al ; set low start addr 0
-
- mov al,14
- mov dx,3d4h
-
- out dx,al ; set CRTC reg 14
-
- sub al,al
- mov dx,3d5h
-
- out dx,al ; set high end addr 0
-
- mov al,15
- mov dx,3d4h
-
- out dx,al ; set CRTC reg 15
-
- sub al,al
- mov dx,3d5h
-
- out dx,al ; set low end addr 0
-
- mov al,01000001b
- mov dx,3d8h
-
- out dx,al ; set psuedographics mode 160x100x16
-
- mov ax,0b800h
- mov es,ax ; set es to video memory
-
- cld
-
- mov ax,00deh ; set even bytes to deh character
- mov cx,8000 ; 8000 words long
- mov di,0 ; set di to offset of start of video buffer
-
- rep stosw ; fill video memory
-
- mov al,01001001b
- mov dx,3d8h
-
- out dx,al ; enable display
-
- Mainloop:
-
- Call Plot_line
-
- dec [Current_pos_x]
-
- inc [Current_pos_y]
-
- inc [Last_pos_x]
-
- dec [Last_pos_y] ; adjust point values
-
- cmp [Last_pos_x],100
- jge OutofLoop
-
- inc [Plot_mode]
- and [Plot_mode],0fh ; get Plot_mode%16
-
- ; mov ax,10h
- ; int 16h ; wait for key
-
- jmp Mainloop ; get next character/mouse action
-
- OutofLoop:
- mov ah,0 ; set video mode
- mov al,[Saved_video_mode] ; restore video mode
- int 10h ; video interrupt
-
- mov ah,4ch ; DOS terminate program function
- int 21h ; DOS interrupt
-
- ; Procedure to plot a pixel using direct memory writes
- ; Input: Plot_mode, Current_pos_x, Current_pos_y
- ; Registers destroyed: ax,bx,cx,dx
- ; Output: none
-
- Plot_pixel PROC
-
- mov ax,[Current_pos_y] ; set ax to current # of lines
- mov dx,80 ; mul by 160
- mul dx ; get current pixel count in lines
- add ax,[Current_pos_x] ; add x pos to count
- mov dx,ax
- and dx,1 ; get odd bit of count
- and ax,0fffeh ; get even count
- inc ax ; make count odd bye
-
- mov bx,ax ; quotient is byte count in bx
-
- mov cl,2
- sal dl,cl ; multiply dl by 4 for correct shift
- add dl,4 ; add 4 to dl to compensate for endianess
- mov cl,dl ; cl is the shift count, which is the bit count
-
- mov dl,[Plot_mode] ; make dl pixel color
- mov dh,0f0h ; prepare to erase
-
- ror dl,cl ; rotate the bit to the correct position in dl
- ror dh,cl ; rotate erasure window to correct pos
-
- and BYTE PTR es:[bx],dh ; clear pixel
-
- or BYTE PTR es:[bx],dl ; draw pixel
- ret
-
- Plot_pixel ENDP
-
- ; Procedure to plot a line from Last_pos_? to Current_pos_? using Plot_pixel
- ; Input: Last_pos_x,Last_pos_y,Current_pos_x,Current_pos_y
- ; Registers destroyed: ax,bx,cx,dx
- ; Output: none
-
- Plot_line PROC
-
- mov cx,[Current_pos_y]
- mov dx,[Current_pos_x] ; put current pos in registers cx,dx
-
- mov ax,cx
- sub ax,[Last_pos_y]
- mov [signed_rise],ax ; get signed rise
-
- mov ax,dx
- sub ax,[Last_pos_x]
- mov [signed_run],ax ; get signed run
-
- mov ax,[Last_pos_y]
- push ax
- mov ax,[Last_pos_x]
- push ax ; preserve last x,y
-
- cmp cx,[Last_pos_y] ; we want a positive rise
- jl Last_y_bigger
- mov [rise_sign],1 ; remember rise sign +
- jmp Do_run
-
- Last_y_bigger:
- xchg cx,[Last_pos_y] ; swap current y and last y
- mov [rise_sign],-1 ; remember rise sign -
-
- Do_run:
- sub cx,[Last_pos_y] ; get +rise
-
- cmp dx,[Last_pos_x] ; want a pos rise
- jl Last_x_bigger
- mov [run_sign],1 ; remember run sign +
- jmp Do_line
-
- Last_x_bigger:
- xchg dx,[Last_pos_x] ; swap current x and last x
- mov [run_sign],-1 ; remember run sign -
-
- Do_line:
- sub dx,[Last_pos_x] ; want pos run
-
- pop ax
- mov [Last_pos_x],ax
- pop ax
- mov [Last_pos_y],ax ; restore last x,y
-
- mov ax,cx
- add ax,dx
- cmp ax,0 ; if cx==dx==0 no draw needed
- jne Continue
- ret
-
- Continue:
- mov ax,[Current_pos_y]
- push ax
- mov ax,[Current_pos_x]
- push ax ; preserve current position x & y
-
- cmp cx,dx ; compare rise to run
- jg Skip
- jmp Run_bigger ; ignore = case, doesn't matter y | x if equal
-
- Skip:
- cmp [rise_sign],1
- je Start_last ; determine starting point, last or current
- jmp Start_next
- Start_last:
- mov ax,[Last_pos_y]
- mov [Current_pos_y],ax ; set last y to start
- mov ax,[Last_pos_x]
- mov [Current_pos_x],ax ; set last x to start
- Start_next:
- mov ax,[Current_pos_y]
- mov [Hold_y],ax ; keep start y
-
- Rise_loop:
- mov ax,[Current_pos_y]
- sub ax,[Hold_y] ; ax=delta y
- mov bx,[signed_run]
- imul bx ; mul y*run
- mov bx,[signed_rise]
- idiv bx ; div (y*run)/rise
-
- add ax,[Current_pos_x] ; add ((y*run)/rise)+b
-
- xchg ax,[Current_pos_x] ; save x
-
- push ax ; preserve ax for Current_pos_x
- push cx ; preserve cx for Loop counter
-
- call Plot_pixel
-
- pop cx ; restore cx
- pop ax ; restore ax
-
- mov [Current_pos_x],ax ; restore x
-
- inc [Current_pos_y] ; go to next y pos
-
- loop Rise_loop ; do next y pos
-
- jmp Restore ; exit procedure
-
- Run_bigger:
-
- mov cx,dx ; put run into counter
-
- cmp [run_sign],1
- je Start_lst ; determine starting point, last or current
- jmp Start_nxt
- Start_lst:
- mov ax,[Last_pos_y]
- mov [Current_pos_y],ax ; set last y to start
- mov ax,[Last_pos_x]
- mov [Current_pos_x],ax ; set last x to start
- Start_nxt:
- mov ax,[Current_pos_x]
- mov [Hold_x],ax ; keep starting x value
-
- Run_loop:
- mov ax,[Current_pos_x]
- sub ax,[Hold_x] ; ax=delta x
- mov bx,[signed_rise]
- imul bx ; mul x*rise
- mov bx,[signed_run]
- idiv bx ; div (x*rise)/run
-
- add ax,[Current_pos_y] ; add ((x*rise)/run)+b
-
- xchg ax,[Current_pos_y] ; save y
-
- push ax ; preserve ax for Current_pos_y
- push cx ; preserve cx for Loop counter
-
- call Plot_pixel
-
- pop cx ; restore cx
- pop ax ; restore ax
-
- mov [Current_pos_y],ax ; restore y
-
- inc [Current_pos_x] ; go to next x pos
-
- loop Run_loop ; do next x pos
-
- jmp Restore
-
- Restore:
- pop ax
- mov [Current_pos_x],ax ; restore x
- pop ax
- mov [Current_pos_y],ax ; restore y
-
- ret
-
- Plot_single:
- call Plot_pixel
-
- ret
- Plot_line ENDP
-
- END Start
-
- --- CUT HERE ---
-
- Harry
-
- --
- hcp@csx.cciw.ca | This message | It takes all kinds,
- hcpiv@grumpy.cis.uoguelph.ca | released to the | and to each his own.
- ------------------------------------| PUBLIC DOMAIN. | This thought in mind,
- Stay away from the DOS side, Luke! | | I walk alone.
-