%TITLE "WorkStation I/O - CHiPS bv 1997" ;********************************************************************** ;** ** ;** Program : WSIO ** ;** Purpose : WorkStation Input/Output ** ;** ** ;** Author : B.F. Schreurs ** ;** Computer High Performance Software (CHiPS) bv ** ;** Date : November 20th, 1997 ** ;** ** ;** Calls : [None] ** ;** ** ;** Language : Turbo Assembler ** ;** ** ;********************************************************************** IDEAL JUMPS ;---------------------------------------------------------------------- ;-- Functions which can be called -- ;---------------------------------------------------------------------- PUBLIC WSIO ;---------------------------------------------------------------------- ;-- Equates -- ;---------------------------------------------------------------------- include ".\equ\dos.equ" include ".\equ\keyboard.equ" include ".\equ\mouse.equ" include ".\equ\sysdep.equ" include ".\equ\video.equ" include ".\equ\wsio.equ" SCREEN_SAVE_TABLE_MAX EQU 10 SCREEN_SAVE_STRUCTURE_SIZE EQU 14 SCREEN_NAME_SIZE EQU 8 KEY_ALPHA EQU "ABCDEFGHIJKLMNOPQRSTUVWXYZ " KEY_NUMERIC EQU "0123456789.,+- " KEY_SPECIAL EQU "@#$" KEY_FILEMASK EQU "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ*\:!#$%&_()'?~^³ñ`ø÷@.- " ;********************************************************************** SEGMENT SSeg Para Stack 'STACK' ;********************************************************************** db 64 dup (0) ; Stack ENDS SSeg ;********************************************************************** SEGMENT DSeg Word Public 'DATA' ;********************************************************************** ;---------------------------------------------------------------------- ;-- Structures -- ;---------------------------------------------------------------------- include ".\str\position.str" include ".\str\wsio.str" Struc Screen_Save Screen_Name DB 8 dup (NULL) Save_Address_Hi DW ? ; Save Area Memory Address HIGH Save_Address_Lo DW ? ; Save Area Memory Address LOW Cursor_Position_Org Position <> ; Location of Cursor of prev screen ends ; Screen_Save ;---------------------------------------------------------------------- ;-- Working Storage -- ;---------------------------------------------------------------------- Return_Code DW NULL Allocation_Strategy_Old DW NULL Allocation_Strategy_New DW NULL ;-------------------------------- ; Saved screen information/tables ;-------------------------------- Screen_Save_Table Screen_Save SCREEN_SAVE_TABLE_MAX dup (<>) Screen_Save_ptr_es DW NULL Screen_Save_ptr_di DW NULL Screen_Name_Last_Used_Wsio_Hi DW ? Screen_Name_Last_Used_Wsio_Lo DW ? ;----------- ; Mouse info ;----------- Pixels_Per_Row DW 0 Pixels_Per_Col DW 0 ;------------ ; Screen info ;------------ Wsio_Initialize DB LOGIC_NO Wsio_No_Input DB LOGIC_NO Wsio_Mouse_Visible DB LOGIC_NO Wsio_Mouse_Present DB LOGIC_NO Wsio_Mouse_Left_Button_Pressed DB LOGIC_NO Wsio_Area_ptr_es DW NULL Wsio_Area_ptr_di DW NULL Wsio_Rows DW NULL Wsio_Cols DW NULL Wsio_Field_Nr_Max DW NULL Wsio_Field_Nr_Mod_Max DW NULL Temp_Wsio_Field_Modifiable DB 0 Temp_Wsio_Field_Mouse_Sensitive DB 0 Save_Wsio_Field_Modifiable DB 0 Save_Wsio_Input_Select_Attrib DB 0 Save_Wsio_Select_Field_Nr DB 0 Save_Wsio_Select_Field_Occur_Nr DB 0 Save_Wsio_Select_Field_Attrib DB 0 ; ; Fields below have the same layout and size as the Wsio structure!!! ; Structure size is WSIO_STRUCTURE_SIZE ; Wsio_Command DB WSIO_OPEN Wsio_Start_Row DB 1 ; Start of screen ROW Wsio_Start_Col DB 1 ; Start of screen COLUMN Wsio_End_Row DB 24 ; End of screen ROW Wsio_End_Col DB 80 ; End of screen COLUMN Wsio_Screen_Attrib DB 0 ; Screen attribute, 0=don't change it Wsio_Field_Attrib DB 0 ; Field attribute, 0=don't change it Wsio_Input_Select_Attrib DB 0 ; Input/Select attribute, input or selected Wsio_Error_Attrib DB 0 ; Input error attribute Wsio_Mouse_Support DB LOGIC_NO ; No Mouse Support Wsio_Select_Field_Nr DB 1 ; Cursor positioned at Active Window field nr Wsio_Select_Field_Occur_Nr DB 1 ; Cursor positioned at Active Window field occurrence Wsio_Select_Field_Position DB 1 ; Cursor positioned at Active Window field position Wsio_Screen_Changed DB LOGIC_NO ; Screen changed, No=LOGIC_NO, Yes=LOGIC_YES Wsio_Cursor_Row DB 1 ; Position at screen location row Wsio_Cursor_Col DB 1 ; Position at screen location col Wsio_Name_Address_Hi DW ? ; Screen Name Address HIGH Wsio_Name_Address_Lo DW ? ; Screen Name Address LOW Wsio_Text_Address_Hi DW ? ; Text Address HIGH Wsio_Text_Address_Lo DW ? ; Text Address LOW Wsio_Attrib_Address_Hi DW ? ; Attribute Table Address HIGH Wsio_Attrib_Address_Lo DW ? ; Attribute Table Address LOW Wsio_Keys_Address_Hi DW ? ; Valid Keys Address HIGH Wsio_Keys_Address_Lo DW ? ; Valid Keys Address LOW Wsio_Enter_Address_Hi DW ? ; Enter Emul Keys Address HIGH Wsio_Enter_Address_Lo DW ? ; Enter Emul Keys Address LOW Wsio_Field_Address_Hi DW ? ; Field Area Table Address HIGH Wsio_Field_Address_Lo DW ? ; Field Area Table Address LOW ;------------------ ; Active field info ;------------------ Wsio_Field_Curr_Char DB SPACE Wsio_Field_Curr_Occur DB 0 Wsio_Field_Data_Save DB MAX_COL dup (SPACE) Wsio_Field_Change DB LOGIC_NO ; ; Fields below have the same layout and size as the Wsio_Field structure!!! ; Structure size is WSIO_FIELD_STRUCTURE_SIZE ; Wsio_Field_Start_Row DB 1 ; Rel. Start of field ROW, NULL=End Wsio_Field_Start_Col DB 1 ; Rel. Start of field COLUMN Wsio_Field_Size DB 1 ; Field size Wsio_Field_Occurs DB 1 ; Nr of occurrences Wsio_Field_Offset DW 0 ; Add this value to the field size to get to the next element, if this element is part of a table Wsio_Field_Modifiable DB 0 ; 0=Protected 1=Modifiable Wsio_Field_Mouse_Sensitive DB 0 ; 0=No, Any other key is the value to be emulated Wsio_Field_Edit DB 0 ; 0=External 1=Any 2=Nrs 3=Letters 4=Nrs+Letters 5=Nrs+Letters+@#$ 6=Filemask 7=Hexadecimal Wsio_Field_Blank DB 0 ; 0=Anywhere 1=Trailing 2=None Wsio_Field_Uppercase DB 0 ; 0=Upper 1=Upper+Lower Wsio_Field_Backspace DB 0 ; Backspace mode, 0=Destructive backspace, 1=Restore character from source data field Wsio_Field_Digits_Before DB 0 ; Digits before dot, max. 15 Wsio_Field_Digits_After DB 0 ; Digits after dot, max 3 Wsio_Field_Negative DB LOGIC_NO ; Can the number be negative Wsio_Field_Decimal_Point DB DECIMAL_SEPERATOR Wsio_Field_Date_Time_Format DB 0 ; Date Format, 0=dd, 1=mm 2=yy, 3=ccyy, 4=yymm, 5=yymmdd, 6=ccyymmdd, 7=ddmmyy, 8=ddmmccyy, 9=hh, 10=mm, 11=ss, 12=tt, 13=hhmm, 14=hhmmss, 15=hhmmsstt, 16=ccyymmddhhmmsstt Wsio_Field_Changed DB LOGIC_NO ; Field changed, LOGIC_NO=No, LOGIC_YES=Yes Wsio_Field_Data_Src_ptr_es DW ? ; Field Data Source Address HIGH Wsio_Field_Data_Src_ptr_di DW ? ; Field Data Source Address LOW Wsio_Field_Data_Obj_ptr_es DW ? ; Field Data Object Address HIGH Wsio_Field_Data_Obj_ptr_di DW ? ; Field Data Object Address LOW Wsio_Field_Video_ptr_es DW ? ; Attribute Address HIGH Wsio_Field_Video_ptr_di DW ? ; Attribute Address LOW Wsio_Field_Keys_ptr_es DW ? ; Valid Keys Address HIGH Wsio_Field_Keys_ptr_di DW ? ; Valid Keys Address LOW ;----------- ; Edit Masks ;----------- Edit_Mask_1_Any DB ? Edit_Mask_2_Nrs DB KEY_NUMERIC DB NULL Edit_Mask_3_Letters DB KEY_ALPHA DB NULL Edit_Mask_4_Nrs_Letters DB KEY_ALPHA DB KEY_NUMERIC DB NULL Edit_Mask_5_Nrs_Let_Spc DB KEY_ALPHA DB KEY_NUMERIC DB KEY_SPECIAL DB NULL Edit_Mask_6_Filemask DB KEY_FILEMASK DB NULL Edit_Mask_7_Hexadecimal DB "0123456789ABCDEF" DB NULL Edit_Mask_8_Tabable DB NULL ;----------------------- ; Video memory addresses ;----------------------- Video_Address_Base DW VIDEO_MODE_COLOR_BASE Video_Address_Offset DW 0 Video_Address_ptr_es DW 1 dup (NULL) Video_Address_ptr_di DW 1 dup (NULL) ;---------------- ; M e s s a g e s ;---------------- Msg_Ok DW 000 ; Screen I/O ok Msg_Screen_Not_Altered DW 001 ; Screen has not been altered Msg_Err_Wsio_Open DW 002 ; Screen already open Msg_Err_No_Empty_Slot DW 003 ; No empty screen slot, all slots in use Msg_Err_Memory_Alloc DW 004 ; Memory Allocation Error Msg_Err_Wsio_Not_Found DW 005 ; Screen save area somehow disappeared ENDS DSeg ;********************************************************************** SEGMENT CSeg Word Public 'CODE' ;********************************************************************** ;********************************************************************** PROC WSIO ;********************************************************************** ASSUME cs:CSeg ASSUME ds:DSeg mov ax, DSeg ; Initialize DS to address mov ds, ax ; of data segment mov bx, sp mov ax, [ss:bx+2] ; si mov bx, [ss:bx+4] ; ds mov [Wsio_Area_ptr_es], bx mov [Wsio_Area_ptr_di], ax push ds si es di mov si, offset Wsio_Command push ds si pop di es mov si, ax mov ds, bx mov cx, WSIO_STRUCTURE_SIZE rep movsb pop di es si ds call Process_Initialize call Process_Passed_Parameters call Process_Wsio_Command mov ah, [byte Return_Code] ret ENDP WSIO ;********************************************************************** PROC Process_Initialize ;********************************************************************** cmp [Wsio_Initialize], LOGIC_YES ; Initialize executed? je @@99 ; Yes ; No, so mov [Wsio_Initialize], LOGIC_YES mov [Wsio_Mouse_Present], LOGIC_NO ;------------------------ ; Determine Video Address ;------------------------ mov [Video_Address_Base], VIDEO_MODE_COLOR_BASE xor ax, ax mov ah, VIDEO_GET_MODE int VIDEO_SERVICE ; Get Video Mode cmp al, VIDEO_MODE_MONO ; Monochrome Mode? jne @@10 ; No ; Yes, so mov [Video_Address_Base], VIDEO_MODE_MONO_BASE ;-------------- ; Mouse support ;-------------- @@10: mov ax, MOUSE_RESET_MOUSE int MOUSE_SERVICE cmp ax, NULL ; Mouse available? je @@99 ; No ; Yes, so mov [Wsio_Mouse_Present], LOGIC_YES mov [Wsio_Mouse_Visible], LOGIC_NO ; ; Get pixel sizes ; mov ax, MOUSE_GET_MAXIMUM_COORDINATES int MOUSE_SERVICE inc cx ; Column size in pixels inc dx ; Row size in pixels mov ax, 8 ; Assume 8 pixels per char horizontal mov bx, 8 ; Assume 8 pixels per char vertical cmp cx, 640 ; 640 pixels horizontal? je @@20 ; Yes ; No, so @@20: mov [Pixels_Per_Col], ax cmp dx, 192 ; 192 pixels vertical? je @@30 ; Yes ; No, so @@30: mov [Pixels_Per_Row], bx @@99: ret ENDP Process_Initialize ;********************************************************************** PROC Process_Passed_Parameters ;********************************************************************** mov ax, NULL mov [Return_Code], ax xor cx, cx xor dx, dx mov cl, [Wsio_End_Row] inc cl mov dl, [Wsio_Start_Row] sub cl, dl mov [Wsio_Rows], cx mov dl, [Wsio_End_Col] inc dl mov cl, [Wsio_Start_Col] sub dl, cl mov [Wsio_Cols], dx mov cl, [Wsio_Start_Row] mov dl, [Wsio_Start_Col] mov [Save_Wsio_Select_Field_Nr], 0 mov [Save_Wsio_Select_Field_Occur_Nr], 0 mov al, [Wsio_Input_Select_Attrib] mov [Save_Wsio_Input_Select_Attrib], al mov di, [Video_Address_Offset] ; Videomap Offset mov es, [Video_Address_Base] ; Videomap Base @@10: add di, (MAX_COL * 2) loop @@10 sub di, (MAX_COL * 2) add di, dx add di, dx sub di, 2 ; Correct video location reached mov [Video_Address_ptr_es], es mov [Video_Address_ptr_di], di ;-------------------------------------- ; Check cursor row/col for location 0,0 ;-------------------------------------- cmp [Wsio_Cursor_Row], 0 ; Jump to pre-specified or first modifiable field? jne @@80 ; No ; Yes, so xor cx, cx ; Reset cx ; ; Assume top left cursor position ; mov ah, [Wsio_Start_Row] ; Assume top left first mov al, [Wsio_Start_Col] ; of current window ; in case of no (modifiable) field mov [Wsio_Cursor_Row], ah mov [Wsio_Cursor_Col], al ; ; Check Field Table ; mov bx, [Wsio_Field_Address_Hi] mov di, [Wsio_Field_Address_Lo] mov es, bx cmp bx, NULL ; Address specified? je @@80 ; No, ; Yes, so ; ; Check (Next) Field ; @@30: cmp [byte es:di], NULL ; Fields left to check? je @@80 ; No ; Yes, so cmp [Wsio_Select_Field_Nr], 0 ; Field nr specified? je @@40 ; No ; Yes, so inc cl ; Field counter cmp cl, [Wsio_Select_Field_Nr] ; Specified Field nr reached? je @@60 ; Yes ; No, so jmp @@50 ; Check next field @@40: cmp [(Wsio_Field ptr di).Modifiable], 1 ; Modifiable? je @@60 ; Yes ; No, so @@50: add di, WSIO_FIELD_STRUCTURE_SIZE ; Point to next field jmp @@30 ; Check next field @@60: ; ; Field found to point the cursor at ; mov ah, [Wsio_Start_Row] add ah, [(Wsio_Field ptr di).Start_Row] dec ah mov al, [Wsio_Start_Col] add al, [(Wsio_Field ptr di).Start_Col] dec al ; ; Position at selected occurrence (if any) ; cmp [Wsio_Select_Field_Occur_Nr], 0 ; Occurrence nr specified? je @@70 ; No ; Yes, so add ah, [Wsio_Select_Field_Occur_Nr] dec ah ; Occurrence reached ; ; Position at selected position (if any) ; cmp [Wsio_Select_Field_Position], 0 ; Position specified? je @@70 ; No ; Yes, so add al, [Wsio_Select_Field_Position] dec al ; Position reached @@70: ; ; Set cursor to selected field ; mov [Wsio_Cursor_Row], ah mov [Wsio_Cursor_Col], al @@80: ; ; Check for cursor off screen ; mov [Wsio_No_Input], LOGIC_NO cmp [Wsio_Cursor_Row], CURSOR_OFF_SCREEN jne @@99 mov [Wsio_No_Input], LOGIC_YES @@99: ret ENDP Process_Passed_Parameters ;********************************************************************** PROC Process_Wsio_Command ;********************************************************************** cmp [Wsio_Command], WSIO_OPEN je @@10 cmp [Wsio_Command], WSIO_DISPLAY_ONLY je @@20 cmp [Wsio_Command], WSIO_DISPLAY_TEXT_ONLY je @@23 cmp [Wsio_Command], WSIO_DISPLAY_FIELDS_ONLY je @@25 cmp [Wsio_Command], WSIO_READ_ONLY je @@30 cmp [Wsio_Command], WSIO_DISPLAY_AND_READ je @@40 cmp [Wsio_Command], WSIO_SELECT_DESELECT je @@50 cmp [Wsio_Command], WSIO_KEY_CHECK je @@60 cmp [Wsio_Command], WSIO_CLOSE je @@70 ; ; Command Error ; jmp @@99 @@10: ;-------- ; O P E N ;-------- call Wsio_Command_Open jmp @@99 @@20: ;------------------------ ; D I S P L A Y O N L Y ;------------------------ call Wsio_Command_Display_Only jmp @@99 @@23: ;---------------------------------- ; D I S P L A Y T E X T O N L Y ;---------------------------------- call Wsio_Command_Display_Text_Only jmp @@99 @@25: ;-------------------------------------- ; D I S P L A Y F I E L D S O N L Y ;-------------------------------------- call Wsio_Command_Display_Fields_Only jmp @@99 @@30: ;------------------ ; R E A D O N L Y ;------------------ call Wsio_Command_Read_Only jmp @@99 @@40: ;-------------------------------- ; D I S P L A Y A N D R E A D ;-------------------------------- call Wsio_Command_Display_And_Read jmp @@99 @@50: ;------------ ; S E L E C T ;------------ call Wsio_Command_Select_Deselect jmp @@99 @@60: ;--------------- ; KEY CHECK ONLY ;--------------- call Wsio_Command_Key_Check jmp @@99 @@70: ;---------- ; C L O S E ;---------- call Wsio_Command_Close jmp @@99 @@99: ret ENDP Process_Wsio_Command ;********************************************************************** PROC Wsio_Command_Open ;********************************************************************** ; ; Check on screen name ; mov bx, [Wsio_Name_Address_Hi] mov di, [Wsio_Name_Address_Lo] mov es, bx mov si, offset Screen_Save_Table.Screen_Name mov bx, HIGH_VALUES mov cx, SCREEN_SAVE_TABLE_MAX @@20: push cx cmp [byte ds:si], NULL ; Empty entry found? jne @@30 ; No ; Yes, so cmp bx, HIGH_VALUES ; Was there an empty already? jnz @@40 ; Yes ; No, so mov bx, SCREEN_SAVE_TABLE_MAX sub bx, cx ; Store free entry nr jmp @@40 @@30: push ds si es di mov cx, SCREEN_NAME_SIZE ; Compare Size rep cmpsb ; Screen already exist? pop di es si ds jne @@40 ; No ; Yes, so ; ; Error, Screen already exist or open ; pop cx mov ax, [Msg_Err_Wsio_Open] mov [Return_Code], ax jmp @@99 @@40: pop cx add si, SCREEN_SAVE_STRUCTURE_SIZE loop @@20 ; ; Check for empty slot to store the screen info ; cmp bx, HIGH_VALUES ; Is there an empty slot? jne @@50 ; Yes ; No, so mov ax, [Msg_Err_No_Empty_Slot] mov [Return_Code], ax jmp @@99 @@50: ; ; Save Screen Name ; mov si, offset Screen_Save_Table.Screen_Name mov cx, bx mov ax, SCREEN_SAVE_STRUCTURE_SIZE mul cx add si, ax mov [Screen_Save_ptr_es], ds mov [Screen_Save_ptr_di], si push ds si es di push ds si es di pop si ds di es mov cx, SCREEN_NAME_SIZE ; Copy Size rep movsb ; Copy Screen Name pop di es si ds ; ; Determine Memory Strategy ; mov ax, DOS_GET_ALLOCATION_STRATEGY int DOS_SERVICE mov [Allocation_Strategy_Old], ax mov [Allocation_Strategy_New], ax mov bx, [Allocation_Strategy_New] or bx, DOS_STRATEGY_MEM_UMB_CONV or bx, DOS_STRATEGY_MEM_BEST_FIT mov [Allocation_Strategy_New], bx mov ax, DOS_SET_ALLOCATION_STRATEGY mov bx, [Allocation_Strategy_New] int DOS_SERVICE ; Set new strategy jnc @@60 ; Failed? ; Yes, so mov ax, DOS_SET_ALLOCATION_STRATEGY mov bx, [Allocation_Strategy_Old] int DOS_SERVICE ; Reset to old strategy @@60: ; ; Allocate Memory for Save Screen Area ; mov ax, [Wsio_Rows] mov cx, [Wsio_Cols] mul cx mov cx, 2 ; Because of video structure mul cx ; being character + attribute mov bx, PARAGRAPH xor dx, dx div bx ; dx:ax / bx mov bx, ax inc bx xor cx, cx xor ax, ax ; Reset ax mov ah, DOS_ALLOCATE_MEMORY int DOS_SERVICE ; Allocate Memory in paragraphs mov cx, ax jnc @@70 ; ; Error, Memory Allocation ; mov ax, DOS_SET_ALLOCATION_STRATEGY mov bx, [Allocation_Strategy_Old] int DOS_SERVICE ; Reset to old strategy mov ax, [Msg_Err_Memory_Alloc] mov [Return_Code], ax jmp @@99 @@70: mov ax, DOS_SET_ALLOCATION_STRATEGY mov bx, [Allocation_Strategy_Old] int DOS_SERVICE ; Reset to old strategy ; ; Save Screen Area Pointers ; mov es, [Screen_Save_ptr_es] mov di, [Screen_Save_ptr_di] mov [(Screen_Save ptr di).Save_Address_Hi], cx mov [(Screen_Save ptr di).Save_Address_Lo], NULL ; ; Save Original Cursor Position ; mov ah, VIDEO_GET_CURSOR int VIDEO_SERVICE ; Get Cursor mov [(Screen_Save ptr di).Cursor_Position_Org.Row], dh mov [(Screen_Save ptr di).Cursor_Position_Org.Col], dl ; ; Set cursor position to requested position ; mov dh, [Wsio_Cursor_Row] dec dh mov dl, [Wsio_Cursor_Col] dec dl xor ax, ax xor bx, bx xor cx, cx mov ah, VIDEO_SET_CURSOR int VIDEO_SERVICE ; Set Cursor ; ; Save Screen Area ; mov bx, [Wsio_Rows] mov dx, [Wsio_Cols] mov ax, [Video_Address_ptr_es] mov cx, [Video_Address_ptr_di] mov es, [Screen_Save_ptr_es] mov di, [Screen_Save_ptr_di] push ds si mov es, [(Screen_Save ptr di).Save_Address_Hi] mov di, [(Screen_Save ptr di).Save_Address_Lo] push ax cx pop si ds @@80: mov cx, dx rep movsw mov cx, MAX_COL sub cx, dx shl cx, 1 add si, cx dec bx jnz @@80 pop si ds @@99: ret ENDP Wsio_Command_Open ;********************************************************************** PROC Wsio_Command_Display_And_Read ;********************************************************************** call Wsio_Command_Display_Only call Wsio_Command_Read_Only ret ENDP Wsio_Command_Display_And_Read ;********************************************************************** PROC Wsio_Command_Display_Only ;********************************************************************** call Show_Screen_Text call Show_Screen_Attributes call Show_Screen_Fields ret ENDP Wsio_Command_Display_Only ;********************************************************************** PROC Wsio_Command_Display_Text_Only ;********************************************************************** call Show_Screen_Text call Show_Screen_Attributes ret ENDP Wsio_Command_Display_Text_Only ;********************************************************************** PROC Wsio_Command_Display_Fields_Only ;********************************************************************** call Show_Screen_Fields ret ENDP Wsio_Command_Display_Fields_Only ;********************************************************************** PROC Wsio_Command_Read_Only ;********************************************************************** ;------------------------ ; Determine Mouse Support ;------------------------ cmp [Wsio_Mouse_Support], LOGIC_NO ; Support mouse? je @@04 ; No ; Yes, so mov cx, [Wsio_Name_Address_Hi] ; Same screen? cmp cx, [Screen_Name_Last_Used_Wsio_Hi] jne @@02 ; No ; Maybe mov cx, [Wsio_Name_Address_Lo] ; Same screen? cmp cx, [Screen_Name_Last_Used_Wsio_Lo] je @@04 ; Yes ; No @@02: ; ; Set mouse boundaries ; mov ax, [Wsio_Name_Address_Hi] mov [Screen_Name_Last_Used_Wsio_Hi], ax mov ax, [Wsio_Name_Address_Lo] mov [Screen_Name_Last_Used_Wsio_Lo], ax ; ; Define border limits mouse column, minimum <-> maximum ; xor ax, ax mov al, [Wsio_End_Col] dec ax mov cx, [Pixels_Per_Col] mul cx mov bx, ax xor ax, ax mov al, [Wsio_Start_Col] dec ax mov cx, [Pixels_Per_Col] mul cx mov cx, ax ; Left border mov dx, bx ; Right border mov ax, MOUSE_DEFINE_HOR_CURSOR_RANGE int MOUSE_SERVICE ; ; Define border limits mouse row, minimum <-> maximum ; xor ax, ax mov al, [Wsio_End_Row] dec ax mov cx, [Pixels_Per_Row] mul cx mov bx, ax xor ax, ax mov al, [Wsio_Start_Row] dec ax mov cx, [Pixels_Per_Row] mul cx mov cx, ax ; Top border mov dx, bx ; Bottom border mov ax, MOUSE_DEFINE_VER_CURSOR_RANGE int MOUSE_SERVICE xor ax, ax mov al, [Wsio_End_Col] mov cx, [Pixels_Per_Col] mul cx xor cx, ax xor dx, dx mov ax, MOUSE_POSITION_MOUSE_CURSOR int MOUSE_SERVICE @@04: ;----------------------------- ; Determine field under cursor ;----------------------------- call Determine_Field_Under_Cursor mov ah, [Wsio_Select_Field_Nr] mov al, [Wsio_Select_Field_Occur_Nr] cmp ah, [Save_Wsio_Select_Field_Nr] ; Active Field changed? jne @@06 ; Yes ; No, so cmp al, [Save_Wsio_Select_Field_Occur_Nr] ; Active Field occurrence changed? je @@10 ; No ; Yes, so ;---------------------- ; Deselect old field nr ;---------------------- @@06: mov bh, [Wsio_Input_Select_Attrib] ; Save attrib of new field cmp [Save_Wsio_Select_Field_Nr], 0 ; Something to deselect? je @@08 ; No ; Yes, so mov bl, [Save_Wsio_Select_Field_Nr] mov [Wsio_Select_Field_Nr], bl mov bl, [Save_Wsio_Select_Field_Occur_Nr] mov [Wsio_Select_Field_Occur_Nr], bl mov bl, [Save_Wsio_Select_Field_Attrib] cmp bl, [Save_Wsio_Input_Select_Attrib] ; Input/Select <-> Field attrib changed? je @@08 ; No ; Yes, so mov [Wsio_Input_Select_Attrib], bl cmp [Save_Wsio_Field_Modifiable], 0 ; Protected field? je @@08 ; Yes ; No, so push ax call Wsio_Command_Select_Deselect pop ax ;-------------------- ; Select new field nr ;-------------------- @@08: mov [Save_Wsio_Select_Field_Nr], ah mov [Save_Wsio_Select_Field_Occur_Nr], al mov [Wsio_Select_Field_Nr], ah mov [Wsio_Select_Field_Occur_Nr], al cmp ah, 0 ; Something to select? je @@10 ; No ; Yes, so cmp [Wsio_Field_Modifiable], 0 ; Protected field? je @@10 ; Yes ; No, so mov [Save_Wsio_Select_Field_Attrib], bh ; Save new field attrib mov al, [Save_Wsio_Input_Select_Attrib] ; Input/Select attrib mov [Wsio_Input_Select_Attrib], al ; Set it cmp al, bh ; Will the attribute change? je @@10 ; No ; Yes, so call Wsio_Command_Select_Deselect @@10: ;-------------------------- ; Set cursor position first ;-------------------------- mov dh, [Wsio_Cursor_Row] dec dh mov dl, [Wsio_Cursor_Col] dec dl cmp [Wsio_No_Input], LOGIC_YES ; Disable cursor? jne @@12 ; No ; Yes, so mov dh, CURSOR_OFF_SCREEN mov dl, CURSOR_OFF_SCREEN @@12: xor ax, ax xor bx, bx xor cx, cx mov ah, VIDEO_SET_CURSOR int VIDEO_SERVICE ; Set Cursor ;------------- ; Keyboard I/O ;------------- mov [Wsio_Mouse_Left_Button_Pressed], LOGIC_NO call Wsio_Show_Mouse_Cursor call Keyboard_IO call Wsio_Hide_Mouse_Cursor ;---------------- ; Valid Key Table ;---------------- mov es, [Wsio_Keys_Address_Hi] mov di, [Wsio_Keys_Address_Lo] ;------------------------ ; Check for the "any" key ;------------------------ cmp [byte es:di], KEY_ANY ; "Any" key allowed? je @@93 ; Yes ; No, so ;--------------------- ; Check Mouse activity ;--------------------- cmp [Wsio_Mouse_Left_Button_Pressed], LOGIC_YES ; Left button pressed? je @@04 ; Yes ; No, so ;------------------------ ; Check valid Window keys ;------------------------ cmp ah, 1 ; Special key (Alt+something) je @@18 @@16: ;----------------------------------------- ; Check key press against Valid Keys Table ;----------------------------------------- cmp [byte es:di], NULL ; End of valid keys found? je @@18 ; Yes ; No, so cmp al, [byte es:di] ; Valid key pressed? je @@93 ; Yes ; No, so inc di ; Try next key frm valid key table jmp @@16 ;------------------------------------------------ ; Check if we have modifable fields on the screen ;------------------------------------------------ @@18: cmp [Wsio_Field_Nr_Mod_Max], 0 ; Are there modifiable fields? je @@10 ; No ; Yes, so ;--------------------------------- ; Check if the user disabled input ;--------------------------------- cmp [Wsio_No_Input], LOGIC_YES je @@10 ;----------------------------------------------------------- ; Determine "internal" key press, and process it accordingly ;----------------------------------------------------------- cmp ah, NULL ; Special character pressed? jne @@90 ; No ; Yes, so cmp al, KEY_ARROW_LEFT je @@20 cmp al, KEY_ARROW_RIGHT je @@20 cmp al, KEY_ARROW_UP je @@20 cmp al, KEY_ARROW_DOWN je @@20 cmp al, KEY_HOME je @@20 cmp al, KEY_END je @@20 cmp al, KEY_PAGE_UP je @@20 cmp al, KEY_PAGE_DOWN je @@20 cmp al, KEY_TAB je @@20 cmp al, KEY_BACKTAB je @@20 cmp al, KEY_BACKSPACE je @@20 cmp al, KEY_DELETE je @@20 cmp al, KEY_INSERT je @@20 ; Other key pressed jmp @@90 @@20: ; ; Interpret special character key press ; cmp al, KEY_ARROW_LEFT je @@25 cmp al, KEY_ARROW_RIGHT je @@30 cmp al, KEY_ARROW_UP je @@35 cmp al, KEY_ARROW_DOWN je @@40 cmp al, KEY_HOME je @@45 cmp al, KEY_END je @@50 cmp al, KEY_PAGE_UP je @@55 cmp al, KEY_PAGE_DOWN je @@60 cmp al, KEY_TAB je @@65 cmp al, KEY_BACKTAB je @@70 cmp al, KEY_DELETE je @@75 cmp al, KEY_INSERT je @@80 cmp al, KEY_BACKSPACE je @@85 @@25: ;--------------- ; KEY ARROW LEFT ;--------------- call Wsio_Key_Arrow_Left jmp @@04 @@30: ;---------------- ; KEY ARROW RIGHT ;---------------- call Wsio_Key_Arrow_Right jmp @@04 @@35: ;------------- ; KEY ARROW UP ;------------- call Wsio_Key_Arrow_Up jmp @@04 @@40: ;--------------- ; KEY ARROW DOWN ;--------------- call Wsio_Key_Arrow_Down jmp @@04 @@45: ;--------- ; KEY HOME ;--------- call Wsio_Key_Home jmp @@04 @@50: ;-------- ; KEY END ;-------- call Wsio_Key_End jmp @@04 @@55: ;------------ ; KEY PAGE UP ;------------ call Wsio_Key_Page_Up jmp @@04 @@60: ;-------------- ; KEY PAGE DOWN ;-------------- call Wsio_Key_Page_Down jmp @@04 @@65: ;-------- ; KEY TAB ;-------- call Wsio_Key_Tab jmp @@04 @@70: ;------------ ; KEY BACKTAB ;------------ call Wsio_Key_Backtab jmp @@04 @@75: ;----------- ; KEY DELETE ;----------- call Wsio_Key_Delete jmp @@04 @@80: ;----------- ; KEY INSERT ;----------- call Wsio_Key_Insert jmp @@04 @@85: ;-------------- ; KEY BACKSPACE ;-------------- call Wsio_Key_Backspace jmp @@04 @@90: ;---------- ; OTHER KEY ;---------- call Wsio_Key_Other cmp ax, 0 ; Invalid key? je @@10 ; Yes ; No, so jmp @@04 ;----------------------------------------------------- ; Interpret special key (and see if ENTER was pressed) ;----------------------------------------------------- @@93: ; ; On the "ENTER" key, we process the entered fields ; mov es, [Wsio_Enter_Address_Hi] mov di, [Wsio_Enter_Address_Lo] @@94: cmp [byte es:di], NULL ; End of valid enter keys found? je @@95 ; Yes ; No, so cmp al, [byte es:di] ; Enter emulation found je @@96 ; Yes ; No, so inc di ; Try next key frm valid enter key table jmp @@94 @@95: cmp al, KEY_ENTER jne @@97 ;---------------------------------------- ; "ENTER" pressed, process entered fields ;---------------------------------------- @@96: call Process_Entered_Screen_Fields @@97: ; ; Update Wsio Command Block ; mov es, [Wsio_Area_ptr_es] mov di, [Wsio_Area_ptr_di] mov bl, [Wsio_Screen_Changed] mov [(Wsio_Area ptr di).Screen_Changed], bl mov bl, [Wsio_Cursor_Row] mov [(Wsio_Area ptr di).Cursor_Position_Row], bl mov bl, [Wsio_Cursor_Col] mov [(Wsio_Area ptr di).Cursor_Position_Col], bl @@99: ret ENDP Wsio_Command_Read_Only ;********************************************************************** PROC Wsio_Show_Mouse_Cursor ;********************************************************************** cmp [Wsio_Mouse_Support], LOGIC_NO ; Support mouse? je @@99 ; No ; Yes, so cmp [Wsio_Mouse_Visible], LOGIC_YES ; Mouse_Visible? je @@99 ; Yes ; No, so ; ; Show mouse cursor ; mov ax, MOUSE_SHOW_MOUSE_CURSOR int MOUSE_SERVICE mov [Wsio_Mouse_Visible], LOGIC_YES @@99: ret ENDP Wsio_Show_Mouse_Cursor ;********************************************************************** PROC Wsio_Hide_Mouse_Cursor ;********************************************************************** cmp [Wsio_Mouse_Present], LOGIC_NO ; Mouse present? je @@99 ; No ; Yes, so push ax ; Save pressed key cmp [Wsio_Mouse_Visible], LOGIC_NO ; Mouse visible je @@98 ; No ; Yes, so mov ax, MOUSE_HIDE_MOUSE_CURSOR int MOUSE_SERVICE ; Kill mouse mov [Wsio_Mouse_Visible], LOGIC_NO @@98: pop ax ; Restore pressed key @@99: ret ENDP Wsio_Hide_Mouse_Cursor ;********************************************************************** PROC Wsio_Key_Arrow_Left ;********************************************************************** ; ; Get current cursor position ; mov ah, [Wsio_Cursor_Row] mov al, [Wsio_Cursor_Col] ; ; Move to the left ; cmp al, [Wsio_Start_Col] ; Left edge reached? je @@10 ; Yes ; No, so dec [Wsio_Cursor_Col] ; Move cursor left jmp @@99 ; Show cursor @@10: ; ; Move to previous row, and wrap to the end of the row ; cmp ah, [Wsio_Start_Row] ; Top edge reached? jnle @@20 ; No ; Yes, so mov ah, [Wsio_End_Row] ; Go to bottom edge inc ah ; Because of subtraction below @@20: dec ah ; Move to previous row mov [Wsio_Cursor_Row], ah ; Done mov al, [Wsio_End_Col] ; Go to right edge mov [Wsio_Cursor_Col], al ; Done @@99: ret ENDP Wsio_Key_Arrow_Left ;********************************************************************** PROC Wsio_Key_Arrow_Right ;********************************************************************** ; ; Get current cursor position ; mov ah, [Wsio_Cursor_Row] mov al, [Wsio_Cursor_Col] ; ; Move to the right ; cmp al, [Wsio_End_Col] ; Right edge reached? je @@10 ; Yes ; No, so inc [Wsio_Cursor_Col] ; Move cursor right jmp @@99 ; Show cursor @@10: ; ; Move to next row, and wrap to the begin of the row ; cmp ah, [Wsio_End_Row] ; Bottom edge reached? jl @@20 ; No ; Yes, so mov ah, [Wsio_Start_Row] ; Go to top edge dec ah ; Because of addition below @@20: inc ah ; Move to next row mov [Wsio_Cursor_Row], ah ; Done mov al, [Wsio_Start_Col] ; Go to left edge mov [Wsio_Cursor_Col], al ; Done @@99: ret ENDP Wsio_Key_Arrow_Right ;********************************************************************** PROC Wsio_Key_Arrow_Up ;********************************************************************** ; ; Get current cursor position ; mov ah, [Wsio_Cursor_Row] mov al, [Wsio_Cursor_Col] ; ; Move up ; cmp ah, [Wsio_Start_Row] ; Top edge reached? je @@10 ; Yes ; No, so dec [Wsio_Cursor_Row] ; Move cursor up jmp @@99 ; Show cursor @@10: ; ; Move to bottom edge ; mov ah, [Wsio_End_Row] ; Bottom edge mov [Wsio_Cursor_Row], ah ; Done @@99: ret ENDP Wsio_Key_Arrow_Up ;********************************************************************** PROC Wsio_Key_Arrow_Down ;********************************************************************** ; ; Get current cursor position ; mov ah, [Wsio_Cursor_Row] mov al, [Wsio_Cursor_Col] ; ; Move down ; cmp ah, [Wsio_End_Row] ; Bottom edge reached? je @@10 ; Yes ; No, so inc [Wsio_Cursor_Row] ; Move cursor down jmp @@99 @@10: ; ; Move to top edge ; mov ah, [Wsio_Start_Row] ; Top edge mov [Wsio_Cursor_Row], ah ; Done @@99: ret ENDP Wsio_Key_Arrow_Down ;********************************************************************** PROC Wsio_Key_Home ;********************************************************************** ; ; Check if we are in a modifiable field ; cmp [Wsio_Select_Field_Nr], 0 je @@99 ; No ; Yes, so ; ; Check if we are at the first position of the field ; cmp [Wsio_Select_Field_Position], 1 ; First position? je @@99 ; Yes ; No, so ; ; Determine new cursor position ; mov al, [Wsio_Select_Field_Position] dec al sub [Wsio_Cursor_Col], al @@99: ret ENDP Wsio_Key_Home ;********************************************************************** PROC Wsio_Key_End ;********************************************************************** ; ; Check if we are in a modifiable field ; cmp [Wsio_Select_Field_Nr], 0 je @@99 ; No ; Yes, so ; ; Determine new cursor position ; mov al, [Wsio_Field_Size] ; Get field size sub al, [Wsio_Select_Field_Position] ; Subtract current position add [Wsio_Cursor_Col], al ; Add to cursor position ; ; Determine last video screen position ; mov es, [Wsio_Field_Video_ptr_es] mov di, [Wsio_Field_Video_ptr_di] xor ax, ax mov al, [Wsio_Field_Size] mov cx, ax ; For searching non space dec ax ; Because of offset 0 add di, ax add di, ax ; To skip attributes ; ; Field completely filled? ; cmp [byte es:di], SPACE ; Space found? jne @@99 ; No, show cursor ; Yes, so @@10: ; ; Search non space character from end to beginning ; cmp [byte es:di], SPACE ; Space found? jne @@20 ; No ; Yes, so dec di ; Move 1 character to the left dec di ; Including the attribute dec [Wsio_Cursor_Col] ; Move cursor 1 to the left too loop @@10 ; Check next character ; Field is completely blank @@20: inc [Wsio_Cursor_Col] ; Move to space character @@99: ret ENDP Wsio_Key_End ;********************************************************************** PROC Wsio_Key_Page_Up ;********************************************************************** ; ; Pointer to Field Table ; mov bx, [Wsio_Field_Address_Hi] mov di, [Wsio_Field_Address_Lo] mov es, bx @@10: ; ; Only check modifiable fields ; cmp [(Wsio_Field ptr di).Modifiable], 1 ; Modifiable? je @@20 ; Yes ; No, so add di, WSIO_FIELD_STRUCTURE_SIZE ; Point to next field jmp @@10 ; Check next field @@20: ; ; Determine Field cursor location ; mov ah, [Wsio_Start_Row] add ah, [(Wsio_Field ptr di).Start_Row] dec ah mov al, [Wsio_Start_Col] add al, [(Wsio_Field ptr di).Start_Col] dec al mov [Wsio_Cursor_Row], ah ; New cursor row mov [Wsio_Cursor_Col], al ; col @@99: ret ENDP Wsio_Key_Page_Up ;********************************************************************** PROC Wsio_Key_Page_Down ;********************************************************************** ; ; Pointer to Field Table ; mov bx, [Wsio_Field_Address_Hi] mov di, [Wsio_Field_Address_Lo] mov es, bx mov dh, 0 ; Possible candidate for row mov dl, 0 ; Possible candidate for col @@10: ; ; Check (Next) Field ; cmp [byte es:di], NULL ; Fields left to check? je @@50 ; No ; Yes, so mov cx, 1 ; Assume occurrence of 1 ; ; Only check modifiable fields ; cmp [(Wsio_Field ptr di).Modifiable], 1 ; Modifiable? jne @@40 ; No ; Yes, so ; ; Determine location of this field ; mov ah, [Wsio_Start_Row] add ah, [(Wsio_Field ptr di).Start_Row] dec ah mov al, [Wsio_Start_Col] add al, [(Wsio_Field ptr di).Start_Col] dec al xor cx, cx ; Reset cx mov cl, [(Wsio_Field ptr di).Occurs] @@20: cmp ah, dh ; This modifiable field further down the road? jl @@40 ; No ; Maybe, so cmp ah, dh ; This modifiable field further down the road? jne @@30 ; Yes ; Maybe, so cmp al, dl ; This modifiable field further down the road? jle @@40 ; No ; Yes, so ; ; Remember this location ; @@30: mov dx, ax @@40: ; ; Check next occurrence ; inc ah ; Get next occurrence loop @@20 ; ; Check next field ; add di, WSIO_FIELD_STRUCTURE_SIZE ; Point to next field jmp @@10 ; Check next field @@50: mov [Wsio_Cursor_Row], dh mov [Wsio_Cursor_Col], dl @@99: ret ENDP Wsio_Key_Page_Down ;********************************************************************** PROC Wsio_Key_Tab ;********************************************************************** ; ; Pointer to Field Table ; mov bx, [Wsio_Field_Address_Hi] mov di, [Wsio_Field_Address_Lo] mov es, bx mov dh, 0 ; Possible candidate for row mov dl, 0 ; Possible candidate for col @@10: ; ; Check (Next) Field ; cmp [byte es:di], NULL ; Fields left to check? je @@70 ; No ; Yes, so ; ; Only check modifiable fields ; cmp [(Wsio_Field ptr di).Modifiable], 1 ; Modifiable? jne @@60 ; No ; Yes, so ; ; Determine if we could tab to this field ; mov ah, [Wsio_Start_Row] add ah, [(Wsio_Field ptr di).Start_Row] dec ah mov al, [Wsio_Start_Col] add al, [(Wsio_Field ptr di).Start_Col] dec al xor cx, cx ; Reset cx mov cl, [(Wsio_Field ptr di).Occurs] @@20: ; ; Check if cursor lies before tabable field ; cmp [Wsio_Cursor_Row], ah ; Cursor before field row? jl @@30 ; Yes ; No, so cmp [Wsio_Cursor_Row], ah ; Cursor on field row? jne @@50 ; No ; Yes, so cmp [Wsio_Cursor_Col], al ; Column before field column? jnl @@50 ; No ; Yes, so ; ; Compare to location to be ; @@30: cmp dx, 0 ; Something to compare? je @@40 ; No ; Yes, so cmp ah, dh ; Row closer to cursor? jnle @@60 ; No ; Maybe, so cmp al, dl ; Column closer to cursor? jnl @@60 ; No ; Yes, so ; ; Remember this location ; @@40: mov dx, ax jmp @@60 @@50: ; ; Check next occurrence ; inc ah ; Get next occurrence loop @@20 @@60: ; ; Check next field ; add di, WSIO_FIELD_STRUCTURE_SIZE ; Point to next field jmp @@10 ; Check next field @@70: cmp dx, 0 ; Tabable field found? jne @@80 ; Yes, ; No, so call Wsio_Key_Page_Up ; Go to first field jmp @@99 @@80: mov [Wsio_Cursor_Row], dh mov [Wsio_Cursor_Col], dl @@99: ret ENDP Wsio_Key_Tab ;********************************************************************** PROC Wsio_Key_Backtab ;********************************************************************** ; ; Pointer to Field Table ; mov bx, [Wsio_Field_Address_Hi] mov di, [Wsio_Field_Address_Lo] mov es, bx mov dh, 0 ; Possible candidate for row mov dl, 0 ; Possible candidate for col @@10: ; ; Check (Next) Field ; cmp [byte es:di], NULL ; Fields left to check? je @@70 ; No ; Yes, so ; ; Only check modifiable fields ; cmp [(Wsio_Field ptr di).Modifiable], 1 ; Modifiable? jne @@60 ; No ; Yes, so ; ; Determine if we could backtab to this field ; mov ah, [Wsio_Start_Row] add ah, [(Wsio_Field ptr di).Start_Row] dec ah mov al, [Wsio_Start_Col] add al, [(Wsio_Field ptr di).Start_Col] add al, [(Wsio_Field ptr di).Size] dec al xor cx, cx ; Reset cx mov cl, [(Wsio_Field ptr di).Occurs] @@20: ; ; Check if cursor lies after tabable field ; cmp [Wsio_Cursor_Row], ah ; Cursor after field row? jnle @@30 ; Yes ; No, so cmp [Wsio_Cursor_Row], ah ; Cursor on field row? jne @@50 ; No ; Yes, so cmp [Wsio_Cursor_Col], al ; Column after field column? jle @@50 ; No ; Yes, so ; ; Compare to location to be ; @@30: cmp dx, 0 ; Something to compare? je @@40 ; No ; Yes, so cmp ah, dh ; Row closer to cursor? jl @@50 ; No ; Maybe, so cmp al, dl ; Column closer to cursor? jl @@50 ; No ; Yes, so ; ; Remember this location ; @@40: sub al, [(Wsio_Field ptr di).Size] mov dx, ax add al, [(Wsio_Field ptr di).Size] @@50: ; ; Check next occurrence ; inc ah ; Get next occurrence loop @@20 @@60: ; ; Check next field ; add di, WSIO_FIELD_STRUCTURE_SIZE ; Point to next field jmp @@10 ; Check next field @@70: cmp dx, 0 ; Tabable field found? jne @@80 ; Yes, ; No, so call Wsio_Key_Page_Down ; Go to last field jmp @@99 @@80: mov [Wsio_Cursor_Row], dh mov [Wsio_Cursor_Col], dl @@99: ret ENDP Wsio_Key_Backtab ;********************************************************************** PROC Wsio_Key_Delete ;********************************************************************** ; ; Check if we are in a modifiable field ; cmp [Wsio_Select_Field_Nr], 0 je @@99 ; No ; Yes, so ; ; Determine current video location ; mov es, [Wsio_Field_Video_ptr_es] mov di, [Wsio_Field_Video_ptr_di] xor bx, bx mov bl, [Wsio_Select_Field_Position] dec bx ; Because of offset 0 add di, bx add di, bx ; To skip attributes ; ; Determine number of characters to move ; xor cx, cx mov cl, [Wsio_Field_Size] sub cl, [Wsio_Select_Field_Position] ;----------------------------------- ; Check for "Trailing Spaces" option ;----------------------------------- cmp [Wsio_Field_Blank], 2 ; Blanks allowed? je @@99 ; No ; Yes, so cmp cx, 0 ; Something to move? je @@95 ; No ; Yes, so ;---------------------------------------------------------------------------- ; Move all characters from next location thru the end, 1 position to the left ;---------------------------------------------------------------------------- @@90: push ds si ; Save pointer push es di ; Receiving pointer pop si ds ; Sending pointer ; ; Go to the next position ; inc si ; Character and inc si ; Attribute to add ; to go to the next position @@91: movsb inc di ; Moved to next receiving char inc si ; Moved to next sending char loop @@91 ; Move next character pop si ds ; Restore pointer @@95: mov [byte es:di], SPACE ; Insert SPACE character @@99: ret ENDP Wsio_Key_Delete ;********************************************************************** PROC Wsio_Key_Insert ;********************************************************************** ; ; Check if we are in a modifiable field ; cmp [Wsio_Select_Field_Nr], 0 je @@99 ; No ; Yes, so ;--------------------------------------- ; Determine if we may insert a character ;--------------------------------------- ; ; Determine current video location ; mov es, [Wsio_Field_Video_ptr_es] mov di, [Wsio_Field_Video_ptr_di] xor bx, bx mov bl, [Wsio_Select_Field_Position] dec bx ; Because of offset 0 add di, bx add di, bx ; To skip attributes ; ; Determine number of characters to move/check ; xor cx, cx mov cl, [Wsio_Field_Size] sub cl, [Wsio_Select_Field_Position] ;----------------------------------- ; Check for "Trailing Spaces" option ;----------------------------------- cmp [Wsio_Field_Blank], 0 ; Blanks anywhere? je @@90 ; Yes ; No, so ; ; Character to be inserted is a SPACE, check if that is allowed ; cmp [Wsio_Field_Blank], 2 ; No blanks allowed at all? je @@99 ; Yes ; Trailing only cmp cx, 0 ; Something to check? je @@95 ; No ; Yes, so push es di cx inc cx ; Check under cursor too jmp @@30 @@10: cmp [byte es:di], SPACE ; Character is space? je @@20 ; Yes ; No, so pop cx di es jmp @@99 ; Error @@20: inc di inc di ; (Next) character to check @@30: loop @@10 pop cx di es ;----------------------------------------------------------------------------- ; Move all characters from this location thru the end, 1 position to the right ;----------------------------------------------------------------------------- @@90: push ds si ; Save pointer ; ; Go to the end of the field ; add di, cx ; Characters and add di, cx ; Attributes to add ; to go to the end of the field push es di ; Receiving pointer pop si ds ; Sending pointer dec si ; is one character to the left dec si ; of the receiving pointer @@91: movsb dec di dec di dec di ; Moved to prev receiving char dec si dec si dec si ; Moved to prev sending char loop @@91 ; Move next character pop si ds ; Restore pointer @@95: mov [byte es:di], SPACE ; Insert SPACE character @@99: ret ENDP Wsio_Key_Insert ;********************************************************************** PROC Wsio_Key_Backspace ;********************************************************************** ; ; Check if we are in a modifiable field ; cmp [Wsio_Select_Field_Nr], 0 je @@99 ; No ; Yes, so ; ; Backspace from position 1 is not possible ; cmp [Wsio_Select_Field_Position], 1 ; Position 1? je @@99 ; Yes ; No, so ;----------------------------------- ; Check for "Trailing Spaces" option ;----------------------------------- cmp [Wsio_Field_Blank], 2 ; Blanks allowed? je @@99 ; No ; Yes, so ; ; Determine current video location ; mov es, [Wsio_Field_Video_ptr_es] mov di, [Wsio_Field_Video_ptr_di] xor bx, bx mov bl, [Wsio_Select_Field_Position] dec bx ; Because of offset 0 add di, bx add di, bx ; To skip attributes ; ; Determine number of characters to move ; xor cx, cx mov cl, [Wsio_Field_Size] sub cl, [Wsio_Select_Field_Position] inc cx ; Move current character too ;------------------------------------------------------------------------------- ; Move all characters from current location thru the end, 1 position to the left ;------------------------------------------------------------------------------- @@90: push ds si ; Save pointer push es di ; Receiving pointer pop si ds ; Sending pointer ; ; Go to the previous position ; dec di ; Character and dec di ; Attribute to add ; to go to the next position @@91: movsb inc di ; Moved to next receiving char inc si ; Moved to next sending char loop @@91 ; Move next character pop si ds ; Restore pointer @@95: mov [byte es:di], SPACE ; Insert SPACE character ; ; After backspacing, we move 1 position to the left ; call Wsio_Key_Arrow_Left @@99: ret ENDP Wsio_Key_Backspace ;********************************************************************** PROC Wsio_Key_Other ;********************************************************************** ; ; Check if we are in a field (modifiable or protected) ; cmp [Wsio_Select_Field_Nr], 0 je @@02 ; No ; Yes, so ; ; Check if we are in a protected field ; cmp [Wsio_Field_Modifiable], 0 ; Protected field? jne @@10 ; No ; Yes, so @@02: push ax call Wsio_Key_Tab ; Jump to first modifiable field call Determine_Field_Under_Cursor mov ah, [Wsio_Select_Field_Nr] mov al, [Wsio_Select_Field_Occur_Nr] mov [Save_Wsio_Select_Field_Nr], ah mov [Save_Wsio_Select_Field_Occur_Nr], al mov bh, [Wsio_Input_Select_Attrib] ; Save attrib of tab-ed field mov [Save_Wsio_Select_Field_Attrib], bh mov al, [Save_Wsio_Input_Select_Attrib] ; Input/Select attrib mov [Wsio_Input_Select_Attrib], al ; Set it cmp al, bh ; Will the attribute change? je @@04 ; No ; Yes, so call Wsio_Command_Select_Deselect @@04: pop ax @@10: ;---------------------------- ; Valid keys for active field ;---------------------------- mov es, [Wsio_Field_Keys_ptr_es] mov di, [Wsio_Field_Keys_ptr_di] ;------------------------------------------------------------- ; Check if a we have to do an uppercase translation of the key ;------------------------------------------------------------- mov ah, al cmp al, "a" ; Key lowercase (min)? jl @@20 ; No ; Maybe, so cmp al, "z" ; Key lowercase (max)? jnle @@20 ; No ; Yes, so sub ah, " " ; "a" -> "A", etc. cmp [Wsio_Field_Uppercase], 1 ; Lowercase ok? je @@20 ; Yes ; No, so mov al, ah ; Only uppercase allowed ;------------------------------------------------ ; Check if a valid key for this Field was pressed ;------------------------------------------------ @@20: push es pop cx cmp cx, NULL ; Any key allowed? je @@40 ; Yes ; No, so @@30: cmp [byte es:di], NULL ; End of valid keys found? je @@98 ; Yes ; No, so cmp ah, [byte es:di] ; Valid key pressed? je @@40 ; Yes ; No, so inc di ; Try next key jmp @@30 ;----------------------------------------------------------------- ; Determine "internal" field key press, and process it accordingly ;----------------------------------------------------------------- @@40: ; ; Determine current video location ; mov es, [Wsio_Field_Video_ptr_es] mov di, [Wsio_Field_Video_ptr_di] xor bx, bx mov bl, [Wsio_Select_Field_Position] dec bx ; Because of offset 0 add di, bx add di, bx ; To skip attributes ;---------------------------- ; Check for decimal seperator ;---------------------------- cmp al, [Wsio_Field_Decimal_Point] ; Character is decimal point? jne @@45 ; No ; Yes, so cmp [Wsio_Field_Digits_After], 0 ; Digits after allowed? je @@98 ; No ; Yes, so @@45: ;----------------------------------- ; Check for "Trailing Spaces" option ;----------------------------------- cmp [Wsio_Field_Blank], 0 ; Blanks anywhere? je @@90 ; Yes ; No, so ;----------------------------------- ; Check if the SPACE key was pressed ;----------------------------------- cmp al, SPACE ; Character is space? jne @@60 ; No ; Yes, so cmp [Wsio_Field_Blank], 2 ; No blanks allowed at all? je @@98 ; Yes ; Trailing only ;---------------------------- ; Check if a SPACE is allowed ;---------------------------- ; ; Determine number of characters to check ; xor cx, cx mov cl, [Wsio_Field_Size] sub cl, [Wsio_Select_Field_Position] cmp cx, 0 ; Something to check? je @@90 ; No ; Yes, so push es di @@50: inc di inc di ; (Next) character to check cmp [byte es:di], SPACE ; Character is space? je @@55 ; Yes ; No, so pop di es jmp @@98 ; Error @@55: loop @@50 pop di es jmp @@90 @@60: ;-------------------------------- ; Check if a non SPACE is allowed ;-------------------------------- push es di ; ; Determine number of characters to check ; xor cx, cx mov cl, [Wsio_Select_Field_Position] jmp @@75 @@70: dec di dec di ; (Previous) character to check cmp [byte es:di], SPACE ; Character is space? jne @@75 ; No ; Yes, so pop di es jmp @@98 ; Error ; No, so @@75: loop @@70 pop di es ;------------------------------ ; Place character on the screen ;------------------------------ @@90: mov [byte es:di], al ; ; After "inserting" a character, we move 1 position to the right ; call Wsio_Key_Arrow_Right jmp @@99 ;------------------ ; Error encountered ;------------------ @@98: xor ax, ax ; Indicate invalid key @@99: ret ENDP Wsio_Key_Other ;********************************************************************** PROC Wsio_Command_Select_Deselect ;********************************************************************** @@00: ;------------------ ; Check Field Table ;------------------ mov bx, [Wsio_Field_Address_Hi] mov di, [Wsio_Field_Address_Lo] mov es, bx cmp bx, NULL ; Fields present? je @@99 ; No ; Yes, so xor cx, cx ; Reset cx mov cl, [Wsio_Select_Field_Nr] jmp @@20 ;------------------- ; Check (Next) Field ;------------------- @@10: cmp [byte es:di], NULL ; Fields left to check? je @@99 ; No ; Yes, so ;---------------------------------- ; Remember Field Information ;---------------------------------- add di, WSIO_FIELD_STRUCTURE_SIZE ; Point to next field already @@20: loop @@10 ; ; Field to Select/Deselect found ; xor cx, cx mov cl, [(Wsio_Field ptr di).Size] push cx mov cl, [(Wsio_Field ptr di).Start_Row] add cl, [Wsio_Select_Field_Occur_Nr] ; Jump to right occurrence dec cx xor dx, dx ; Reset dx mov dl, [(Wsio_Field ptr di).Start_Col] mov es, [Video_Address_ptr_es] mov di, [Video_Address_ptr_di] @@30: add di, (MAX_COL * 2) loop @@30 sub di, (MAX_COL * 2) add di, dx add di, dx sub di, 1 ; Correct video location reached pop cx mov dl, [byte es:di] mov [Save_Wsio_Select_Field_Attrib], dl mov dl, [Wsio_Input_Select_Attrib] @@40: mov [byte es:di], dl inc di inc di loop @@40 @@99: ret ENDP Wsio_Command_Select_Deselect ;********************************************************************** PROC Wsio_Command_Key_Check ;********************************************************************** xor ax, ax ; Reset ax mov ah, KEYBOARD_KBD_STATUS ; Check buffer int KEYBOARD_SERVICE ; Key waiting? jnz @@10 ; Yes ; No, so xor ax, ax ; No key pressed jmp @@99 ; Exit @@10: mov ah, KEYBOARD_READ_CHAR ; Retrieve Key press int KEYBOARD_SERVICE or al, al ; Special Key pressed? jnz @@20 ; No ; Yes, so xchg ah, al ; ah<-0, al<-scan code add al, 32 ; Adjust scan code to >= 32 jmp @@30 @@20: xor ah, ah ; Assume Special Key cmp al, 32 ; Special Key pressed? jb @@30 ; Yes ; No, so inc ah ; It's an ASCII key @@30: or ah, ah ; Set or clear zf result flag @@99: ret ENDP Wsio_Command_Key_Check ;********************************************************************** PROC Wsio_Command_Close ;********************************************************************** ; ; Check on screen name ; mov cx, SCREEN_SAVE_TABLE_MAX mov bx, [Wsio_Name_Address_Hi] mov di, [Wsio_Name_Address_Lo] mov es, bx mov si, offset Screen_Save_Table.Screen_Name @@20: push cx cmp [byte ds:si], NULL ; Table entry empty? je @@40 ; Yes ; No, so push ds si es di mov cx, SCREEN_NAME_SIZE ; Compare Size rep cmpsb ; Screen found? pop di es si ds jne @@40 ; No ; Yes, so ; ; Screen to close found ; pop cx mov bx, SCREEN_SAVE_TABLE_MAX sub bx, cx ; Store free entry nr jmp @@50 @@40: pop cx add si, SCREEN_SAVE_STRUCTURE_SIZE loop @@20 ; ; Error, screen name somehow disappeared! ; mov ax, [Msg_Err_Wsio_Not_Found] mov [Return_Code], ax jmp @@99 @@50: ; ; Restore Screen Area ; push ds si pop di es mov dh, [(Screen_Save ptr di).Cursor_Position_Org.Row] mov dl, [(Screen_Save ptr di).Cursor_Position_Org.Col] push dx ; Save cursor position mov bx, [(Screen_Save ptr di).Save_Address_Hi] mov dx, [(Screen_Save ptr di).Save_Address_Lo] ; ; Reset entry ; mov cx, SCREEN_SAVE_STRUCTURE_SIZE mov ax, NULL rep stosb mov ax, bx mov cx, dx mov bx, [Wsio_Rows] mov dx, [Wsio_Cols] mov es, [Video_Address_ptr_es] mov di, [Video_Address_ptr_di] push ds si push ax cx pop si ds @@60: mov cx, dx rep movsw mov cx, MAX_COL sub cx, dx shl cx, 1 add di, cx dec bx jnz @@60 pop si ds ; ; Release Allocated Memory ; mov es, ax xor ax, ax mov ah, DOS_FREE_ALLOCATED_MEMORY int DOS_SERVICE ; Release Allocated Memory ; ; Restore cursor ; pop dx ; Restore curosr position xor ax, ax xor bx, bx xor cx, cx mov ah, VIDEO_SET_CURSOR int VIDEO_SERVICE ; Set Cursor @@99: ret ENDP Wsio_Command_Close ;********************************************************************** PROC Determine_Field_Under_Cursor ;********************************************************************** ;--------------------- ; Initialize variables ;--------------------- mov [Wsio_Select_Field_Nr], 0 ; We start from the beginning mov [Wsio_Select_Field_Occur_Nr], 0 mov [Wsio_Select_Field_Position], 0 mov [Wsio_Input_Select_Attrib], 0 ;------------------ ; Check Field Table ;------------------ mov bx, [Wsio_Field_Address_Hi] mov di, [Wsio_Field_Address_Lo] mov es, bx cmp bx, NULL ; Fields to check? je @@99 ; No ; Yes, so ;------------------- ; Check (Next) Field ;------------------- @@10: cmp [byte es:di], NULL ; Fields left to check? je @@90 ; No ; Yes, so inc [Wsio_Select_Field_Nr] ;---------------------------------- ; Remember Field Information ;---------------------------------- push ds si es di ; Save pointers mov si, offset Wsio_Field_Start_Row ; Beginning of Field structure push ds si es di ; Copy Wsio Field info pop si ds di es ; from table to active info mov cx, WSIO_FIELD_STRUCTURE_SIZE ; Field structure size rep movsb ; Structure copied pop di es si ds ; Restore pointers add di, WSIO_FIELD_STRUCTURE_SIZE ; Point to next field already ;----------------------------- ; Only check modifiable fields ;----------------------------- cmp [Wsio_Field_Modifiable], 1 ; Modifiable? je @@15 ; Yes ; No, so cmp [Wsio_Field_Mouse_Sensitive], 0 ; Mouse_Sensitive? je @@10 ; No ; Yes, so @@15: ;--------------------------------------------------- ; Determine Field cursor location start/end of field ;--------------------------------------------------- mov ah, [Wsio_Start_Row] add ah, [Wsio_Field_Start_Row] dec ah mov al, [Wsio_Start_Col] add al, [Wsio_Field_Start_Col] dec al mov bx, ax add bl, [Wsio_Field_Size] dec bl xor cx, cx ; Reset cx mov cl, [Wsio_Field_Occurs] mov [Wsio_Select_Field_Occur_Nr], 0 @@20: ;--------------------------------------------------- ; Check if cursor lies within field row/column range ;--------------------------------------------------- inc [Wsio_Select_Field_Occur_Nr] ; Current occurrence cmp ah, [Wsio_Cursor_Row] ; Cursor on this field row? je @@30 ; Yes ; No, so inc ah ; Get next occurrence loop @@20 jmp @@10 ; Check next field @@30: cmp al, [Wsio_Cursor_Col] ; Cursor > field col start? jnle @@10 ; No ; Yes, so cmp bl, [Wsio_Cursor_Col] ; Cursor > field col end jl @@10 ; Yes ; No, so ;------------------------- ; Determine field position ;------------------------- mov [Wsio_Select_Field_Position], 0 mov bl, [Wsio_Cursor_Col] ; Current column sub bl, al ; Subtract begin of field inc bl ; For correct position mov [Wsio_Select_Field_Position], bl cmp [Wsio_Field_Modifiable], 0 ; Protected field? je @@99 ; Yes ; No, so ;---------------------------------------- ; Determine video address of active field ;---------------------------------------- mov es, [Video_Address_Base] mov di, [Video_Address_Offset] xor cx, cx ; Reset cx mov cl, ah ; Field row mov ah, NULL ; Reset upper part of ax @@40: add di, (MAX_COL * 2) loop @@40 sub di, (MAX_COL * 2) add di, ax add di, ax sub di, 2 ; Correct video location reached mov [Wsio_Field_Video_ptr_es], es mov [Wsio_Field_Video_ptr_di], di ;-------------------------- ; Remember active attribute ;-------------------------- mov al, [es:di + 1] mov [Wsio_Input_Select_Attrib], al ;-------------------------------- ; Remember character under cursor ;-------------------------------- mov al, [Wsio_Select_Field_Position] dec ax ; Because of offset 0 add di, ax add di, ax ; To skip attributes mov al, [byte es:di] ; Get character mov [Wsio_Field_Curr_Char], al ; Remember character under cursor @@50: ;--------------------------------------------------- ; Valid keys of active field depend on the edit mask ;--------------------------------------------------- ; ; Check edit mask 0 = External key map ; cmp [Wsio_Field_Edit], 0 je @@99 ; ; Check edit mask 1 = Any ; mov [Wsio_Field_Keys_ptr_es], NULL mov [Wsio_Field_Keys_ptr_di], NULL cmp [Wsio_Field_Edit], 1 je @@99 ; ; Check edit mask 2 = Nrs ; mov si, offset Edit_Mask_2_Nrs mov [Wsio_Field_Keys_ptr_es], ds mov [Wsio_Field_Keys_ptr_di], si cmp [Wsio_Field_Edit], 2 je @@99 ; ; Check edit mask 3 = Letters 4=Nrs+Letters 5=Nrs+Letters+@#$ 6=Filemask1 = External key map ; mov si, offset Edit_Mask_3_Letters mov [Wsio_Field_Keys_ptr_es], ds mov [Wsio_Field_Keys_ptr_di], si cmp [Wsio_Field_Edit], 3 je @@99 ; ; Check edit mask 4 = Nrs and Letters ; mov si, offset Edit_Mask_4_Nrs_Letters mov [Wsio_Field_Keys_ptr_es], ds mov [Wsio_Field_Keys_ptr_di], si cmp [Wsio_Field_Edit], 4 je @@99 ; ; Check edit mask 5 = Nrs and Letters and @#$ ; mov si, offset Edit_Mask_5_Nrs_Let_Spc mov [Wsio_Field_Keys_ptr_es], ds mov [Wsio_Field_Keys_ptr_di], si cmp [Wsio_Field_Edit], 5 je @@99 ; ; Check edit mask 6 = Filemask ; mov si, offset Edit_Mask_6_Filemask mov [Wsio_Field_Keys_ptr_es], ds mov [Wsio_Field_Keys_ptr_di], si cmp [Wsio_Field_Edit], 6 je @@99 ; ; Check edit mask 7 = Hexadecimal ; mov si, offset Edit_Mask_7_Hexadecimal mov [Wsio_Field_Keys_ptr_es], ds mov [Wsio_Field_Keys_ptr_di], si cmp [Wsio_Field_Edit], 7 je @@99 ; ; Check edit mask 8 = Tabable ; mov si, offset Edit_Mask_8_Tabable mov [Wsio_Field_Keys_ptr_es], ds mov [Wsio_Field_Keys_ptr_di], si cmp [Wsio_Field_Edit], 8 je @@99 ; ; Invalid edit mask specified, assume any key is valid ; mov [Wsio_Field_Keys_ptr_es], NULL mov [Wsio_Field_Keys_ptr_di], NULL jmp @@99 @@90: ;---------------------------------- ; Cursor outside a modifiable field ;---------------------------------- mov [Wsio_Select_Field_Nr], 0 mov [Wsio_Select_Field_Occur_Nr], 0 mov [Wsio_Select_Field_Position], 0 mov [Wsio_Input_Select_Attrib], 0 @@99: ret ENDP Determine_Field_Under_Cursor ;********************************************************************** PROC Process_Entered_Screen_Fields ;********************************************************************** mov [Wsio_Screen_Changed], LOGIC_NO mov bx, [Wsio_Field_Address_Hi] mov di, [Wsio_Field_Address_Lo] mov es, bx cmp bx, NULL ; Any fields to update? je @@99 ; No ; Yes, so @@10: push ds si es di cmp [byte es:di], NULL ; Are there (still) any fields? je @@99 ; No ; Yes, so ; ; Assume nothing happened ; mov [(Wsio_Field ptr di).Field_Changed], LOGIC_NO ; Nothing changed ; ; Only process modifiable fields ; cmp [(Wsio_Field ptr di).Modifiable], 1 ; Modifiable? jne @@70 ; No ; Yes, so ; ; Copy field info to active info ; push ds si ; Save pointers mov si, offset Wsio_Field_Start_Row ; Beginning of Field structure push ds si es di ; Copy Wsio Field info pop si ds di es ; from table to active info mov cx, WSIO_FIELD_STRUCTURE_SIZE ; Field structure size rep movsb ; Structure copied pop si ds ; Restore pointers mov [Wsio_Field_Curr_Occur], 1 ; Current occurrence @@20: ;------------------------------------------------------------- ; Copy screen input to save area first of (current) occurrence ;------------------------------------------------------------- push ds si mov [Wsio_Field_Change], LOGIC_NO xor cx, cx mov cl, [Wsio_Field_Start_Row] add cl, [Wsio_Field_Curr_Occur] dec cx ; For offset reasons xor dx, dx mov dl, [Wsio_Field_Start_Col] xor bx, bx mov bl, [Wsio_Field_Size] mov si, offset Wsio_Field_Data_Save mov es, [Video_Address_ptr_es] mov di, [Video_Address_ptr_di] push ds si es di pop si ds di es ; Video -> Save copy direction @@30: add si, (MAX_COL * 2) loop @@30 ; Go to correct row sub si, (MAX_COL * 2) ; Done add si, dx ; Go to correct column add si, dx sub si, 2 ; Done ; Correct video location reached mov cx, bx ; Field size @@40: movsb inc si loop @@40 pop si ds ;-------------------- ; Field changed check ;-------------------- mov si, offset Wsio_Field_Data_Save cmp [Wsio_Field_Data_Src_ptr_es], NULL ; Any source data? jne @@41 ; Yes ; Maybe cmp [Wsio_Field_Data_Src_ptr_di], NULL ; Any source data? je @@70 ; No ; Yes @@41: mov es, [Wsio_Field_Data_Src_ptr_es] mov di, [Wsio_Field_Data_Src_ptr_di] xor dx, dx ; Reset dx mov dl, [Wsio_Field_Size] ; Field size xor cx, cx ; Reset cx mov cl, [Wsio_Field_Curr_Occur] jmp @@43 @@42: add di, dx ; Next source occurrence @@43: loop @@42 mov cx, dx rep cmpsb ; Field changed? je @@50 ; No ; Yes, so mov [Wsio_Screen_Changed], LOGIC_YES mov [Wsio_Field_Change], LOGIC_YES @@50: ;------------------------------------------------------------------- ; Check if we should copy screen input to the source or object field ;------------------------------------------------------------------- mov bx, [Wsio_Field_Data_Obj_ptr_es] mov di, [Wsio_Field_Data_Obj_ptr_di] cmp bx, NULL ; Copy to Object field? jne @@60 ; Yes ; No, so mov bx, [Wsio_Field_Data_Src_ptr_es] mov di, [Wsio_Field_Data_Src_ptr_di] ;--------------------- ; Update field content ;--------------------- @@60: mov es, bx mov si, offset Wsio_Field_Data_Save xor cx, cx ; Reset cx mov cl, [Wsio_Field_Curr_Occur] jmp @@62 @@61: add di, dx ; Next source/object occurrence @@62: loop @@61 mov cx, dx ; Field size rep movsb ; Field updated ;-------------------- ; Get next occurrence ;-------------------- inc [Wsio_Field_Curr_Occur] ; Assume next occurrence cmp [Wsio_Field_Occurs], 0 ; Insanity check first je @@70 ; User supplied an occ of 0 ; User specified an occ of 1 or more dec [Wsio_Field_Occurs] ; More occurrences? jnz @@20 ; Yes ; No, so ;--------------- ; Get next field ;--------------- @@70: pop di es si ds ; ; Update field status ; mov bl, [Wsio_Field_Change] mov [(Wsio_Field ptr di).Field_Changed], bl add di, WSIO_FIELD_STRUCTURE_SIZE jmp @@10 @@99: pop di es si ds ret ENDP Process_Entered_Screen_Fields ;********************************************************************** PROC Keyboard_IO ;********************************************************************** @@00: xor ax, ax ; Reset ax mov ah, KEYBOARD_KBD_STATUS ; Check buffer int KEYBOARD_SERVICE ; Key waiting? jnz @@10 ; Yes ; No, so ; ; Check mouse I/O ; cmp [Wsio_Mouse_Present], LOGIC_NO ; Mouse present? je @@00 ; No ; Yes, so cmp [Wsio_Mouse_Support], LOGIC_NO ; Support mouse? je @@00 ; No ; Yes, so ; ; Check mouse press ; mov ax, MOUSE_GET_MOUSE_BUTTON_STATUS mov bx, 0 ; Status of left button int MOUSE_SERVICE cmp ax, 1 ; Left button pressed? jne @@00 ; No ; Yes, so cmp bx, 0 ; Nr of left button presses > 0? je @@00 ; No ; Yes, so ; ; Left mouse button pressed, position cursor on requested position ; mov [Wsio_Mouse_Left_Button_Pressed], LOGIC_YES mov ax, dx xor dx, dx mov bx, [Pixels_Per_Row] div bx ; dx:ax / bx = cursor Row inc ax mov [Wsio_Cursor_Row], al mov ax, cx xor dx, dx mov bx, [Pixels_Per_Col] div bx ; dx:ax / bx = cursor col inc ax mov [Wsio_Cursor_Col], al mov dh, [Wsio_Cursor_Row] dec dh mov dl, [Wsio_Cursor_Col] dec dl xor ax, ax xor bx, bx xor cx, cx mov ah, VIDEO_SET_CURSOR int VIDEO_SERVICE ; Set Cursor call Determine_Field_Under_Cursor cmp [Wsio_Select_Field_Nr], 0 ; Outside a field? je @@99 ; Yes ; No, so cmp [Wsio_Field_Mouse_Sensitive], 0 ; Mouse sensitive field? je @@99 ; No ; Yes, so ; ; Mouse sensitive field encountered, emulate specified key ; Cursor location specifies which "key" was pressed ; mov [Wsio_Mouse_Left_Button_Pressed], LOGIC_NO xor ax, ax mov al, [Wsio_Field_Mouse_Sensitive] mov [Return_Code], WSIO_MOUSE_PRESSED ; Indicate mouse pressed jmp @@99 @@10: mov ah, KEYBOARD_READ_CHAR ; Retrieve Key press int KEYBOARD_SERVICE or al, al ; Special Key pressed? jnz @@20 ; No ; Yes, so xchg ah, al ; ah<-0, al<-scan code add al, 32 ; Adjust scan code to >= 32 jmp @@30 @@20: xor ah, ah ; Assume Special Key cmp al, 32 ; Special Key pressed? jb @@30 ; Yes ; No, so inc ah ; It's an ASCII key @@30: or ah, ah ; Set or clear zf result flag @@99: ret ENDP Keyboard_IO ;********************************************************************** PROC Show_Screen_Text ;********************************************************************** push ds si mov bx, [Wsio_Rows] mov dx, [Wsio_Cols] mov ax, [Wsio_Text_Address_Hi] mov cx, [Wsio_Text_Address_Lo] mov es, [Video_Address_ptr_es] mov di, [Video_Address_ptr_di] push ax cx pop si ds @@10: mov cx, dx @@20: movsb inc di loop @@20 mov cx, MAX_COL sub cx, dx shl cx, 1 add di, cx dec bx jnz @@10 @@99: pop si ds ret ENDP Show_Screen_Text ;********************************************************************** PROC Show_Screen_Attributes ;********************************************************************** push ds si mov bx, [Wsio_Rows] mov dx, [Wsio_Cols] mov ax, [Wsio_Attrib_Address_Hi] mov cx, [Wsio_Attrib_Address_Lo] mov es, [Video_Address_ptr_es] mov di, [Video_Address_ptr_di] inc di cmp ax, NULL ; Use screen attributes table? je @@30 ; No ; Yes, so push ax cx pop si ds ;------------------------------------- ; Use specified screen attribute table ;------------------------------------- @@10: mov cx, dx @@20: movsb inc di loop @@20 mov cx, MAX_COL sub cx, dx shl cx, 1 add di, cx dec bx jnz @@10 jmp @@99 @@30: ;------------------------------- ; Use specified screen attribute ;------------------------------- mov al, [Wsio_Screen_Attrib] ; Specified screen attribute cmp al, 0 ; Change screen's attribute? je @@99 ; No ; Yes, so mov cx, dx @@40: mov [byte es:di], al ; Use screen attribute inc si inc di inc di loop @@40 mov cx, MAX_COL sub cx, dx shl cx, 1 add di, cx dec bx jnz @@30 @@99: pop si ds ret ENDP Show_Screen_Attributes ;********************************************************************** PROC Show_Screen_Fields ;********************************************************************** push ds si ;-------------------------- ; Determine Fields location ;-------------------------- mov bx, [Wsio_Field_Address_Hi] mov di, [Wsio_Field_Address_Lo] mov es, bx ; ; Number of fields on the screen ; mov [Wsio_Field_Nr_Max], 0 ; ; Number of modifiable fields on the screen ; mov [Wsio_Field_Nr_Mod_Max], 0 cmp bx, NULL ; Any fields to update? je @@99 ; No ; Yes, so @@10: push ds si es di cmp [byte es:di], NULL ; Are there (still) any fields? je @@80 ; No ; Yes, so ; ; Determine number of fields (w/o their occurrences) on the screen ; inc [Wsio_Field_Nr_Max] ; ; Determine number of modifiable fields (w/o their occurrences) on the screen ; cmp [(Wsio_Field ptr di).Modifiable], 1 ; Modifiable? jne @@15 ; No ; Yes, so inc [Wsio_Field_Nr_Mod_Max] @@15: mov ax, [(Wsio_Field ptr di).Offset] mov [Wsio_Field_Offset], ax xor ax, ax xor cx, cx xor dx, dx mov al, [(Wsio_Field ptr di).Size] mov [Wsio_Field_Size], al mov dl, [(Wsio_Field ptr di).Occurs] mov [Wsio_Field_Occurs], dl mov cl, [(Wsio_Field ptr di).Start_Row] mov [byte Wsio_Field_Start_Row], cl mov dl, [(Wsio_Field ptr di).Start_Col] mov [byte Wsio_Field_Start_Col], dl ;----------- ; Field DATA ;----------- mov bx, [(Wsio_Field ptr di).Data_Address_Src_Hi] mov di, [(Wsio_Field ptr di).Data_Address_Src_Lo] cmp bx, NULL jne @@16 cmp di, NULL je @@70 @@16: mov es, bx push es di mov es, [Video_Address_ptr_es] mov di, [Video_Address_ptr_di] @@20: add di, (MAX_COL * 2) loop @@20 sub di, (MAX_COL * 2) add di, dx add di, dx sub di, 2 ; Correct video location reached xor cx, cx mov cl, [Wsio_Field_Size] mov ah, [Wsio_Field_Occurs] mov bx, [Wsio_Field_Offset] pop si ds @@25: movsb inc di loop @@25 dec ah ; Nr of occurrences jz @@30 mov cx, (MAX_COL * 2) ; Move to location of next occurrence push ax xor ah, ah ; Reset hi part sub cx, ax ; Subtract Field size sub cx, ax ; Subtract Field size add di, cx ; Location reached mov cx, ax ; Get Field size pop ax add si, bx ; In case this field is just part of a table jmp @@25 ; Show next occurrence @@30: pop di es si ds push ds si es di ;----------------------- ; Temporary fields setup ;----------------------- mov al, [(Wsio_Field ptr di).Modifiable] mov [Temp_Wsio_Field_Modifiable], al mov al, [(Wsio_Field ptr di).Mouse_Sensitive] mov [Temp_Wsio_Field_Mouse_Sensitive], al ;----------------- ; Field ATTRIBUTES ;----------------- mov ax, [(Wsio_Field ptr di).Attrib_Address_Hi] mov bx, [(Wsio_Field ptr di).Attrib_Address_Lo] mov es, [Video_Address_ptr_es] mov di, [Video_Address_ptr_di] mov cl, [Wsio_Field_Start_Row] mov dl, [Wsio_Field_Start_Col] @@40: add di, (MAX_COL * 2) loop @@40 sub di, (MAX_COL * 2) add di, dx add di, dx sub di, 1 ; Correct video location reached mov cx, bx ; High portion of attrib address xor bx, bx mov bl, [Wsio_Field_Size] xor dx, dx mov dl, [Wsio_Field_Occurs] @@50: ;------------------------------------------- ; Field ATTRIBUTES using an attributes table ;------------------------------------------- cmp ax, NULL ; Attribute table present? je @@60 ; No ; Yes, so push ax cx pop si ds ; Attrib table -> Video @@53: push ds si ; Occurrence attribute pointer mov cx, bx ; Field size mov al, [byte ds:si] ; Get field attribute of occurr. @@55: mov [byte es:di], al inc di inc di loop @@55 dec dx ; More occurrences? jz @@59 ; No ; Yes, so mov ax, (MAX_COL * 2) ; Move to location of next occurrence sub ax, bx ; Subtract Field size sub ax, bx ; Subtract Field size add di, ax ; Location reached pop si ds ; Occurrence attribute pointer inc si ; Get next occurrence jmp @@53 ; Show next occurrence @@59: pop si ds jmp @@70 @@60: ;------------------------------------------- ; Field ATTRIBUTES using the field attribute ;------------------------------------------- ; ; Normally protected fields are displayed as fields as well, ; however when they are mouse sensitive, it is probably a special field, ; i.e. a Function Selection Key field, i.e. Enter, Cancel, Help ; Special fields will retain their "background" attribute and will ; not be displayed as fields ; cmp [Temp_Wsio_Field_Modifiable], 1 ; Modifiable? je @@62 ; Yes ; No, so cmp [Temp_Wsio_Field_Mouse_Sensitive], 0 ; Mouse sensitive? jne @@70 ; Yes ; No, so @@62: mov al, [Wsio_Field_Attrib] cmp al, 0 ; Field attribute specified? je @@70 ; No ; Yes, so @@63: mov cx, bx ; Field size mov al, [Wsio_Field_Attrib] @@65: mov [byte es:di], al inc di inc di loop @@65 dec dx ; More occurrences? jz @@70 ; No ; Yes, so mov ax, (MAX_COL * 2) ; Move to location of next occurrence sub ax, bx ; Subtract Field size sub ax, bx ; Subtract Field size add di, ax ; Location reached jmp @@63 ; Show next occurrence @@70: ;--------------- ; Get next field ;--------------- pop di es si ds add di, WSIO_FIELD_STRUCTURE_SIZE jmp @@10 @@80: pop di es si ds @@99: pop si ds ret ENDP Show_Screen_Fields ENDS CSeg ; End of Code segment END ; End of WSIO