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