;************************************************************************** ;* DEVICE SPECIFIC ROUTINES * ;* * ;* These routines and equates are device dependant. * ;* * ;* * ;* * ;************************************************************************** ;Hist ;Name Date Modification ; dseg copyright db 'GEMVDI V1.2 8/1/85' db 'Genius Card' db 'Serial No. XXXX-0000-654321 ' db 'All Rights Reserved' db 'Copyright (C) 1985 ' db 'Digital Research Inc.' cseg ; public graph_seg_high public graph_seg_low public INIT_G,DINIT_G public CONCAT public TRAN_FM public EX_TIMV public S_COLMAP public I_COLMAP ; extrn entry:near ;the place to jump to if this module ;integer array indexing equates W_1 equ word ptr 0 W_2 equ word ptr 2 W_3 equ word ptr 4 W_4 equ word ptr 6 W_5 equ word ptr 8 W_6 equ word ptr 10 W_7 equ word ptr 12 W_8 equ word ptr 14 W_9 equ word ptr 16 W_10 equ word ptr 18 ; include externs.a86 ibmvdi equ 0 ;leave out the old code if for retail ; ; ;**************************************************************** ; IBM STANDARD ROM BIOS CALLS * ;**************************************************************** direct equ true ; direct = true --> don't use ROS calls ; (for example, for two-screen stuff) ; set to false for PCjr SCREEN equ 10H ;interrupts to use for rom routine I/O KEYBD equ 16H rev_vid_on equ 70h ;turn on reverse video bits rev_vid_off equ 07h ;turn off reverse video bits ; read_cur_pos equ 3 ;bios rom calls for char I/O set_cur_pos equ 2 read_char equ 8 write_char equ 9 set_palette equ 0bh get_character equ 0 ;keyboard read ; EJECT ; jmp entry ;if we come in from here, go to real entry graph_seg_high dw seg_high ; graph_seg_low dw seg_low ;**************************************** ;escape func 2 ; Enter Graphics Mode ;**************************************** INIT_G: pushf mov ax,cs mov usermot+2,ax ;init the user call vectors segs mov userbut+2,ax mov usercur+2,ax mov ax,offset umotvec mov usermot,ax mov ax,offset ubutvec mov userbut,ax mov ax,offset mov_cur mov usercur,ax popf escfn2: cmp dispmode,0 jnz escfn2_ok ret escfn2_ok: mov dispmode,0 ; if direct mov dx, 3d8h mov al, 8 out dx,al ;turn graphics on mov dx,3b8h mov al,0 out dx,al mov dx,3b0h mov al,00000001b out dx,al endif call clearmem ; clear graphics display mov bl,1 call mouse_function ;initialize the mouse mov bl,2 call mouse_function mov bl,1 call mouse_function ret ; ;**************************************** ;escape func 3 ; Exit Graphics Mode ;**************************************** DINIT_G: escfn3: cmp dispmode,0 jz escfn3_ok ret escfn3_ok: ; if mouse mov bl,2 call mouse_function endif mov dispmode,1 if direct mov dx, 3d8h mov al, 0 out dx, al mov dx, 3b8h mov al, 00101000b out dx, al mov dx, 3b0h mov al, 00000000b out dx, al endif mov attribute,rev_vid_off if ibmvdi call escfn8 ;home call escfn9 ;clear to end of screen else mov ah,2 ;set cursor position 0,0 xor dx, dx mov bh, dh int 10h mov ah, 9 xor bh, bh mov cx, 2000 mov al, 20h mov bl, 7 int 10h endif ret EJECT ;**************************************************************** ;I_COLMAP * ; ENTRY * ; INTIN[0] = color index * ; INTIN[1] = req or actual flag * ; * ; EXIT * ; INTOUT[0] = color index * ; INTOUT[1] = RED * ; INTOUT[2] = GRN * ; INTOUT[3] = BLU * ; * ; Reg. Used. AX, BX, CX, DX, DI * ; * ;**************************************************************** I_COLMAP: mov bx, INTIN ;check if the index is in range of dev cmp bx, 0 jge i_colmap_chkix jmps i_colmap_badix i_colmap_chkix: cmp bx, num_colors-1 ;test if index is too high jle i_colmap_ixok jmps i_colmap_badix i_colmap_ixok: shl bx, 1 mov bx, MAP_COL[bx] mov di, bx ; di = ptr to act/req col tbls shl di, 1 shl di, 1 add di, bx add di, bx ; mpy ix by 6 to point into table mov si, offset INTOUT+2 mov cx, 3 mov INTOUT, bx ; return the color index mov bx, offset req_col_tbl test INTIN+2, 0ffffh ; if != 0 then return actual values jz i_colmap_load mov bx, offset act_col_tbl i_colmap_load: mov ax, [bx+di] mov [si], ax add di, 2 add si, 2 loop i_colmap_load ret i_colmap_badix: mov INTOUT, -1 ret EJECT ;**************************************************************** ;S_COLMAP * ; ENTRY * ; INTIN[0] = color index * ; INTIN[1] = RED 0 - 1000 * ; INTIN[1] = GRN 0 - 1000 * ; INTIN[1] = BLU 0 - 1000 * ; * ; EXIT * ; * ; * ; Reg. Used. AX, BX, CX, DX, DI * ; * ;**************************************************************** S_COLMAP: mov bx, INTIN ;check if the index is in range of dev cmp bx, 0 jge s_colmap_chkix jmp s_colmap_exit s_colmap_chkix: cmp bx, num_colors-1 ;test if index is too high jle s_colmap_ixok jmp s_colmap_exit s_colmap_ixok: shl bx, 1 mov bx, MAP_COL[bx] mov di, bx ; di = ptr to act/req col tbls shl di, 1 shl di, 1 add di, bx add di, bx ; mpy ix by 6 to point into table mov dx, INTIN+2 ; get the red value call s_colmap_val mov dx, INTIN+4 ; get the grn value call s_colmap_val mov dx, INTIN+6 ; get the blu values call s_colmap_val s_colmap_exit: ret ; s_colmap_val: mov req_col_tbl[di], dx ; save the requested value add di, 2 ; move to the next value ret ;**************************************************************** ;TRAN_FM * ; ENTRY * ; * ; * ; EXIT * ; * ; * ; Reg. Used. AX, BX, CX, DX, DI * ; * ;**************************************************************** TRAN_FM: push bp push es push ds les di,contrl_ptr mov ax, es: word ptr 14[di] mov bx, es: word ptr 16[di] ; get smfdb pointer mov dx, es: word ptr 18[di] mov bp, es: word ptr 20[di] ; get dmfdb pointer mov es, bx mov di, ax ; set es:di to it mov ax, es: word ptr 12[di] ; get num of planes in source ; xform n to n planes push ax ; save the plane count call calc_src_form call calc_des_form call calc_seg_off pop bx ; get the plane count back col_to_col_lp: push si push di push bx push cx col_to_col_loop: lodsw if not byte_swap xchg ah,al endif if rev_vid not ax endif stosw loop col_to_col_loop pop cx pop bx pop di pop si call tran_next_seg dec bx jnz col_to_col_lp pop ds pop es pop bp ret tran_next_seg: push cx mov ax, cx mov cl, 3 shr ax, cl ;get the segment increment mov bp, es add bp, ax mov es, bp mov bp, ds add bp, ax mov ds, bp pop cx mov ax, cx ;get the byte increment and ax, 0007h shl ax, 1 add si, ax add di, ax ret ; calc_seg_off: mov bp, cx ; find the next seg shr bp,1 shr bp,1 shr bp,1 mov dx, cx shl dx, 1 and dx, 000fh ; find the incremental offset ; mov bx,num_planes ret ; calc_des_form: mov ds, bp mov si, dx ; load dmfdb pointer not bx and bx,1 ; invert format mov 10[si],bx ; toggle dest form mov ax, es: word ptr 2[di] ; get source ptr seg mov di, es: word ptr [di] ; offset mov es, ax mov ax, 2[si] mov si, [si] ; get dest ptr seg,offset mov ds, ax xchg si,di ; swap pointers mov ax, es mov dx, ds mov es, dx mov ds, ax ret ; calc_src_form: mov bx, es: word ptr 10[di] ; get the format flag mov ax, es: word ptr 8[di] ; get the width in words mov cx, es: word ptr 6[di] ; get the height in pixels push dx mul cx pop dx mov cx, ax ; cx = word count and bx,bx ; if bx = 0 then dev spec form ret EJECT ;**************************************************************** ;EX_TIMV * ; ENTRY * ; CONTRL 7,8 = NEW VEC * ; EXIT * ; * ; CONTRL 9,10 = OLD VEC * ; INTOUT [0] = TIMER TICK COUNT IN MILLISECS * ; * ;**************************************************************** EX_TIMV: pushf cli push es push ds les di,contrl_ptr xor ax,ax mov ds,ax mov si,4 * 1ch ;setup the offset to timer int vector mov ax,[si] mov es:word ptr 18[di],ax ;save old timer vector mov ax,2[si] mov es:word ptr 20[di],ax mov ax, es:word ptr 14[di] mov [si],ax mov ax, es:word ptr 16[di] mov 2[si],ax pop ds pop es popf mov ax,1 mov CONTRL+8,ax ; flag that data is to be returned mov ax, 55 mov INTOUT, ax ; return the millisec/tick count ret EJECT ;**************************************************************** ;CONCAT * ; ENTRY Reg. BX - X-coordinate (dev. coord.) * ; Reg. AX - Y-coordinate (dev. coord.) * ; * ; EXIT Reg. DI - Physical address * ; Reg. BL - Byte index * ; Reg. ES - Segment address * ; Reg. Used. AX, BX, CX, DX, DI * ; * ;**************************************************************** concat: mov dl, bl ;save low order byte of x-coord and dl, 07h ;mask off data bit index. mov cl, 3 ;set count to 3 shr bx, cl ;bx = x in bytes mov cl, 7 cmp ax, 512 ;is this in the first or second part jl concat1 sub ax, 512 ;make it 0 based in this segment shl ax, cl add ax, bx mov di, ax mov ax, seg_high mov es, ax jmps concat2 concat1: shl ax, cl ;mpy by 128 add ax, bx ;concatenate y and x coordinates in AX mov di, ax ;di = memory address mov ax, seg_low mov es, ax concat2: xor dh, dh mov bx, dx ;bx = bit index into data byte ret EJECT include ibmmdvsp.a86 if mouse cseg include imouse.a86 endif cseg include monmmre1.a86 include monmmre2.a86 dseg include devdata.a86 dispmode dw 1 mode_save db 0 if not rev_vid act_col_tbl dw 0, 0, 0 ;black dw 1000, 1000, 1000 ;white req_col_tbl dw 0, 0, 0 ;black dw 1000, 1000, 1000 ;white else act_col_tbl dw 1000, 1000, 1000 ;white dw 0, 0, 0 ;black req_col_tbl dw 1000, 1000, 1000 ;white dw 0, 0, 0 endif MAP_COL dw 0 dw 1 ;red dw 1 ;green dw 1 ;blue dw 1 ;cyan dw 1 ;yellow dw 1 ;magenta dw 1 ;white dw 1 dw 1 dw 1 dw 1 dw 1 dw 1 dw 1 dw 1