1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
|
TITLE PC graphics module
; uses LINEPROC.MAC
; Michael Gordon - 8-Dec-86
;
; Certain routines were taken from the Hercules BIOS of Dave Tutelman - 8/86
; Others came from pcgraph.asm included in GNUPLOT by Colin Kelley
;
; modified slightly by Colin Kelley - 22-Dec-86
; added header.mac, parameterized declarations
; added dgroup: in HVmodem to reach HCh_Parms and HGr_Parms - 30-Jan-87
;
; modified and added to for use in plot(3) routines back end.
; Gil Webster.
;
; Assemble with masm ver. 4.
include header.mac
if1
include lineproc.mac
endif
GPg1_Base equ 0B800h ; Graphics page 1 base address
extrn _inter:far
_text segment
public _PC_line, _PC_color, _PC_mask, _PC_curloc, _PC_puts, _Vmode
public _erase, _save_stack, _ss_interrupt
pcpixel proc near
ror word ptr linemask,1
jc cont
ret
cont:
push ax
push bx
push cx
push dx
push bp
mov cx,ax ; x
mov dx,bx ; y
mov ah,0ch ; ah = write pixel
mov al,byte ptr color
mov bh, 0 ; page 0
int 10h
pop bp
pop dx
pop cx
pop bx
pop ax
ret
pcpixel endp
lineproc _PC_line, pcpixel
;
; erase - clear page 1 of the screen buffer to zero (effectively, blank
; the screen)
;
beginproc _erase
push es
push ax
push cx
push di
mov ax, GPg1_Base
mov es, ax
xor di, di
mov cx, 4000h
xor ax, ax
cld
rep stosw ; zero out screen page
pop di
pop cx
pop ax
pop es
ret
_erase endp
beginproc _PC_color
push bp
mov bp,sp
mov al,[bp+X] ; color
mov byte ptr color,al
pop bp
ret
_PC_color endp
beginproc _PC_mask
push bp
mov bp,sp
mov ax,[bp+X] ; mask
mov word ptr linemask,ax
pop bp
ret
_PC_mask endp
beginproc _Vmode
push bp
mov bp,sp
push si
push di
mov ax,[bp+X]
int 10h
pop di
pop si
pop bp
ret
_Vmode endp
beginproc _PC_curloc
push bp
mov bp,sp
mov dh, byte ptr [bp+X] ; row number
mov dl, byte ptr [bp+X+2] ; col number
mov bh, 0
mov ah, 2
int 10h
pop bp
ret
_PC_curloc endp
;
; thanks to watale!broehl for finding a bug here--I wasn't pushing BP
; and reloading AH before INT 10H, which is necessary on genuine IBM
; boards...
;
beginproc _PC_puts
push bp
mov bp,sp
push si
mov bl,byte ptr color
mov si,[bp+X] ; offset
ifdef LARGE_DATA
mov es,[bp+X+2] ; segment if large or compact data model
endif
puts2:
ifdef LARGE_DATA
mov al,es:[si]
else
mov al,[si]
endif
or al,al
jz puts3
mov ah,0eh ; write TTY char
int 10h
inc si
jmp short puts2
puts3: pop si
pop bp
ret
_PC_puts endp
; int kbhit();
; for those without MSC 4.0
; Use BIOS interrupt 16h to determine if a key is waiting in the buffer.
; Return nonzero if so.
;
beginproc _kbhit
mov ah, 1 ; function code 1 is keyboard test
int 16h ; keyboard functions
jnz kbfin ; Exit if char available
xor ax, ax ; No char: return zero.
kbfin: ret
_kbhit endp
; _save_stack and _ss_interrupt are needed due to a bug in the MSC 4.0
; code when run under MS-DOS 3.x. Starting with 3.0, MS-DOS automatically
; switches to an internal stack during system calls. This leaves SS:SP
; pointing at MS-DOS's stack when the ^C interrupt (INT 23H) is triggered.
; MSC should restore its own stack before calling the user signal() routine,
; but it doesn't.
;
; Presumably this code will be unnecessary in later releases of the compiler.
;
; _save_stack saves the current SS:SP to be loaded later by _ss_interrupt.
;
beginproc _save_stack
mov ax,ss
mov cs:save_ss,ax
mov ax,sp
mov cs:save_sp,ax
ret
_save_stack endp
; _ss_interrupt is called on ^C (INT 23H). It restores SS:SP as saved in
; _save_stack and then jumps to the C routine interrupt().
;
beginproc _ss_interrupt
cli ; no interrupts while the stack is changed!
mov ax,-1 ; self-modifying code again
save_ss equ this word - 2
mov ss,ax
mov sp,-1 ; here too
save_sp equ this word - 2
sti
jmp far ptr _inter; now it's safe to call the real routine
_ss_interrupt endp
_text ends
const segment
linemask dw -1
color db 1
const ends
end
|