;************************************************************************** ;* DEVICE SPECIFIC ROUTINES * ;* * ;* These routines and equates are device dependant. * ;* * ;* * ;* * ;************************************************************************** ;Hist ;Name Date Modification ; cseg copyright db 'GEMVDI V1.0 2/9/85' db 'IBM Enhanced Card lores color' db 'Serial No. XXXX-0000-654321 ' db 'All Rights Reserved' db 'Copyright (C) 1985 ' db 'Digital Research Inc.' ; 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 false ; 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 ;**************************************** ;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 ; push ds mov ax,0 mov ds,ax mov bx,410h mov dl,[bx] ;get current screen adapter mov al,dl and al,0cfh or al,10h mov [bx],al ;select color card pop ds mov mode_save,dl mov ah,0 mov al,0eh ;hi-res graphics int screen call init_lut mov dx, 3c4h mov al, 02 out dx, al ; init the plane mask add reg mov dx, 3ceh mov al, 04 out dx, al call clearmem ; clear graphics display if mouse mov bl,1 call mouse_function ;initialize the mouse mov bl,2 call mouse_function mov bl,1 call mouse_function endif ret init_lut: mov dx,offset initial_color_table mov ah,10h mov al, 2 push ds push ds pop es int 10h pop ds 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 mov dl,mode_save ;get screen adapter push ds mov ax,0 mov ds,ax mov bx,410h mov [bx],dl ;select default card mov ah,0 mov al,3 ;alpha mode int screen pop ds 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 ;**************************************************************** ;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. Used. AX, BX, CX, DX, DI * ; * ;**************************************************************** concat: and bx, 03ffh ;mask off 10 lsb for x-coord. mov cx, bytes_line mul cx 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 ;shift out 3 lsb of x-coord. add ax, bx ;concatenate y and x coordinates in AX mov di, ax ;di = memory address xor dh, dh mov bx, dx ;bx = bit index into data byte 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 xor cx, cx ; init the temp accum 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 mov bh, ch or bh, cl ; the index lut value is done mov ah, 10h xor al, al int 10h ; load it up ret s_colmap_exit: ret ; ; entry ; di = offset within act/real tbl of rgb values ; ch = high order rgb lut bits ; cl = low order rgb lut bits ; dx = intensity value in 0 - 1000 ; s_colmap_val: shl cx, 1 ; move over the lutval by 1 bit mov req_col_tbl[di], dx ; save the requested value cmp dx, 0 jge s_colmap_val_intck xor dx, dx ; if less than 0 map to 0 s_colmap_val_intck: cmp dx, 1000 jl s_colmap_val_intok mov dx, 999 ; map >= 1000 to 999 for simplicity s_colmap_val_intok: mov ax, 166 xor bh, bh s_colmap_val_loop: cmp dx, ax jle s_colmap_val_done add ax, 333 inc bh jmps s_colmap_val_loop s_colmap_val_done: sub ax, 166 cmp ax, 999 jnz s_colmap_val_exit inc ax ; map 999 back to 1000 s_colmap_val_exit: mov act_col_tbl[di], ax add di, 2 ; move to the next value test bh, 1 ; is high bit set jz s_colmap_val_exit1 or ch, 8 s_colmap_val_exit1: test bh, 2 jz s_colmap_val_exit2 or cl, 1 s_colmap_val_exit2: ret EJECT include ibmmdvsp.a86 if mouse cseg include imouse.a86 endif cseg include egammre1.a86 include egammre2.a86 dseg include devdata.a86 ; dispmode dw 1 mode_save db 0 if num_planes eq 4 act_col_tbl dw 1000, 1000, 1000 ;white dw 1000, 0, 0 ;red dw 0, 1000, 0 ;green dw 1000, 1000, 0 ;yellow dw 0, 0, 1000 ;blue dw 1000, 0, 1000 ;magenta dw 0, 1000, 1000 ;cyan dw 0, 0, 0 ;black dw 333, 333, 333 ;grey dw 333, 0, 0 ;light red dw 0, 333, 0 ;light green dw 333, 333, 0 ;light yellow dw 0, 0, 333 ;light blue dw 333, 0, 333 ;light magenta dw 0, 333, 333 ;light cyan dw 0, 0, 0 ;black req_col_tbl dw 1000, 1000, 1000 ;white dw 1000, 0, 0 ;red dw 0, 1000, 0 ;green dw 1000, 1000, 0 ;yellow dw 0, 0, 1000 ;blue dw 1000, 0, 1000 ;magenta dw 0, 1000, 1000 ;cyan dw 0, 0, 0 ;black dw 333, 333, 333 ;grey dw 333, 0, 0 ;light red dw 0, 333, 0 ;light green dw 333, 333, 0 ;light yellow dw 0, 0, 333 ;light blue dw 333, 0, 333 ;light magenta dw 0, 333, 333 ;light cyan dw 0, 0, 0 ;black initial_color_table db 00010111b ;pel val = 0 white db 00010100b ;pel val = 1 red db 00010010b ;pel val = 2 green db 00010110b ;pel val = 3 yellow db 00010001b ;pel val = 4 blue db 00010101b ;pel val = 5 magenta db 00010011b ;pel val = 6 cyan db 00000111b ;pel val = 7 black db 00010000b ;pel val = 0 grey db 00000100b ;pel val = 1 lt red db 00000010b ;pel val = 2 lt green db 00000110b ;pel val = 3 lt yellow db 00000001b ;pel val = 4 lt blue db 00000101b ;pel val = 5 lt magenta db 00000011b ;pel val = 6 lt cyan db 00000000b ;pel val = 7 black db 0 ;overscan = 0 MAP_COL dw 0 ;white dw 0fh ;black dw 1 ;red dw 2 ;green dw 4 ;blue dw 6 ;cyan dw 3 ;yellow dw 5 ;magenta dw 7 ;white dw 8 ;black dw 9 ;lt red dw 10 ;lt green dw 12 ;lt blue dw 14 ;lt cyan dw 11 ;lt yellow dw 13 ;lt magenta else act_col_tbl dw 1000, 1000, 1000 ;white dw 1000, 0, 0 ;red dw 0, 1000, 0 ;green dw 1000, 1000, 0 ;yellow dw 0, 0, 1000 ;blue dw 1000, 0, 1000 ;magenta dw 0, 1000, 1000 ;cyan dw 0, 0, 0 ;black dw 333, 333, 333 ;grey dw 333, 0, 0 ;light red dw 0, 333, 0 ;light green dw 333, 333, 0 ;light yellow dw 0, 0, 333 ;light blue dw 333, 0, 333 ;light magenta dw 0, 333, 333 ;light cyan dw 0, 0, 0 ;black req_col_tbl dw 1000, 1000, 1000 ;white dw 1000, 0, 0 ;red dw 0, 1000, 0 ;green dw 1000, 1000, 0 ;yellow dw 0, 0, 1000 ;blue dw 1000, 0, 1000 ;magenta dw 0, 1000, 1000 ;cyan dw 0, 0, 0 ;black dw 333, 333, 333 ;grey dw 333, 0, 0 ;light red dw 0, 333, 0 ;light green dw 333, 333, 0 ;light yellow dw 0, 0, 333 ;light blue dw 333, 0, 333 ;light magenta dw 0, 333, 333 ;light cyan dw 0, 0, 0 ;black initial_color_table db 00010111b ;pel val = 0 white db 00010100b ;pel val = 1 red db 00010010b ;pel val = 2 green db 00010110b ;pel val = 3 yellow db 00010001b ;pel val = 4 blue db 00010101b ;pel val = 5 magenta db 00010011b ;pel val = 6 cyan db 00000000b ;pel val = 7 black db 00010111b ;pel val = 0 white db 00010100b ;pel val = 1 red db 00010010b ;pel val = 2 green db 00010110b ;pel val = 3 yellow db 00010001b ;pel val = 4 blue db 00010101b ;pel val = 5 magenta db 00010011b ;pel val = 6 cyan db 00000000b ;pel val = 7 black db 0 ;overscan = 0 MAP_COL dw 0 ;white dw 7 ;black dw 1 ;red dw 2 ;green dw 4 ;blue dw 6 ;cyan dw 3 ;yellow dw 5 ;magenta dw 7 ;white dw 7 ;black dw 7 ;lt red dw 7 ;lt green dw 7 ;lt blue dw 7 ;lt cyan dw 7 ;lt yellow dw 7 ;lt magenta endif