From ugle.unit.no!sunic!mcsun!uunet!utcsri!torn!maccs!mcshub!csx.cciw.ca!hcp Mon Sep 14 19:00:41 1992 Article: 31586 of comp.sys.ibm.pc.hardware Newsgroups: comp.sys.ibm.pc.hardware Path: ugle.unit.no!sunic!mcsun!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. > 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. From ugle.unit.no!sunic!mcsun!uunet!spool.mu.edu!yale.edu!jvnc.net!nuscc!nusunix3.nus.sg!isc30108 Mon Sep 14 19:01:21 1992 Article: 31648 of comp.sys.ibm.pc.hardware Newsgroups: comp.sys.ibm.pc.hardware Path: ugle.unit.no!sunic!mcsun!uunet!spool.mu.edu!yale.edu!jvnc.net!nuscc!nusunix3.nus.sg!isc30108 From: isc30108@nusunix3.nus.sg (AMBAT SASI S/O PALISSERY P) Subject: Re: CGA 160x100x16 Message-ID: <1992Sep14.122249.14656@nuscc.nus.sg> Sender: usenet@nuscc.nus.sg Organization: National University of Singapore References: <1992Sep13.161927.19097@csx.cciw.ca> Date: Mon, 14 Sep 1992 12:22:49 GMT Lines: 21 hey, ur code works ! (after some minor twiddling} here's what u need to change 3d4[1] = 71h 2 50h 5ah 0ah 7fh 6 64h 70h 2 1 6 7 0 0 0 thanks for everything. sasi.