TITLE Hercules Graphics Routines for FRACTINT ; required for compatibility if Turbo ASM IFDEF ??version MASM51 QUIRKS ENDIF .MODEL medium,c .8086 .data HGCBase equ 0B000h ;segment for HGC regen buffer page 0 herc_index equ 03B4h herc_cntrl equ 03B8h herc_status equ 03BAh herc_config equ 03BFh ; Hercules control/configuration register settings scrn_on equ 08h grph equ 02h text equ 20h enable equ 03h .code ; ; ; inithgc - Initialize the HGC in graphics mode. ; Code mostly from the Hercules Graphics Card Owner's Manual. ; inithgc PROC USES DI SI mov al,enable ; enable mode changes mov dx,herc_config ; same as HGC FULL command out dx,al mov al,grph ; set graphic mode lea si,gtable ; address of graphic parameters mov bx,0 mov cx,4000h call setmd ; call set mode common processing ret inithgc ENDP ; ; termhgc - Restore the Hercules Graphics Card to text mode. ; Code mostly from the Hercules Graphics Card Owner's Manual. ; termhgc PROC USES DI SI mov al,text ; set text mode lea si,ttable ; get address of text parameters mov bx,720h mov cx,2000 call setmd ret termhgc ENDP ; ; setmd - sets mode to graphic or text depending on al ; si = address of parameter table ; cx = number of words to be cleared ; bx = blank value ; ; from Hercules Graphics Card Owner's Manual ; setmd PROC NEAR ; push bp mov bp,sp push ax push bx push cx ; change mode, but without screen on mov dx,herc_cntrl ; get address of control register out dx,al ; al has the mode byte ; initialize the 6845 mov ax,ds mov es,ax ; also point es:si to parameter table mov dx,herc_index ; get index register address mov cx,12 ; 12 parameters to be output xor ah,ah ; starting from register 0 parms: mov al,ah ; first output register number out dx,al inc dx ; get data register address lodsb ; get next byte from param. table out dx,al ; output parameter data inc ah ; increment register number dec dx ; restore index register address loop parms ; go do another one ; now go clear the buffer pop cx ; get number of words to clear mov ax,HGCBase ; get address off video buffer cld ; set auto increment mov es,ax ; set segment for string move xor di,di ; start at offset 0 pop ax ; get blank value rep stosw ; repeat store string ; turn screen on with page 0 active mov dx,herc_cntrl ; get control register address pop ax ; get the mode byte add al,scrn_on ; set the screen-on bit out dx,al mov sp,bp pop bp ret setmd ENDP ; ; writehgc (x, y, c) - write a dot at x, y in color color ; x = x coordinate ; y = y coordinate ; color = color ; writehgc PROC USES DI SI, x, y, color cmp y,348 ; Clip for hardware boundaries jge WtDot030 cmp x,720 jge WtDot030 lea bx,HGCRegen ;set up offset of regen scan line table mov ax,HGCBase ;segment for regen buffer mov es,ax ; calculate byte address of dot in regen buffer mov si,y ;get y coordinate shl si,1 ;mult by 2 to get offset in Scan Line Table mov si,[bx][si] ;get address of start of scan line from table mov ax,x ;get x coordinate mov cl,3 shr ax,cl ;divide by 8 to get byte offset add si,ax ;es:si has address of byte with the bit ; build the bit mask for the specific dot in the byte mov cx,x ;get x coordinate and cx,0007h ;get bit number within the byte mov al,80h ;prepare bit mask shr al,cl ;al has bit mask ; either turn on the bit or turn it off, depending on the color cmp word ptr color,0 ;turn off bit? je WtDot020 ;yes -- branch ; turn on the bit or byte ptr es:[si],al jmp short WtDot030 WtDot020: ; turn off the bit xor al,0FFh and byte ptr es:[si],al WtDot030: ret writehgc ENDP ; ; readhgc (x,y) - read a dot at x,y ; x = x coordinate ; y = y coordinate ; ; dot value is to be returned in AX ; readhgc PROC USES DI SI, x,y lea bx,HGCRegen ;set up offset of regen scan line table mov ax,HGCBase ;segment for regen buffer mov es,ax ; calculate byte address of dot in regen buffer mov si,y ;get y coordinate shl si,1 ;mult by 2 to get offset in Scan Line Table mov si,[bx][si] ;get address of start of scan line from table mov ax,x ;get x coordinate mov cl,3 shr ax,cl ;divide by 8 to get byte offset add si,ax ;es:si has address of byte with the bit ; build the bit mask for the specific dot in the byte mov cx,x ;get x coordinate and cx,0007h ;get bit number within the byte mov al,80h ;prepare bit mask shr al,cl ;al has bit mask ; pick up the bit from the regen buffer test byte ptr es:[si],al jz readhgc020 ;branch if bit is zero mov ax,1 ;else return foreground bit value jmp short readhgc030 readhgc020: xor ax,ax ;bit is zero readhgc030: ret readhgc ENDP .data gtable db 35h,2dh,2eh,07h db 5bh,02h,57h,57h db 02h,03h,00h,00h ttable db 61h,50h,52h,0fh db 19h,06h,19h,19h db 02h,0dh,0bh,0ch ;offsets into HGC regen buffer for each scan line HGCRegen dw 0,8192,16384,24576,90,8282,16474,24666 dw 180,8372,16564,24756,270,8462,16654,24846 dw 360,8552,16744,24936,450,8642,16834,25026 dw 540,8732,16924,25116,630,8822,17014,25206 dw 720,8912,17104,25296,810,9002,17194,25386 dw 900,9092,17284,25476,990,9182,17374,25566 dw 1080,9272,17464,25656,1170,9362,17554,25746 dw 1260,9452,17644,25836,1350,9542,17734,25926 dw 1440,9632,17824,26016,1530,9722,17914,26106 dw 1620,9812,18004,26196,1710,9902,18094,26286 dw 1800,9992,18184,26376,1890,10082,18274,26466 dw 1980,10172,18364,26556,2070,10262,18454,26646 dw 2160,10352,18544,26736,2250,10442,18634,26826 dw 2340,10532,18724,26916,2430,10622,18814,27006 dw 2520,10712,18904,27096,2610,10802,18994,27186 dw 2700,10892,19084,27276,2790,10982,19174,27366 dw 2880,11072,19264,27456,2970,11162,19354,27546 dw 3060,11252,19444,27636,3150,11342,19534,27726 dw 3240,11432,19624,27816,3330,11522,19714,27906 dw 3420,11612,19804,27996,3510,11702,19894,28086 dw 3600,11792,19984,28176,3690,11882,20074,28266 dw 3780,11972,20164,28356,3870,12062,20254,28446 dw 3960,12152,20344,28536,4050,12242,20434,28626 dw 4140,12332,20524,28716,4230,12422,20614,28806 dw 4320,12512,20704,28896,4410,12602,20794,28986 dw 4500,12692,20884,29076,4590,12782,20974,29166 dw 4680,12872,21064,29256,4770,12962,21154,29346 dw 4860,13052,21244,29436,4950,13142,21334,29526 dw 5040,13232,21424,29616,5130,13322,21514,29706 dw 5220,13412,21604,29796,5310,13502,21694,29886 dw 5400,13592,21784,29976,5490,13682,21874,30066 dw 5580,13772,21964,30156,5670,13862,22054,30246 dw 5760,13952,22144,30336,5850,14042,22234,30426 dw 5940,14132,22324,30516,6030,14222,22414,30606 dw 6120,14312,22504,30696,6210,14402,22594,30786 dw 6300,14492,22684,30876,6390,14582,22774,30966 dw 6480,14672,22864,31056,6570,14762,22954,31146 dw 6660,14852,23044,31236,6750,14942,23134,31326 dw 6840,15032,23224,31416,6930,15122,23314,31506 dw 7020,15212,23404,31596,7110,15302,23494,31686 dw 7200,15392,23584,31776,7290,15482,23674,31866 dw 7380,15572,23764,31956,7470,15662,23854,32046 dw 7560,15752,23944,32136,7650,15842,24034,32226 dw 7740,15932,24124,32316 END