;************************************************************************** ;* DEVICE SPECIFIC ROUTINES * ;* Hercule's Card * ;* These routines and equates are device dependant. * ;* * ;* * ;* * ;************************************************************************** ;hist ;Name Date Modification ;DH 9/30/83 Choice returns char ; Clear uses bakcol ;DH 9/30/83 Fixed prog func key bug ;WH 11/20/82 Squid support added dseg copyright db 'GSX-86 V1.3 28 Dec 83' db 'CPM Hercules 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 concat public valuator,choice,get_char public plyfill_rot public abline,draw_char public next_address public enable_cross,move_cross,clip_cross,get_loc_key public device_table , size_table public gcurx,gcury public y1,y2,x1,x2 public lstlin public arstl2 ; 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 xresmx equ 719 ;X - Maximum resolution. yresmx equ 347 ;Y - Maximum resolution. xsize equ 68 ;size of pixel in microns ysize equ 91 ; graph_plane equ 0b800h ;start of graphics segment plane_size equ 08000h ;size of graphics memory msb_first equ true ;set if msb is first out byte_swap equ false multiseg equ true num_segs equ 4 ;number of graphics segments bytes_line equ 90 ;used to compute addresses chars_line equ 80 ;number of characters per line lines_page equ 24 ;lines per alpha screen last_escape equ 19 ;last escape function id last_dri_escape equ 19 ;last dri defined escape mouse equ true ;is mouse available ; ;**************************************************************** ; 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 16 ;1/2 width of cross hair curwty equ 12 ;1/2 height of cross hair cur_mot_max_x equ 16 ;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 mov al,bakcol mov ah,al mov di,0 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 jna 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 mov si,offset pfk_table call send_code call escfn8 ; home alpha cursor. call escfn9 ; clear alpha display. 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.? jne 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 call clearmem ; clear graphics display jmps CCPM_Common_Enter_Graphics 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 call clearmem CCPM_Common_Enter_Graphics: mov cl,2dh ;turn off BDOS error messages to consol mov dl,0ffh int BDOS jmps common_enter CPM_Enter_Graphics: call clearmem ; clear graphics display common_enter: mov al,82h 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: ; 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,0 ;start at es:0 rep stosw ; store plane_size zeros in graphmem mov dl,mode_save ;get screen adapter push ds 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: common_exit: mov al,20h 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 ;three 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: push ax mov dx,3b8h out dx,al mov dx,03b4h ;select port mov cx,12 xor ah,ah crt_init_loop: mov al,ah out dx,al inc dx lodsb out dx,al inc ah dec dx loop crt_init_loop mov dx,3b8h pop ax add al,8 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: 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 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 * ; * ;**************************************************************** EJECT 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 shr ax,1 mov dh,cl 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. mov cl,bytes_line mul cl ;brute force calculation ;use shift and add if possible add ax, bx ;concatenate y and x coordinates in AX and dh,3 jz concat1 mov cl,dh xor ch,ch concat0: add ax,next_line ;if odd address, then start at next_line loop concat0 concat1:mov di, ax ;di = memory address xor dh, dh mov bx, dx ;bx = bit index into data byte ret ; ;************************************************************************ ;*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,2 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,2 choice_done: ret check_choice: xor bh,bh 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 ; include monommre.a86 dseg ;*************************************************************************** ;* * ;* Data Area * ;* contains data for escape functions * ;* and the values returned on open_workstation * ;* * ;* * ;* * ;*************************************************************************** ; extrn txtclx:word ;text color index extrn txtcol:byte ;text writing mode extrn wrmode:word ;writing mode extrn plncol:byte ;polygon color index extrn style:word ;line style extrn contrl:dword extrn intin:dword extrn ptsin:dword extrn intout:dword extrn ptsout:dword extrn bakcol:byte ;background color of screen(0/ff) ; 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 ; ; crt_init_table_g db 35h,2dh,2eh,07h db 5bh,2h,57h,57h db 2,3,0,0 ; crt_init_table_a db 61h,50h,52h,0fh,19h,6h,19h,19h,2,0dh,0bh,0ch ; ; ; 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 ; pfk_table db 96 ;96 bytes to output db 27,':',';',27,1,0 ;F1 db 27,':','<',27,2,0 db 27,':','=',27,3,0 db 27,':','>',27,4,0 db 27,':','?',27,5,0 db 27,':','@',27,6,0 db 27,':','A',27,7,0 db 27,':','B',27,8,0 db 27,':','C',27,9,0 db 27,':','D',27,10,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)