home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume8 / gnuplot1.10A / part02 / hrcgraph.asm < prev    next >
Encoding:
Assembly Source File  |  1989-09-09  |  7.8 KB  |  347 lines

  1. TITLE    Hercules graphics module
  2.  
  3. ;    Michael Gordon - 8-Dec-86
  4. ;
  5. ; Certain routines were taken from the Hercules BIOS of    Dave Tutelman - 8/86
  6. ; Others came from pcgraph.asm included in GNUPLOT by Colin Kelley
  7. ;
  8. ; modified slightly by Colin Kelley - 22-Dec-86
  9. ;    added header.mac, parameterized declarations
  10. ; added dgroup: in HVmodem to reach HCh_Parms and HGr_Parms - 30-Jan-87
  11.  
  12. include header.mac
  13.  
  14. if1
  15. include lineproc.mac
  16. endif
  17.  
  18.  
  19. GPg1_Base equ 0B800h    ; Graphics page 1 base address
  20.  
  21. _text    segment
  22.  
  23.     public _H_line, _H_color, _H_mask, _HVmode, _H_puts
  24.  
  25. hpixel    proc near
  26.     ror word ptr bmask,1
  27.     jc cont
  28.     ret
  29. cont:
  30.     push ax
  31.     push bx
  32.     push cx
  33.     push dx
  34.     push si
  35.     mov cx,ax        ; x
  36.     mov dx,bx        ; y
  37. ;
  38. ; [couldn't this be done faster with a lookup table? -cdk]
  39. ;
  40.     ; first compute the address of byte to be modified
  41.     ; = 90*[row/4] + [col/8] + 2^D*[row/4] + 2^F*page
  42.     mov    bh,cl        ; col (low order) in BH
  43.     mov    bl,dl        ; row (low order) in BL
  44.     and    bx,0703H    ; mask the col & row remainders
  45. IFDEF iAPX286
  46.     shr    cx,3        ; col / 8
  47.     shr    dx,2        ; row / 4
  48.     mov    al,90
  49.     mul    dx        ; AX = 90*[ row/4 ]
  50.     add    ax,cx        ;  ... + col/8
  51.     shl    bl,5        ; align row remainder
  52. ELSE            ; same as above, obscure but fast for 8086
  53.     shr    cx,1        ; divide col by 8
  54.     shr    cx,1
  55.     shr    cx,1
  56.     shr    dx,1        ; divide row by 4
  57.     shr    dx,1
  58.     shl    dx,1        ; begin fast multiply by 90 (1011010 B)
  59.     mov    ax,dx
  60.     shl    dx,1
  61.     shl    dx,1
  62.     add    ax,dx
  63.     shl    dx,1
  64.     add    ax,dx
  65.     shl    dx,1
  66.     shl    dx,1
  67.     add    ax,dx        ; end fast multiply by 90
  68.     add    ax,cx        ; add on the col/8
  69.     shl    bl,1        ; align row remainder
  70.     shl    bl,1
  71.     shl    bl,1
  72.     shl    bl,1
  73.     shl    bl,1
  74. ENDIF
  75.     add    ah,bl        ; use aligned row remainder
  76. end_adr_calc:            ; address of byte is now in AX
  77.     mov    dx,GPg1_Base    ; base of pixel display to DX
  78.     mov    es,dx        ; ...and thence to segment reg
  79.     mov    si,ax        ; address of byte w/ pixel to index reg
  80.     mov    cl,bh        ; bit addr in byte
  81.     mov    al,80H        ; '1000 0000' in AL 
  82.     shr    al,cl        ; shift mask to line up with bit to read/write
  83. set_pix:            ; set the pixel
  84.     or    es:[si],al    ; or the mask with the right byte
  85.     pop si
  86.     pop dx
  87.     pop cx
  88.     pop bx
  89.     pop ax
  90.     ret
  91. hpixel endp
  92.  
  93. lineproc _H_line, hpixel
  94.  
  95. ;
  96. ; clear - clear page 1 of the screen buffer to zero (effectively, blank
  97. ;    the screen)
  98. ;
  99. clear   proc near
  100.     push es
  101.     push ax
  102.     push cx
  103.     push di
  104.     mov ax, GPg1_Base
  105.     mov es, ax
  106.     xor di, di
  107.     mov cx, 4000h
  108.     xor ax, ax
  109.     cld
  110.     rep stosw            ; zero out screen page
  111.     pop di
  112.     pop cx
  113.     pop ax
  114.     pop es
  115.     ret
  116. clear    endp
  117.  
  118. beginproc _H_color
  119.     push bp
  120.     mov bp,sp
  121.     mov al,[bp+X]            ; color
  122.     mov byte ptr color,al
  123.     pop bp
  124.     ret
  125. _H_color endp
  126.  
  127. beginproc _H_mask
  128.     push bp
  129.     mov bp,sp
  130.     mov ax,[bp+X]            ; mask
  131.     mov word ptr bmask,ax
  132.     pop bp
  133.     ret
  134. _H_mask endp
  135.  
  136. HCtrl_Port    equ    03B8H    ; Hercules 6845 control port IO addr
  137. HIndx_Port    equ    03B4H    ; Hercules 6845 index port IO addr
  138. HScrn_Enable    equ    008h    ; Control port bit to enable video
  139. HCh_Mode    equ    020h    ; Character output mode
  140. HGr_Mode    equ    082h    ; Graphics output mode page 1
  141.  
  142. parm_count equ 12
  143.  
  144. beginproc _HVmode
  145.     push bp
  146.     mov bp, sp
  147.     push si
  148.     mov ax, [bp+X]
  149.     or ah, al
  150.     mov al, HCh_Mode        ; Assume character mode is wanted
  151.     mov si, offset dgroup:HCh_Parms
  152.     cmp ah, 0            ; nonzero means switch to graphics
  153.     jz vmode_ok
  154.     call near ptr clear        ; clear the graphics page
  155.     mov al, HGr_Mode
  156.     mov si, offset dgroup:HGr_Parms
  157. vmode_ok:
  158.     mov dx, HCtrl_Port
  159.     out dx, al            ; Set Hercules board to proper mode
  160.     call near ptr setParms        ; Set the 6845 parameters
  161.     or al, HScrn_Enable        ; Enable the video output
  162.     out dx, al
  163.     pop si
  164.     pop bp
  165.     ret
  166. _HVmode    endp
  167.  
  168. setParms proc near        ; Send 6845 parms to Hercules board
  169.     push ax
  170.     push dx
  171.     push si            
  172.     mov dx, HIndx_Port    ; Index port addr -> DX
  173.     mov ah, 0        ; 0 -> parameter counter
  174. sp_loop:
  175.     mov al, ah
  176.     out dx, al        ; output to 6845 addr register
  177.     inc dx            ; next output to data register
  178.     mov al, [si]        ; next control byte -> al
  179.     inc si
  180.     out dx, al        ; output control byte
  181.     dec dx            ; 6845 index addr -> dx
  182.     inc ah            ; bump addr
  183.     cmp ah, parm_count
  184.     jnz sp_loop
  185.     pop si
  186.     pop dx
  187.     pop ax
  188.     ret
  189. setParms endp
  190.  
  191. ; H_puts - print text in graphics mode
  192. ;
  193. ;    cx = row
  194. ;    bx = column
  195. ;    si = address of string (null terminated) to print
  196.  
  197. beginproc _H_puts
  198.     push bp
  199.     mov bp, sp
  200.     push si
  201.     push ds
  202.     mov si, [bp+X]            ; string offset
  203.  
  204. ifdef LARGE_DATA
  205.     mov ds, [bp+X+2]        ; string segment
  206.     mov cx, [bp+X+4]        ; row
  207.     mov bx, [bp+X+6]        ; col
  208. else
  209.     mov cx, [bp+X+2]        ; row
  210.     mov bx, [bp+X+4]        ; col
  211. endif
  212.  
  213. ploop:    lodsb                ; get next char
  214.     or    al, al            ; end of display?
  215.     je    pdone
  216.     call near ptr display
  217.     inc    bx            ; bump to next column
  218.     jmp    ploop
  219. pdone:    pop ds
  220.     pop si
  221.     pop bp
  222.     ret
  223. _H_puts    endp
  224.  
  225. ;
  226. ; display - output an 8x8 character from the IBM ROM to the Herc board
  227. ;
  228. ; AX = char, BX = column (0-89), CX = row(0-42)  ** all preserved **
  229. ;
  230. CON8    db    8
  231. CON180    db    180
  232. IBMROM    equ    0F000h
  233. CHARTAB    equ    0FA6Eh
  234.  
  235. display    proc near
  236.     push    ds            ; save the lot
  237.     push    es
  238.     push    ax
  239.     push    bx
  240.     push    cx
  241.     push    dx
  242.     push    si
  243.     push    di
  244.  
  245. ; setup ds -> IBM ROM, and si -> index into IBM ROM character table located
  246. ;    at 0fa6eh in the ROM
  247.  
  248.     and    ax, 07fh
  249.     mul    cs:CON8            ; mult by 8 bytes of table per char
  250.     mov    si, ax
  251.     mov    ax, IBMROM
  252.     mov    ds, ax
  253.     assume    ds:nothing
  254.     add    si, CHARTAB        ; add offset of character table
  255.  
  256. ; compute index into Hercules screen memory for scan line 0.  The remaining
  257. ;    seven scan lines are all at fixed offsets from the first.
  258. ;
  259. ;    Since graphics mode treats the screen as sets of 16x4 "characters",
  260. ;    we need to map an 8x8 real character onto the front or back of
  261. ;    a pair of graphics "characters".  The first four scan lines of our
  262. ;    8x8 character will map to the top graphics "character", and the second
  263. ;    four scan lines map to the graphics character on the "line" (4 scan
  264. ;    lines high) below it.
  265. ;
  266. ;    For some exotic hardware reason (probably speed), all scan line 0
  267. ;    bits (i.e. every fourth scan line) are stored in memory locations
  268. ;    0-2000h in the screen buffer.  All scan line 1 bits are stored
  269. ;    2000h-4000h.  Within these banks, they are stored by rows.  The first
  270. ;    scan line on the screen (scan line 0 of graphics character row 0)
  271. ;    is the first 45 words of memory in the screen buffer.  The next 45
  272. ;    words are the first scan line graphics row 1, and since graphics
  273. ;    "characters" are 4 bits high, this second scan line is physically
  274. ;    the fifth scan line displayed on the screen.
  275. ;
  276. ;    SO, to display an 8x8 character, the 1st and 5th rows of dots are
  277. ;    both scan line 0 of the graphics "character", the 2nd and 6th are
  278. ;    scan line 1, and so on.
  279. ;
  280. ;    The column (0-89) tells which byte in a scan line we need to load.
  281. ;    Since it takes two rows of graphics characters to hold one row of
  282. ;    our characters, column+90 is a index to scan line 4 rows of pixels
  283. ;    higher (n+4).  Thus 180 bytes of screen memory in any bank (0h, 2000h,
  284. ;    4000h, 6000h) represent a row of 8x8 characters.
  285. ;    
  286. ;    The starting location in screen memory for the first scan line of
  287. ;    a character to be displayed will be:      (row*180)+column
  288. ;    The 5th scan line will be at:        (row*180)+column+90
  289. ;
  290. ;    The second and 6th scan lines will be at the above offsets plus
  291. ;    the bank offset of 2000h.  The third and 7th, add 4000h and finally
  292. ;    the 4th and 8th, add 6000h.
  293. ;
  294.     mov    ax, GPg1_Base
  295.     mov    es, ax            ; es = hercules page 0
  296.     mov    ax, cx            ; get row
  297.     mul    cs:CON180        ; mult by 180(10)
  298.     mov    di, ax            ; di = index reg
  299.     cld                ; insure right direction
  300.  
  301. ;output 8 segments of character to video ram
  302.  
  303.     lodsb                ; line 0
  304.     mov    es:[di+bx], al
  305.     lodsb
  306.     mov    es:[di+bx+2000h], al    ; line 1
  307.     lodsb
  308.     mov    es:[di+bx+4000h], al    ; line 2
  309.     lodsb
  310.     mov    es:[di+bx+6000h], al    ; line 3
  311.     lodsb
  312.     mov    es:[di+bx+90], al    ; line 4
  313.     lodsb
  314.     mov    es:[di+bx+2000h+90], al    ; line 5
  315.     lodsb
  316.     mov    es:[di+bx+4000h+90], al    ; line 6
  317.     lodsb
  318.     mov    es:[di+bx+6000h+90], al    ; line 7
  319.  
  320.     pop    di
  321.     pop    si
  322.     pop    dx
  323.     pop    cx
  324.     pop    bx
  325.     pop    ax
  326.     pop    es
  327.     pop    ds
  328.     ret
  329. display    endp
  330.  
  331. _text    ends
  332.  
  333. _data    segment
  334. bmask    dw -1
  335. color    db 1
  336. _data    ends
  337.  
  338. const    segment
  339. HCh_Parms db     61H, 50H, 52H, 0FH, 19H, 06H, 19H, 19H, 02H, 0DH, 0BH, 0CH
  340. HGr_Parms db    35H, 2DH, 2EH, 07H, 5BH, 02H, 57H, 57H, 02H, 03H, 00H, 00H
  341. const    ends
  342.  
  343.     end
  344. ---------------------------end HRCGRAPH.ASM-------------------------------
  345.  
  346.  
  347.