;************************************************************************** ;* DEVICE SPECIFIC ROUTINES * ;* * ;* These routines and equates are device dependant. * ;* * ;* * ;* * ;************************************************************************** ; ;Hist ;17 OCT 83 SR ;color driver modifications done ;31 OCT 83 SR ;bdos call for screen initialization added ;16 Nov 83 WH ;squid support added ; dseg copyright db 'GSX-86 V1.3 28 Dec 83' db 'CPM IBM color screen driver' db 'Serial No. XXXX-0000-654321 ' db 'Digital Research, Inc. ' cseg ; public clearmem public check_escape public escfn0,escfn1,escfn2,escfn3 public escfn4,escfn5,escfn6,escfn7 public escfn8,escfn9,escf10,escf11 public escf12,escf13,escf14,escf15 public escf16,escf17,escf18,escf19 public escf60 public concat public get_loc_key public valuator,choice,get_char public load_lut ; extrn entry:near ;the place to jump to if this module ;is linked in first ; ;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 ; false equ 0 true equ not false val_inc_big equ 10 ;maximum valuator increment val_inc_small equ 1 ;minimum valuator increment EJECT ;**************************************************************** ; screen coordinate equates * ; these must be changed to the values for specific machines * ;**************************************************************** ; xresmx equ 319 ;X - Maximum resolution. yresmx equ 199 ;Y - Maximum resolution. xsize equ 338 ;size of pixel in microns ysize equ 400 ; graph_plane equ 0b800h ;start of graphics segment plane_size equ 04000h ;size of graphics memory msb_first equ true ;set if msb is first out byte_swap equ false ;are bytes swapped multiseg equ true num_segs equ 2 ;number of graphics segments bytes_line equ 80 ;used to compute addresses chars_line equ 80 ;number of characters per line lines_page equ 24 ;lines per alpha screen last_escape equ 60 ;last escape function id last_dri_escape equ 19 mouse equ true ;mouse driver to be included ; ;**************************************************************** ; device dependant equates * ; these may or may not be necessary depending on hardware * ;**************************************************************** ; if multiseg next_line equ plane_size / num_segs ;offset to get to next segment else next_line equ bytes_line endif neg_next_line equ 0-next_line move_to_first equ 0-plane_size+bytes_line move_to_last equ plane_size-bytes_line ;from before first to last curwtx equ 8 ;1/2 width of cross hair curwty equ 8 ;1/2 height of cross hair cur_mot_max_x equ 8 ;how far cursor moves fast in x cur_mot_max_y equ 8 ;how far cursor moves fast in y cur_mot_min_x equ 1 ;how far cursor moves slow in x cur_mot_min_y equ 1 ;how far cursor moves slow in y ; ;*************************************************************** ; CPM STANDARD CALLS ;*************************************************************** STATUS_LINE equ true ;is the status line on? BDOS equ 224 ;BDOS call entry point. CON_STAT equ 0bh ; console status (is a char available?) CON_OUT equ 02h ; console output CON_IN equ 01h ; console input DIRECT_CON_IO equ 06h ; direct console i/o ;!!!!! xios_entry_offset equ 28h ccpm_version equ 14h ccpm_squid_ver equ 31h ; EJECT ; jmp entry ;if we come in from here, go to real entry ; ;**************************************** ;* clearmem * ;* clears graphics memory * ;* uses ax,cx,di * ;* stores zeros in graphics plane * ;**************************************** clearmem: mov ax,graph_plane ; ld in graphics memory address mov es,ax mov cx,plane_size/2 ;number of bytes to zero xor ax,ax mov di,ax rep stosw ; store plane_size zeros in graphmem ret ; ;************************************************************************ ;* escape functions * ;* handle character I/O , alpha and graphics cursor * ;* * ;* ENTRY * ;* contrl points to segment and offset of contrl * ;* intin points to segment and offset of intin * ;* ptsin points to segment and offset of ptsin * ;* intout points to segment and offset of intout * ;* ptsout points to segment and offset of ptsout * ;* * ;* * ;************************************************************************ ; ;**************************************** ;check_escape * ; checks escape function called * ; against last_escape * ;**************************************** check_escape: cmp bx,last_dri_escape jbe its_ok cmp bx,last_escape jne not_ok mov bx,20 ;this is change palette jmps its_ok not_ok: xor bx,bx ;do a nop if its not valid its_ok: ret ; ;**************************************** ;escape func 0 ; Nop ;**************************************** escfn0: ret ; ;**************************************** ;escape func 1 ; Inquire Addressable Character Cells ;**************************************** escfn1: les di,intout mov es:W_1[di], lines_page ; number of addressable rows. mov es:W_2[di], chars_line ; number of addressable columns. ret ;**************************************** ;escape func 2 ; Enter Graphics Mode ;**************************************** escfn2: ; if STATUS_LINE mov cl,CON_OUT mov dl,1bh ;escape int BDOS mov cl,CON_OUT mov dl,30h ;zero int BDOS ;turn off status line endif push ds mov ax,0 mov ds,ax mov bx,410h mov al,[bx] ;get current screen adapter pop ds mov mode_save,al ;save it ; !!!!!! this is where we have to see if we are in the concurrent ; environment, and cannot get into the hardware directly. mov cl,0ch ; get BDOS version int BDOS ;get version mov version_number,ax cmp ah,CCPM_Version ; is this a concurrent O.S.? je $+5 jmp CPM_Enter_Graphics ; go to "Not_Concurrent" if it is not mov cl,0a3h ; get the concurrent revision level int BDOS mov Concur_rev_level,ax cmp al,ccpm_squid_ver ; squid is 31h, old concurrent in 3.0 jae squid_enter_graphics ; if al >= 31h, do the squid entry CCPM_Pre_squid_enter_Graphics: ; else do the pre squid concurrent entr mov si,offset pfk_table call send_code call clearmem ; clear graphics display mov si,offset graphics_mode call send_code ;tell cpm we want med-res color call escfn8 ; home alpha cursor. call escfn9 ; clear alpha display. jmp CCPM_common_enter Squid_Enter_graphics: mov cl,99h int BDOS ;get vcn mov vcn,ax push es mov cl,09ah int BDOS ;get sysdat area push ax mov word ptr sysdat_area,ax mov ax,es mov word ptr sysdat_area+2,ax pop bx mov ax,es:xios_entry_offset[bx] mov cs:word ptr xios_entry,ax mov ax,es:xios_entry_offset+2[bx] mov cs:word ptr xios_entry+2,ax pop es ; push es mov cl,156d ; get the process descriptor block addr int BDOS mov pd_addr,bx mov ax,es:word ptr 10h[bx] ; get the user data area address mov uda,ax pop es ; push es push ds mov al,30 ; call the xios with the mov ch,0 ; enter graphics mode call mov cl,10h mov dl, byte ptr vcn mov bx,uda mov es,bx mov bx,word ptr sysdat_area+2 mov ds,bx callf cs:xios_entry pop ds pop es mov si,offset pfk_table call send_code call escfn8 ; home alpha cursor. call escfn9 ; clear alpha display. call clearmem ; clear graphics display CCPM_Common_Enter: mov cl,2dh ;turn off BDOS error messages to consol mov dl,0ffh int BDOS jmps common_enter CPM_Enter_Graphics: mov si,offset pfk_table call send_code call escfn8 ; home alpha cursor. call escfn9 ; clear alpha display. mov si,offset graphics_mode call send_code ;tell cpm we want med-res color call clearmem ; clear graphics display common_enter: mov si,offset crt_init_table_g call crt_init ;initialize it ourselves too if mouse mov bl,1 call mouse_function ;initialize the mouse endif ret ;!!!!! necessary jump location is code segment for 3.1 environment xios_entry dd escfn2 ; ;**************************************** ;escape func 3 ; Exit Graphics Mode ;**************************************** escfn3: ; call clearmem ; clear graphics display. push ds mov dl,mode_save ;get screen adapter mov ax,0 mov ds,ax mov bx,410h mov [bx],dl ;select default card pop ds mov ax,version_number cmp ah,CCPM_Version ; is this a concurrent O.S.? jne CPM_Exit_Graphics ; go to "Not_Concurrent" if it is not mov ax,Concur_rev_level cmp al,ccpm_squid_ver ; squid is 31h, old concurrent in 3.0 jae squid_exit_graphics ; if al >= 31h, do the squid exit CCPM_Pre_squid_exit_Graphics: ; else do the pre squid concurrent exit jmps CCPM_Common_Exit_Graphics Squid_Exit_Graphics: push es push ds mov al,30 ; !!!!! this is necessary in the mov ch,0 ; concurrent environment mov cl,01h mov dl,byte ptr vcn mov bx,uda mov es,bx mov bx,word ptr sysdat_area+2 mov ds,bx callf cs:xios_entry pop ds pop es CCPM_Common_Exit_Graphics: mov cl,2dh ;turn on BDOS error messages to consol mov dl,0h int BDOS jmps common_exit CPM_Exit_Graphics: mov al,mode_save mov si,offset alpham_mode ;for b/w card and al,30h cmp al,30h ;how are those switches set je mode_found mov si,offset alphac_mode ;for color card mode_found: call send_code ;tell cpm we want alpha common_exit: mov si,offset crt_init_table_a call crt_init ;initialize screen the way it was call escfn8 ;home call escfn9 ;clear to end of screen if STATUS_LINE mov ax,version_number cmp ah,CCPM_Version ; is this a concurrent O.S.? jne CPM_Status_Line_On ; go to "Not_Concurrent" if it is not CCPM_Status_Line_On: mov cl,CON_OUT mov dl,1bh ;escape int BDOS mov cl,CON_OUT mov dl,33h ;one int BDOS ;turn on status line jmps Common_Status_Line_On CPM_Status_Line_On: mov cl,CON_OUT mov dl,1bh ;escape int BDOS mov cl,CON_OUT mov dl,31h ;one int BDOS ;turn on status line Common_Status_Line_On: call escfn8 ;home call escfn9 ;clear to end of screen endif if mouse mov bl,2 call mouse_function endif ret ; ;***************************************************************** ;crt_init ; initializes the display controller with data from table ;***************************************************************** crt_init: mov dx,03d4h ;select port mov bl,0 ;select register mov cl,length crt_init_table_a crt_init_loop: mov al,bl out dx,al inc bx inc dx lodsb out dx,al dec dx loop crt_init_loop inc dx inc dx inc dx inc dx lodsb out dx,al inc dx lodsb out dx,al ret ; ;**************************************** ;escape func 4 ; Cursor Up ;**************************************** escfn4: mov si,offset cur_up jmp send_code ; ;**************************************** ;escape func 5 ; Cursor Down ;**************************************** escfn5: mov si,offset cur_down jmp send_code ; ;**************************************** ;escape func 6 ; Cursor Right ;**************************************** escfn6: mov si,offset cur_right jmp send_code ; ;**************************************** ;escape func 7 ; Cursor Left ;**************************************** escfn7: mov si,offset cur_left jmp send_code ; ;**************************************** ;escape func 8 ; Home Cursor ;**************************************** escfn8: mov si,offset home_cur jmp send_code ; ;**************************************** ;escape func 9 ; Erase to end of screen ;**************************************** escfn9: mov si,offset erase_to_eop jmp send_code ; ;**************************************** ;escape func 10 ; Erase to end of line ;**************************************** escf10: mov si,offset erase_to_eol jmp send_code ; ;**************************************** ;escape func 11 ; Move Cursor to x,y ;**************************************** escf11: les di,intin mov ax,es:[di] add ax,31 mov cur_row,al mov ax,es:W_2[di] add ax,31 mov cur_column,al mov si,offset cur_position jmp send_code ; ;**************************************** ;escape func 12 ; Output text ;**************************************** escf12: les di,contrl mov cx, es: W_4[di] ; get string length. and cx, cx ; test if 0 count jz esc12_done les di,intin escf12cpm: push es push di push cx mov dl,es:[di] mov cl,CON_OUT int BDOS pop cx pop di pop es add di,2 loop escf12cpm esc12_done: ret ; ;**************************************** ;escape func 13 ; Reverse video on ;**************************************** escf13: mov si,offset reverse_on jmp send_code ; ;**************************************** ;escape func 14 ; Reverse video off ;**************************************** escf14: mov si,offset reverse_off jmp send_code ; ;**************************************** ;escape func 15 ; Return Current Cursor Address ;**************************************** escf15: les di,intout mov ax,1 mov es:[di],ax mov es:W_2[di],ax call escfn8 ret ; ;**************************************** ;send_code ; loads cx with count of characters ; outputs characters at [si] ;**************************************** send_code: xor ch,ch mov cl,[si] ;get number of characters to send inc si send_loop: push cx mov cl,CON_OUT mov dl,[si] push si int BDOS pop si inc si pop cx loop send_loop ret ;**************************************** ;escape func 16 ; Return Tablet Status ;**************************************** escf16: les di,intout if mouse mov es:W_1[di],1 ;if mouse then return 1 else mov es:W_1[di],0 ;else return a 0 endif ret ; ;**************************************** ;escape func 17 NOT SUPPORTED ; Hard Copy ;**************************************** escf17: ret ; ;**************************************** ;escape func 18 ; Place graphic cross-hair cursor at x,y ;**************************************** escf18: les di,ptsin mov ax,es:[di] mov gcurx,ax mov ax,es:W_2[di] mov gcury,ax call enable_cross ret ; locator is called before esc19. ;**************************************** ;escape func 19 ; Remove cursor ;**************************************** escf19: call enable_cross esc19d: ret ; ;**************************************** ;escape func 60 ; Change palette on ibm ;**************************************** escf60: les di,intin mov ax,es:[di] cmp ax,1 ja esc60d cmp ax,0 je palette_0 or color_save,20h jmps valid_color palette_0: and color_save,1fh ;clear bit 5 valid_color: mov al,color_save mov dx,03d9h out dx,al esc60d: 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, yresmx ;normalize y-coordinate sub cx, ax mov ax, cx shr ax,1 ;divide y by two because two segments mov dh,cl mov dl, bl ;save low order byte of x-coord and dl, 3 ;mask off data bit index. mov cl, 2 ;set count to 3 shr bx, cl ;shift out 3 lsb of x-coord. mov cx,ax shl ax,1 ;muliply by 80 shl ax,1 add ax,cx shl ax,1 shl ax,1 shl ax,1 shl ax,1 add ax, bx ;concatenate y and x coordinates in AX and dh,1 jz concat1 add ax,next_line ;if odd address, then start at next_line concat1:mov di, ax ;di = memory address xor dh, dh mov bx, dx ;bx = bit index into data byte ret EJECT ; ;************************************************************************ ;*get_loc_key * ;* Get Locator key * ;* Entry none * ;* Exit * ;* al=0 nothing happened * ;* * ;* al=1 button press * ;* ah = character information * ;* * ;* al=2 coordinate information * ;* bx = delta x * ;* cx = delta y * ;* * ;* * ;************************************************************************ get_loc_key: if mouse mov bl,3 call mouse_function and al,al jz get_loc_mouse ret get_loc_mouse: endif mov cl,DIRECT_CON_IO mov dl,0ffh int BDOS and al,al ;is there a character? jz no_position mov ah,al mov al,1 cmp ah,1bh ;is it an escape? jnz locator_done mov cl,DIRECT_CON_IO ;yes then are there others? mov dl,0ffh int BDOS and al,al jnz check_locator ;yes then go get them mov ah,1bh ;else we got an escape mov al,1 locator_done: ret check_locator: xor ah,ah cmp al,'L' jnz no_locator_increment_change xor locator_increment,110b jmps no_position no_locator_increment_change: mov si,offset locator_table add si,locator_increment mov cx,5 locator_key_search: cmp ax,[si] jz got_locator_key add si,12 loop locator_key_search mov ah,al mov al,1 ret got_locator_key: add si,2 mov bx,[si] add si,2 mov cx,[si] mov al,2 ret no_position: xor ax,ax ret if mouse include mouse.a86 endif EJECT ;************************************************************************ ;*valuator * ;* Get valuator increment * ;* Exit * ;* al=0 nothing happened * ;* * ;* al=1 button press * ;* ah = character information * ;* * ;* al=2 coordinate information * ;* bx = delta value * ;* * ;************************************************************************ valuator: mov cl,DIRECT_CON_IO mov dl,0ffh int BDOS and al,al ;is there a character? jz no_value mov ah,al mov al,1 cmp ah,1bh ;is it an escape? jnz valuator_done mov cl,DIRECT_CON_IO ;yes then are there others? mov dl,0ffh int BDOS and al,al jnz check_valuator ;yes then go get them mov ah,1bh ;else we got an escape mov al,1 valuator_done: ret check_valuator: xor ah,ah cmp al,'L' jnz no_increment_change xor valuator_increment,100b jmps no_value no_increment_change: mov si,offset valuator_table add si,valuator_increment mov cx,2 valuator_key_search: cmp ax,[si] jz got_valuator_key add si,8 loop valuator_key_search mov ah,al mov al,1 ret got_valuator_key: add si,2 mov bx,[si] mov al,2 ret no_value: xor ax,ax ret EJECT ; ;************************************************************************ ;* Get choice for choice input * ;* Entry none * ;* * ;* Exit * ;* al=0 nothing happened * ;* * ;* al=1 button press * ;* ah=character information * ;* bx = choice number 1 to max choice keys * ;* * ;************************************************************************ choice: mov cl,DIRECT_CON_IO mov dl,0ffh int BDOS and al,al ;is there a character? jz no_choice mov ah,al mov al,1 cmp ah,1bh ;is it an escape? jnz choice_done mov cl,DIRECT_CON_IO ;yes then are there others? mov dl,0ffh int BDOS and al,al jnz check_choice ;yes then go get them mov ah,1bh ;else we got an escape mov al,1 choice_done: ret check_choice: xor ah,ah mov bx,ax ;move the character sub bl,64 cmp bl,10 ja no_choice mov ax,1 ret no_choice: xor ax,ax ret EJECT ; ;************************************************************************ ;*get_char * ;* Get character for string input * ;* Entry none * ;* * ;* Exit * ;* al=0 nothing happened * ;* * ;* al=1 button press * ;* bx = character information * ;* * ;************************************************************************ get_char: mov cl,DIRECT_CON_IO mov dl,0ffh int BDOS and al,al ;is there a character? jz no_char xor bx,bx mov bl,al mov ax,1 ret no_char: xor ax,ax ret EJECT ;*************************************************************************** ;* load_lut * ;* loads lookup table for background color * ;* si contains address of request_color_table entry * ;* ax contains color index requested * ;* Original data in request_color_table * ;* New data in realized color table * ;* Programs background color lookup table * ;* uses ax,bx,cx,dx,si,di,es * ;* * ;*************************************************************************** load_lut: cmp ax,0 jne load_lut_done ;can't set foreground color mov cx,3 ;three entries to look at mov bx,0 ;initialize mov dl,4 mov di,offset realized_color_table mov ax,500 mov bp,0 lut_loop: mov [di],bp ;clear value cmp [si],bp ;is there a zero in the table je next_color or bl,dl ;no, then this bit should be 1 mov [di],ax cmp [si],ax ;is intensity greater than 500 jbe next_color or bl,8 ;set intensity bit next_color: add si,2 ;next color add di,2 ror dl,1 loop lut_loop cmp bl,7 jne not_gray mov bl,8 ;if its a seven,make it gray jmps inten_done not_gray: test bl,8 jz inten_done mov cx,3 mov di,offset realized_color_table shift_loop: mov ax,[di] shl ax,1 mov [di],ax add di,2 loop shift_loop inten_done: mov dx,3d9h and color_save,30h ;save palette info or color_save,bl mov al,color_save out dx,al ;set background color load_lut_done: ret ; include colibmre.a86 dseg ;*************************************************************************** ;* * ;* Data Area * ;* contains data for escape functions * ;* and the values returned on open_workstation * ;* * ;* * ;* * ;*************************************************************************** ; extrn contrl:dword extrn intin:dword extrn ptsin:dword extrn intout:dword extrn ptsout:dword extrn realized_color_table:byte ; ;!!!!! required in the concurrent 3.1 environment version_number dw 0 concur_rev_level dw 0 vcn dw 0 sysdat_area dd escfn2 pd_addr dw 0 uda dw 0 ; mode_save db 0 color_save db 0 ; crt_init_table_g db 38h,28h,2dh,0ah,7fh,06h,64h,70h,02,01,06,07,0,0 db 0ah,00h ; crt_init_table_a db 71h,50h,5ah,0ah,1fh,06h,19h,1ch,02,07,06,07,0,0 db 29h,10h ; locator_table dw 'C' ;right arrow un shifted dw cur_mot_max_x dw 0 dw 'C' ;right arrow shifted dw cur_mot_min_x dw 0 dw 'D' ;left arrow unshifted dw 0-cur_mot_max_x dw 0 dw 'D' ;left arrow shifted dw 0-cur_mot_min_x dw 0 dw 'A' ;up arrow unshifted dw 0 dw cur_mot_max_y dw 'A' ;up arrow shifted dw 0 dw cur_mot_min_y dw 'B' ;down arrow unshifted dw 0 dw 0-cur_mot_max_y dw 'B' ;down arrow shifted dw 0 dw 0-cur_mot_min_y dw 'H' ;home un shifted dw 0-xresmx dw 0-yresmx dw 'H' ;home shifted dw 0-xresmx dw 0-yresmx ; locator_increment dw 0 valuator_increment dw 0 ; valuator_table dw 'A' ;up arrow unshifted dw val_inc_big dw 'A' ;up arrow shifted dw val_inc_small dw 'B' ;down arrow unshifted dw 0-val_inc_big dw 'B' ;down arrow shifted dw 0-val_inc_small ; cur_up db 2,27,'A' cur_down db 2,27,'B' cur_right db 2,27,'C' cur_left db 2,27,'D' home_cur db 2,27,'H' erase_to_eop db 2,27,'J' erase_to_eol db 2,27,'K' reverse_on db 2,27,'p' reverse_off db 2,27,'q' cur_position db 4,27,'Y' cur_row db 32 cur_column db 32 graphics_mode db 3,27,'a',5 alpham_mode db 3,27,'a',7 alphac_mode db 3,27,'a',2 set_mode_color db 2,27,'x' set_mode_mono db 2,27,'y' set_palette_0 db 3,27,'/',0 set_palette_1 db 3,27,'/',1 set_back_color db 3,27,'c' background db 0 ; pfk_table db 96 ;96 bytes to output db 27,':',';',27,65,0 ;F1 db 27,':','<',27,66,0 db 27,':','=',27,67,0 db 27,':','>',27,68,0 db 27,':','?',27,69,0 db 27,':','@',27,70,0 db 27,':','A',27,71,0 db 27,':','B',27,72,0 db 27,':','C',27,73,0 db 27,':','D',27,74,0 ;F10 db 27,':','H',27,'A',0 ;up arrow db 27,':','K',27,'D',0 ;left db 27,':','M',27,'C',0 ;right db 27,':','P',27,'B',0 ;down db 27,':','G',27,'H',0 ;home db 27,':','R',27,'L',0 ;insert (toggles speed)