home *** CD-ROM | disk | FTP | other *** search
- ;History:772,1
- ;Mon Mar 26 03:22:48 1990 If they enter e0 using the alt-keypad, pretend it's a real key.
- ;Sun Mar 25 13:07:39 1990 Forgot to set num_screen_cols in monochrome mode.
- ;Sat Feb 24 20:51:15 1990 M-Escape was M-Esc, which was wrong.
- ;Thu Jan 11 23:59:48 1990 Only force video mode 3 if there is no memory at b000:0
- ;Wed Oct 11 22:43:28 1989 When inversing, swap the colors rather than xoring with 77h.
- ;Sun Sep 24 23:18:42 1989 fix the desqview support.
- ;Sun Sep 24 23:05:51 1989 reserve a column on the right for the scroll bar.
- ;Tue Sep 19 23:01:46 1989 add Desqview support.
- ;Thu Jun 15 23:29:25 1989 Didn't restore port 61h correctly -- crashes a PC.
- ;Thu Jun 15 00:27:41 1989 clear_count was destroying dx if ibm_cga != 0.
- ;Sun May 28 00:52:17 1989 Use a different method of testing for enhanced keyboards.
- ;Sun May 07 00:40:17 1989 Move mouse code from pick.asm to ibm.asm
- ;Wed May 03 22:15:40 1989 change the arguments to ring_the_bell.
- ;Wed May 03 21:10:32 1989 'and' the background color with 7 to avoid blinking.
- ;Tue Mar 07 23:57:47 1989 add parameters to ring_the_bell
- ;Tue Mar 07 23:46:52 1989 add Jonathan Vail's visual bell code.
- ;Tue Feb 21 22:20:40 1989 add keypad key support.
- ;Sat Feb 18 16:57:32 1989 Use hardware cursor positioning for EGA only.
- ;Fri Feb 17 22:35:11 1989 cleaned up snow-avoidance code a little.
- ;Mon Jan 30 22:58:16 1989 change the parameters for set_screen_color.
- ;08-25-88 23:37:09 Create two new keycodes, "C- " and "M- ".
- ;05-30-88 22:27:44 fix a small problem in save/restore screen
- ;05-29-88 22:49:48 try getting the attributes from lower left.
- ;05-29-88 22:42:39 get the attributes from the lower right corner rather than upper right.
- ;05-27-88 23:25:34 fix a problem in putch where it put garbage characters up.
- ;05-27-88 00:09:00 read_ibm_cga sometimes gets called with ds=bufseg, not data.
- ;05-27-88 00:07:02 move_line didn't respect ibm_cga flag--it was always set.
- ;05-17-88 20:33:20 Add support for hardware scrolls (should work for all displays) [kdb]
- ;05-17-88 20:02:45 Make move_line wait while reading cga screen [kdb]
- ;05-17-88 19:35:35 Remove all reference to scrwait function [kdb]
- ;05-17-88 19:03:22 Macroize scrwait for single char [kdb]
- ;05-15-88 19:16:51 add scrwait in scrolls [kdb]
- ;05-15-88 18:58:45 Make move_line wait for each character [kdb]
- ;05-07-88 22:07:59 implement a swap_screen_flag.
- ;05-03-88 23:54:55 add more extended keys.
- ;04-17-88 19:22:28 add some extended keycodes.
- ;04-16-88 13:13:01 add extended keyboard support.
- ;04-14-88 22:51:58 If ibm_cga, don't store_debug.
- ;04-01-88 23:08:28 respond to mouse keys with M-, S-, and C-
- ;03-31-88 22:02:25 use C-break for the break character (duh)
- ;03-28-88 19:19:14 just clear the screen on a MDA.
- ;03-28-88 19:09:19 don't save and restore video memory on an MDA.
- ;03-28-88 18:28:50 remove block_cursor and under_cursor
- ;03-26-88 21:59:07 change back to bios calls to read the keyboard.
- ;03-24-88 00:02:13 add fore_original and back_original.
- ;02-21-88 12:24:50 make control be bright, meta inverse video.
- ;02-13-88 18:22:56 use the 18.2 ms timer tick to time the beep.
- ;02-13-88 16:43:45 don't map Timeout using M-, C-, or S-
- ;12-07-87 20:07:29 add store_debug
- ;12-05-87 11:23:35 make the color default to the current color.
- ;12-05-87 11:20:13 clear the screen on init_entry.
- ;12-05-87 11:16:53 save dos's screen and restore it when finished.
- ;07-05-87 22:14:22 caps lock shouldn't apply to M- and C- keys.
- page ,132
-
- comment /
-
- Porting EMACS and Percival to MS-DOS computers other than the Z-100:
-
- This entire file (Z-100.ASM) needs to be re-written, since it contains
- all the Z-100 dependencies. The following conventions must be maintained:
- 1) Never leave this module with DF=1.
- 2) Never destroy ES.
- 3) Never MOV AX,DATA, always use the copy in the appropriate segment register.
- 4) Return NC if a routine succeeds, or fulfills its goals.
-
- /
- .xlist
- include memory.def
-
-
- data segment byte public
-
- public max_screen_line
- max_screen_line db 22 ;number of last text row on screen.
-
- public num_screen_cols
- num_screen_cols db ?
- db 0 ;in case they access it as a word.
-
- screen_columns db ?
- db 0 ;in case they access it as a word.
-
- public fore_original, back_original
- fore_original db ?
- back_original db ?
-
-
- public scan_lines_per_char
- scan_lines_per_char db 8
-
- public computer_name, computer_name_len
- computer_name db 'IBM-PC'
- computer_name_len equ $-computer_name
-
- public swap_screen_flag
- swap_screen_flag dw 1 ;=1 if we should swap screens.
-
- old_cursor dw ? ;old cursor position from the swapped
- ; screen.
-
- mouse_flag db ?
- mouse_buttons db ?
-
-
- key_names label byte
- db ',','Comma',0
- db '(','LPar',0
- db ')','RPar',0
- db 7fh,'Delete',0
-
- db -1,'Timeout',0
- db -2,'Left Down',0 ;mouse button key names.
- db -3,'Right Down',0
- db -4,'Left Up',0
- db -5,'Right Up',0
- db -6,'Middle Down',0
- db -7,'Middle Up',0
- db 0
-
-
- key_others label byte
- db 14,'Back Space',0
- db 15,'Tab',0
- db 28,'Return',0
- db 1,'Escape',0
-
- db 71,'KP7',0 ;Home
- db 72,'KP8',0 ;UpArrow
- db 73,'KP9',0 ;PgUp
- db 74,'KP-',0 ;MMinus
- db 75,'KP4',0 ;LeftArrow
- db 76,'KP5',0 ;Five
- db 77,'KP6',0 ;RightArrow
- db 78,'KP+',0 ;MPlus
- db 79,'KP1',0 ;End
- db 80,'KP2',0 ;DownArrow
- db 81,'KP3',0 ;PgDn
- db 82,'KP0',0 ;Ins
- db 83,'KP.',0 ;Del
-
- db 0
-
-
- key_special label byte
- db 127,'C-Back Space',0
- db 10,'C-Return',0
- db 0
-
- key_table label byte
- ; db 0,'000',0
- db 1,'M-Escape',0 ;extended
- ; db 2,'002',0
- db 3,'C-@',0
- ; db 4,'004',0
- ; db 5,'005',0
- ; db 6,'006',0
- ; db 7,'007',0
- ; db 8,'008',0
- ; db 9,'009',0
- ; db 10,'010',0
- ; db 11,'011',0
- ; db 12,'012',0
- ; db 13,'013',0
- db 14,'M-Back Space',0 ;extended
- db 15,'S-Tab',0
- db 16,'M-q',0
- db 17,'M-w',0
- db 18,'M-e',0
- db 19,'M-r',0
- db 20,'M-t',0
- db 21,'M-y',0
- db 22,'M-u',0
- db 23,'M-i',0
- db 24,'M-o',0
- db 25,'M-p',0
- db 26,'M-{',0 ;extended
- db 27,'M-}',0 ;extended
- db 28,'M-Return',0 ;extended
- ; db 29,'029',0
- db 30,'M-a',0
- db 31,'M-s',0
- db 32,'M-d',0
- db 33,'M-f',0
- db 34,'M-g',0
- db 35,'M-h',0
- db 36,'M-j',0
- db 37,'M-k',0
- db 38,'M-l',0
- db 39,'M-;',0 ;extended
- db 40,"M-'",0 ;extended
- db 41,'M-`',0 ;extended
- ; db 42,'042',0
- db 43,'M-\',0 ;extended
- db 44,'M-z',0
- db 45,'M-x',0
- db 46,'M-c',0
- db 47,'M-v',0
- db 48,'M-b',0
- db 49,'M-n',0
- db 50,'M-m',0
- db 51,'M-Comma',0 ;extended
- db 52,'M-.',0 ;extended
- db 53,'M-/',0 ;extended
- ; db 54,'054',0
- db 55,'M-Asterisk',0
- ; db 56,'056',0
- ; db 57,'057',0
- ; db 58,'058',0
- db 59,'F1',0
- db 60,'F2',0
- db 61,'F3',0
- db 62,'F4',0
- db 63,'F5',0
- db 64,'F6',0
- db 65,'F7',0
- db 66,'F8',0
- db 67,'F9',0
- db 68,'F10',0
- ; db 69,'069',0
- ; db 70,'070',0
- db 71,'Home',0
- db 72,'Up Arrow',0
- db 73,'Pg Up',0
- db 74,'M-Minus',0
- db 75,'Left Arrow',0
- db 76,'Five',0
- db 77,'Right Arrow',0
- db 78,'M-Plus',0
- db 79,'End',0
- db 80,'Down Arrow',0
- db 81,'Pg Dn',0
- db 82,'Ins',0
- db 83,'Del',0
- db 84,'S-F1',0
- db 85,'S-F2',0
- db 86,'S-F3',0
- db 87,'S-F4',0
- db 88,'S-F5',0
- db 89,'S-F6',0
- db 90,'S-F7',0
- db 91,'S-F8',0
- db 92,'S-F9',0
- db 93,'S-F10',0
- db 94,'C-F1',0
- db 95,'C-F2',0
- db 96,'C-F3',0
- db 97,'C-F4',0
- db 98,'C-F5',0
- db 99,'C-F6',0
- db 100,'C-F7',0
- db 101,'C-F8',0
- db 102,'C-F9',0
- db 103,'C-F10',0
- db 104,'M-F1',0
- db 105,'M-F2',0
- db 106,'M-F3',0
- db 107,'M-F4',0
- db 108,'M-F5',0
- db 109,'M-F6',0
- db 110,'M-F7',0
- db 111,'M-F8',0
- db 112,'M-F9',0
- db 113,'M-F10',0
- db 114,'C-PrtSc',0
- db 115,'C-Left Arrow',0
- db 116,'C-Right Arrow',0
- db 117,'C-End',0
- db 118,'C-Pg Dn',0
- db 119,'C-Home',0
- db 120,'M-1',0
- db 121,'M-2',0
- db 122,'M-3',0
- db 123,'M-4',0
- db 124,'M-5',0
- db 125,'M-6',0
- db 126,'M-7',0
- db 127,'M-8',0
- db 128,'M-9',0
- db 129,'M-0',0
- db 130,'M--',0
- db 131,'M-=',0
- db 132,'C-Pg Up',0
- ;all of the following are extended.
- db 133,'F11',0
- db 134,'F12',0
- db 135,'S-F11',0
- db 136,'S-F12',0
- db 137,'C-F11',0
- db 138,'C-F12',0
- db 139,'M-F11',0
- db 140,'M-F12',0
- db 141,'C-Up Arrow',0
- db 142,'C-Minus',0
- db 143,'C-Five',0
- db 144,'C-Plus',0
- db 145,'C-Down Arrow',0
- db 146,'C-Ins',0
- db 147,'C-Del',0
- db 148,'C-Tab',0
- db 149,'C-Slash',0
- db 150,'C-Asterisk',0
- db 151,'M-Home',0
- db 152,'M-Up Arrow',0
- db 153,'M-Pg Up',0
- ; db 154,'154',0
- db 155,'M-Left Arrow',0
- ; db 156,'156',0
- db 157,'M-Right Arrow',0
- ; db 158,'158',0
- db 159,'M-End',0
- db 160,'M-Down Arrow',0
- db 161,'M-Pg Dn',0
- db 162,'M-Ins',0
- db 163,'M-Del',0
- db 164,'M-Slash',0
- db 165,'M-Tab',0
- db 166,'M-Return',0
- db 167,'C- ',0
- db 168,'M- ',0
-
- ; db 224,'Slash',0
- ; db 224,'Return',0
-
- db 0,'Unknown',0
-
-
- one_key_string db ?,0
- ctrl_key_string db 'C-'
- ctrl_key_char db ?,0
-
- left_flag equ 1
- right_flag equ 2
- ctrl_flag equ 4
- alt_flag equ 8
- all_flags equ left_flag + right_flag + ctrl_flag + alt_flag
- shift_flags db ?
-
- bios_seg segment at 40h
- org 17h
- bios_shifts db ?
- bios_seg ends
-
-
- key_buffer label byte ;this is where we put the ASCII
- db 26 dup(?) ; representation of the key.
-
-
- extrn inversing: word ;if we're inverse videoing.
-
- public color
- color db 0fh ;xbbbifff bbb=background, ifff=fore.
- control_color db 1fh ;attributes for control characters.
- whitespc_color db 0fh ;attributes for whitespace characters.
-
- font_8_table label byte
- db 007h ;visi space
- db 004h ;visi tab
- db ? ;del
- db ? ;eof
- db ? ;visi newline
- db 01ah ;right arrow
- db ? ;random char.
- db 01fh ;visible newline.
- db 018h ;up arrow.
- db 019h ;down arrow.
- db 20h ;trailing space
-
- ibm_cga db 0 ;=0 if we can write to screen anytime,
- ;=1 if we should wait for retrace.
- have_ega db 0 ;=0 if we don't have an EGA.
-
- int_16_input db 0 ;function code for keyboard input
- int_16_status db 1 ;function code for keyboard status
-
- in_dv db 0 ;<>0 if we are running under DesqView.
-
- data ends
-
-
- code segment byte public
- assume cs:code, ds:data, es:nothing
- ;all of the code in this segment is called with the above assumes.
-
- break_flag db ?
-
- their_1b dd ?
- our_1b:
- mov cs:break_flag,1
- iret
-
-
- public init_entry
- init_entry:
- push es ;get their C-break.
- mov ax,351bh
- int 21h
- mov word ptr their_1b+0,bx
- mov word ptr their_1b+2,es
- pop es
-
- push ds ;set our C-break.
- mov ax,cs
- mov ds,ax
- mov dx,offset our_1b
- mov ax,251bh
- int 21h
- pop ds
-
- ;
- ;Determine if Desqview is present.
- ;
- mov cx,'DE'
- mov dx,'SQ'
- mov ax,2b01h
- int 21h
- cmp al,0ffh
- je no_desqview
- inc in_dv
- no_desqview:
-
- ;
- ;Determine whether or not the BIOS supports extended keyboard functions.
- ;
- push ds
- mov ax,40h
- mov ds,ax
- mov al,ds:[96h] ;keyboard support byte.
- pop ds
- test al,10h
- je init_entry_0 ;no - they don't have an extended kbd.
-
- mov int_16_input,10h ;yes - use extended keyboard function codes.
- mov int_16_status,11h
- init_entry_0:
-
- ;
- ;Now set the video mode to one that we can use.
- ;
- mov ah,15
- int 10h ;get video state of the PC
- mov screen_columns,40
- mov num_screen_cols,40
- cmp al,1 ;40 column text mode?
- jbe init_entry_1 ;Yes, ok.
- mov screen_columns,80
- mov num_screen_cols,80
- cmp al,3 ;Is screen CGA Text?
- jbe init_entry_1 ;Yes, ok.
- cmp al,7 ;Is screen MDA?
- je init_entry_5 ;Yes, ok - but we can't have an EGA.
-
- ;
- ;Check to make sure there's memory at b800h. If there isn't, revert to
- ;video mode 3.
- ;
- push ds
- mov ax,0b800h
- mov ds,ax
- mov ax,ds:[0] ;save the original
- not word ptr ds:[0] ;try to change the memory.
- not ax ;change the original.
- cmp ax,ds:[0] ;did they both change?
- pushf
- not ax ;restore the original contents.
- mov ds:[0],ax
- popf
- pop ds
- je init_entry_1 ;go if there's memory there.
-
- mov ax,0*256 + 3 ;use 25x80 color if some strange mode.
- int 10h
-
- init_entry_1:
- mov ax,1200h ;test for an EGA
- mov bx,10h
- mov cx,-1
- int 10h
- cmp cx,-1
- je init_entry_2 ;no EGA.
-
- mov have_ega,1 ;remember that we have an EGA.
-
- push ds ;get the max scanlines.
- xor ax,ax
- mov ds,ax
- mov al,ds:[484h]
- mov ah,ds:[485h]
- mov cl,ds:[44ah]
- pop ds
-
- mov screen_columns,cl ;remember how wide it is.
- sub al,2 ;leave room for a status and minibuffer line.
- mov max_screen_line,al
-
- init_entry_2:
- mov al,screen_columns
- mov num_screen_cols,al
-
- cmp swap_screen_flag,0 ;should we swap the screen?
- je init_entry_4 ;no.
-
- mov bh,0
- mov ah,3 ;get cursor position
- int 10h
- mov old_cursor,dx
-
- mov dl,max_screen_line ;copy the page zero to page one.
- add dl,2
- mov al,dl
- inc al
- add al,dl
- init_entry_3:
- call move_line ;enter with dl=source, al=destination.
- dec al
- dec dl
- jns init_entry_3
-
- init_entry_5:
- push es
- mov dh,0
- mov dl,max_screen_line
- add dl,2
- call get_video_ptr
- mov ax,es:[di] ;get the attributes from the lower left.
- pop es
- mov fore_original,ah
- and fore_original,0fh
- mov cl,4 ;rotate the background to where we
- shr ah,cl ; want it.
- and ah,7
- mov back_original,ah
-
- clear_screen:
- mov dh,0 ;clear the screen.
- mov dl,max_screen_line
- add dl,2
- clear_screen_1:
- call clear_to_eol ;enter with dl=row, dh=column.
- dec dl
- jns clear_screen_1
- init_entry_4:
- dec num_screen_cols
- ret
-
-
- public uninit_exit
- uninit_exit:
- ;called when exiting. May destroy any but seg-regs.
-
- push ds ;restore C-break.
- lds dx,their_1b
- mov ax,251bh
- int 21h
- pop ds
-
- cmp swap_screen_flag,0 ;should we swap the screen?
- jne uninit_exit_4 ;yes.
- ret ;no.
- uninit_exit_4:
-
- inc num_screen_cols
-
- mov ah,15
- int 10h ;get video state of the PC
- cmp al,7 ;don't restore the memory on an MDA
- je uninit_exit_1 ; 'cuz it ain't there.
-
- mov dx,old_cursor
- mov bh,0
- mov ah,2 ;set cursor position
- int 10h
-
- mov al,max_screen_line ;copy the page one to page zero.
- add al,2
- mov dl,al
- add dl,dl
- uninit_exit_3:
- call move_line ;enter with dl=source, al=destination.
- dec dl
- dec al
- jns uninit_exit_3
-
- dec num_screen_cols
-
- ret
-
- uninit_exit_1:
- mov dl,0
- mov dh,max_screen_line
- add dh,2
- mov bh,0
- mov ah,2 ;set cursor position
- int 10h
-
- call clear_screen
-
- dec num_screen_cols
-
- ret
-
-
- outreg macro port,value
- mov al,port
- out dx,al
- inc dx
- mov al,value
- out dx,al
- dec dx
- endm
-
-
- if 0
- set_start_addr:
- ;given screen_start (the first text line on the screen), scan_row (the first
- ; scan row we're displaying), and bot_window, set the appropriate registers.
-
- mov dx,03dah ;wait for vertical retrace.
- cli ;no interrupts.
- set_start_addr_h:
- in al,dx ;Wait for horizontal retrace
- test al,8 ; so will catch vertical
- jz set_start_addr_h ; retrace at start.
- set_start_addr_v:
- in al,dx ;Wait for vertical retrace.
- rcr al,1
- jc set_start_addr_v
-
- mov dx,03d4h
-
- mov bx,screen_start ;screen_start is given in terms of
- shr bx,1 ; bytes, but we need words.
- outreg 0ch,bh ;the high byte of the starting address.
- outreg 0dh,bl ;the low byte of the starting address.
-
- outreg 08h,scan_row ;Preset row scan.
-
- mov bx,bot_window
- shl bh,1 ;put the bit in the right place.
- shl bh,1
- shl bh,1
- shl bh,1
- or bh,0fh ;assume that the rest are ones.
-
- outreg 18h,bl ;set the low byte of line compare.
- outreg 07h,bh ;set the overflow bits.
-
- sti
-
- ret
- endif
-
-
- public store_ibm_cga
- store_ibm_cga:
- cmp have_ega,0 ;do we have an EGA?
- jne store_ibm_cga_1 ;yes - we know better than they do,
- mov ibm_cga,al ; so ignore them.
- store_ibm_cga_1:
- ret
-
-
- public store_debug
- store_debug:
- if 0
- cmp ibm_cga,0 ;don't do this on an IBM CGA.
- jne store_debug_1
- push ds
- push es
- push ax
- mov ax,data
- mov ds,ax
- mov es,ax
- mov dh,screen_columns
- sub dh,2
- mov dl,max_screen_line
- inc dl
- call get_video_ptr ;enter with dl=current row, dh=current column.
- ;return with es:di->character position.
- pop ax
- mov es:[di],al
- mov es:[di+2],ah
- pop es
- pop ds
- store_debug_1:
- endif
- ret
-
-
- ;this routine should check for a break character. Return cy if none,
- ; nc if we should break.
- public check_breakchar
- check_breakchar:
- cmp cs:break_flag,0 ;test the break flag.
- mov cs:break_flag,0 ;clear the break flag.
- stc
- je check_breakchar_1
- clc
- check_breakchar_1:
- ret
-
-
- public give_up_slice
- give_up_slice:
- cmp in_dv,0
- je give_up_slice_1
- push bx
- push si
- push bp
- mov bx,1000h
- int 15h
- pop bp
- pop si
- pop bx
- give_up_slice_1:
- ret
-
-
- public check_for_key
- check_for_key:
- ;return zr,ax=0 if no key is waiting.
- ;return nz,ax=key if a key is waiting, but don't input the key yet.
- mov ah,int_16_status ;check for a key.
- int 16h
- jne check_for_key_1 ;go if we got a key.
- mov ax,0 ;return ax=0 if we didn't.
- check_for_key_1:
- ret
-
-
- public get_key_value
- get_key_value:
- ;exit with ax=keycode.
- mov ah,int_16_input
- int 16h
- ret
-
-
- public decode_key
- decode_key:
- ;enter with ax=key value.
- ;exit with si,cx -> the key's name in ASCII.
- mov di,offset key_buffer
-
- cmp ax,0f9h ;one of the mouse buttons?
- jb decode_key_7
- cmp ax,0feh
- ja decode_key_7
-
- push ax
- push ds
- mov ax,bios_seg
- mov ds,ax
- assume ds:bios_seg
-
- mov ah,bios_shifts
- and ah,all_flags ;isolate the flags we're interested in.
- pop ds
- assume ds:data
- mov shift_flags,ah
- call decode_meta
- call decode_ctrl
- call decode_shift
- pop ax
-
- decode_key_7:
-
- or al,al ;extended function key?
- je decode_key_5
- cmp ax,00e0h ;Did they enter e0 using the keypad?
- je decode_key_6 ;yes -- it's a real key.
- cmp al,0e0h
- je decode_key_5
-
- push ax ;now we look for ASCII keys that
- mov si,offset key_others ; have dedicated keys.
- call decode_search ;search for the scan code names.
- pop ax
- jne decode_key_2 ;go if we found it.
-
- mov ah,al
- mov si,offset key_names ;now search for the ASCII keys that
- ; we don't (or can't) represent.
- call decode_search ;search for the literal names.
- jne decode_key_1 ;copy it in.
- mov al,ah
-
- cmp al,' ' ;control char?
- jae decode_key_6 ;no
- add al,'`' ;yes - convert into letter.
- mov ctrl_key_char,al
- mov si,offset ctrl_key_string
- cmp al,'z' ;control character > 'C-z'?
- jbe decode_key_1 ;no.
- sub ctrl_key_char,'`'-'@' ;yes - make it C-[, not C-{
- jmp short decode_key_1
- decode_key_2:
- push si
- mov si,offset key_special
- mov ah,al ;now see if it's one of the ones we
- call decode_search ; know are special.
- pop ax
- jne decode_key_1 ;yes - it is.
- mov si,ax
- jmp short decode_key_1
- decode_key_6:
- mov one_key_string,al
- mov si,offset one_key_string
- jmp short decode_key_1
-
- decode_key_5:
- mov si,offset key_table ;search for the extended functions.
- call decode_search
- decode_key_1:
- lodsb ;copy to the next null.
- stosb
- or al,al
- jne decode_key_1
- dec di ;don't include the null.
- mov si,offset key_buffer
- mov cx,di
- sub cx,si
- ret
-
-
- decode_ctrl:
- test shift_flags,ctrl_flag
- je decode_ctrl_1
- mov ax,'C' + '-'*256
- stosw
- decode_ctrl_1:
- ret
-
-
- decode_shift:
- test shift_flags,left_flag + right_flag
- je decode_shift_1
- mov ax,'S' + '-'*256
- stosw
- decode_shift_1:
- ret
-
- decode_meta:
- test shift_flags,alt_flag
- je decode_meta_1
- mov ax,'M' + '-'*256
- stosw
- decode_meta_1:
- ret
-
-
- decode_search:
- ;enter with ah=key to search for, si->table.
- ;exit with al=key, nz if found, al=0, zr if not found.
- lodsb
- or al,al ;end of table?
- je decode_search_2 ;yes - try shifted values.
- cmp al,ah ;is this the key?
- je decode_search_2 ;yes.
- decode_search_1:
- lodsb ;skip to the next null.
- or al,al
- jne decode_search_1
- jmp decode_search
- decode_search_2:
- or al,al
- ret
-
-
- public ring_the_bell
- ring_the_bell:
- ;enter with bx = first argument, cx = second argument.
- or cx,cx
- jne ring_the_bell_1
- mov cx,1 ;defaults to duration of one.
- ring_the_bell_1:
- or bx,bx ;negative frequency?
- jl vbell ;yes - they must want a visual bell.
-
-
- ;Beep procedure count values
- ;---------------------------
- ;To generate a given freqency note out of the speaker with the Beep procedure
- ;on the PC using Channel 2 of the 8253 timer, the channel 2 count register
- ;must be loaded with a value such that the 8253 input clock frequency
- ;(1.19318 MHz) divided by the count figure equals the audio frequency.
- ;enter with bx=count figure for frequency to be generated.
- beep:
- push cx
- mov cx,1
- call sleep
- pop cx
- mov al,0b6h ; Channel 2, LSB then MSB, Square Wave, Binary
- out 43h,al ; Program 8253 command register
- mov ax,bx ; Get the frequency to be generated
- out 42h,al ; Load Channel 2 count register LSB
- mov al,ah
- out 42h,al ; Load Channel 2 count register MSB
- in al,61h ; Read settings from 8255 PPI I/O Port "PB"
- push ax ; Save original settings in AH
- or al,3 ; Enable Timer Channel 2 & Speaker data
- out 61h,al ; program the 8255 with new setting-speaker on
- call sleep ; Wait for a while.
- pop ax ; Get original 8255 Port "PB" settings
- out 61h,al ; Reset port to original values-speaker off
- ret
-
-
- vbell:
- push cx
- mov cx,1 ;get syncronized with the timer
- call sleep
-
- call reverse
-
- pop cx ;now wait that many seconds.
- or cx,cx ;if zero duration, just wait one tick.
- jne vbell_1
- mov cx,1
- vbell_1:
- call sleep
-
- reverse:
- push di ; Save es,di
- push es
- call get_video_seg
-
- mov ah,num_screen_cols ; Calc number of chars
- mov al,max_screen_line
- add al,2 ; the entire screen
- mul ah
- mov cx,ax
- mov di,1 ; Offset to start at
- rev1:
- mov al,es:[di] ; Reverse the foreground/background
- rol al,1
- rol al,1
- rol al,1
- rol al,1
- and al,77h
- and byte ptr es:[di],not 77h
- or es:[di],al
- add di,2
- loop rev1
-
- pop es
- pop di
-
- ret
-
-
- sleep:
- ;pause for cx 18ths.
- push bx
- push ds ; make ds = bios.
- mov ax,40h
- mov ds,ax
- wait2:
- mov bx,ds:[6ch] ; Get the current timer value.
- wait1:
- cmp bx,ds:[6ch] ; Did the timer value "tick"?
- je wait1 ; No - keep waiting for a tick.
- loop wait2 ; LOOP is first executed
- pop ds
- pop bx
- ret
-
-
- code ends
-
- code segment byte public
- assume cs:code, ds:nothing, es:data, ss:data
- ;all of the code in this segment is called with the above assumes.
-
-
- public read_ibm_cga
- read_ibm_cga:
- mov al,ibm_cga
- ret
-
-
- public position_cursor
- position_cursor:
- ;enter with dh=col (0...80), dl=row (0..max_screen_line)
- ;exit with cursor set to that position.
- push bx
- push dx
- push si
- push di
- push bp
-
- xchg dh,dl
- mov bh,0
- mov ah,2 ;set cursor position
- int 10h
-
- pop bp
- pop di
- pop si
- pop dx
- pop bx
- ret
-
-
- crt_status equ 3dah ; crt status port
-
- ;requires dx = crt_status. Destroys ax.
- retrace_wait macro
- local loop1,loop2
- loop1:
- in al,dx
- shr al,1 ; display enabled?
- jc loop1 ; yes, keep waiting
- loop2:
- in al,dx
- shr al,1 ; now wait for it to go off
- jnc loop2 ; so can have whole cycle
- endm
-
-
- public move_line
- move_line:
- ;enter with dl=source row, al=destination row.
- push ax
- push bx
- push cx
- push dx
- push si
- push di
- push bp
- push ds
- push es
-
- push ax ;compute the source byte.
- mov al,screen_columns
- mul dl
- shl ax,1
- mov si,ax
- pop ax
-
- mov ah,screen_columns ;compute the destination byte.
- mul ah
- shl ax,1
- mov di,ax
-
- mov cx,word ptr num_screen_cols ;move the line.
- call get_video_seg ;get the video card plane.
- mov ds,ax
- assume ds:nothing, es:nothing
-
- cmp ibm_cga,0
- je move_line_2
-
- mov dx,crt_status ;load it only once.
- move_line_1:
- retrace_wait
- lodsw ;get our char into bx.
- mov bx,ax
- retrace_wait
- mov ax,bx
- stosw
- loop move_line_1
- jmp short move_line_3
-
- move_line_2:
- rep movsw
-
- move_line_3:
-
- pop es
- pop ds
- assume ds:nothing, es:data
- pop bp
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- ret
-
-
- public clear_to_eol
- clear_to_eol:
- ;enter with dl=current row, dh=current column.
- push bx
- mov bl,num_screen_cols
- call clear_count
- pop bx
- ret
-
-
- public clear_count
- clear_count:
- ;enter with dl=current row, dh=current column, bl=column to clear to.
- push ax
- push bx
- push cx
- push si
- push di
- push bp
- push es
- clear_count_0:
- cmp dh,bl ;already past it?
- jae clear_count_3 ;yes.
-
- mov ah,color
- mov al,' ' ;clear to the background color.
- push ax
- call get_video_ptr
- assume ds:nothing, es:nothing
-
- mov cl,bl ;compute the number of chars to clear.
- sub cl,dh
- mov ch,0
-
- pop ax
-
- cmp ibm_cga,0 ;slow refresh?
- je clear_count_2
-
- push dx
- mov bx,ax ;retrace_wait destroys ax.
- mov dx,crt_status ;load it only once.
- clear_count_1:
- retrace_wait
- mov ax,bx
- stosw
- loop clear_count_1
- pop dx
- jmp short clear_count_3
-
- clear_count_2:
- rep stosw
-
- clear_count_3:
- pop es
- assume ds:nothing, es:data
- pop bp
- pop di
- pop si
- pop cx
- pop bx
- pop ax
- ret
-
-
- get_video_ptr:
- ;enter with dl=current row, dh=current column.
- ;doesn't destroy bx.
- ;return with es:di->character position.
- mov al,screen_columns ;compute the offset of the char.
- mul dl
- add al,dh
- adc ah,0
- shl ax,1
- mov di,ax
- get_video_seg:
- ;return with es,ax=video segment.
- xor ax,ax
- mov es,ax
- mov ax,0b000h
- cmp byte ptr es:[449h],7 ;MDA?
- je get_video_seg_1 ;yes - we have the segment already.
- mov ax,0b800h ;no - segment at b800h.
- get_video_seg_1:
- mov es,ax
- mov ah,0feh ;let desqview change the segment.
- int 10h
- mov ax,es
- ret
-
-
- public xychrout
- xychrout:
- ;enter with dh=col, dl=row, al=character to print, ah=font to print it in.
- push ax ;save everything that we might need.
- push bx
- push cx
- push dx
- push di
- push si
- push es
- push ds
- mov bx,es
- mov ds,bx
- cmp dh,screen_columns ;past the right margin?
- jae xychrout_3 ;yes - don't print.
- cmp ah,0 ;font zero?
- jne xychrout_5 ;no - print specially.
- mov ah,color ;assume no inverse video
- cmp al,0ffh ;print 255 specially
- je xychrout_del
- cmp al,20h ;is this a space or so?
- jb xychrout_control ;print control chars specially.
- jmp short xychrout_1
- xychrout_del:
- mov al,7fh-'@' ;show bold del.
- xychrout_control:
- mov ah,control_color
- add al,'@'
- jmp short xychrout_1
- xychrout_5:
- mov ah,whitespc_color
- mov bx,offset font_8_table
- sub al,4dh ;first character in font 8.
- xlat
- xychrout_1:
- cmp inversing,0 ; check inversion flag
- je no_invers ; skip inversion code
- mov cl,4 ; we're inversing: so exchange
- rol ah,cl ; fore & background color
- and ah,7Fh ; avoid blinking background
- no_invers:
- mov bx,ax ;save the char in bx.
- call get_video_ptr
- assume ds:nothing, es:nothing
- cmp ibm_cga,0 ;if we have an IBM CGA, we have to wait
- je xychrout_4 ; for retrace, otherwise not.
- mov dx,crt_status
- retrace_wait
- xychrout_4:
- mov ax,bx
- stosw
- xychrout_3:
- pop ds
- pop es
- assume ds:nothing, es:data
- pop si
- pop di
- pop dx
- pop cx
- pop bx
- pop ax
- ret
-
-
- public hardware_roll_down
- hardware_roll_down:
- ;exit: if this machine is capable of hardware roll, do it and exit with cy=0,
- ; otherwise, exit with cy=1. The hardware roll must leave the last line
- ; on the screen as the last line.
- ;preserve bx.
- cmp ibm_cga,0
- je no_roll_down
-
- push bx
- push cx
- push dx
- mov ch,ah
- mov cl,0
- mov dh,al
- mov dl,num_screen_cols
- dec dl
- mov bh,color
- mov ax,701h
- int 10h
- pop dx
- pop cx
- pop bx
- clc
- ret
- no_roll_down:
- stc
- ret
-
-
- public hardware_roll_up
- hardware_roll_up:
- ;exit: if this machine is capable of hardware roll, do it and exit with cy=0,
- ; otherwise, exit with cy=1. The hardware roll must leave the last line
- ; on the screen as the last line.
- ;preserve bx.
- cmp ibm_cga,0
- je no_roll_up
-
- push bx
- push cx
- push dx
- mov ch,ah
- mov cl,0
- mov dh,al
- mov dl,num_screen_cols
- dec dl
- mov bh,color
- mov ax,601h
- int 10h
- pop dx
- pop cx
- pop bx
- clc
- ret
- no_roll_up:
- stc
- ret
-
-
- public set_screen_color
- set_screen_color:
- ;enter with si -> list of colors (fore, back, control, whitespc)
- mov cl,4
- mov ah,[si+1] ;background doesn't change.
- shl ah,cl
- and ah,70h ;don't let them set blinking colors.
- mov al,[si] ;compute the normal attributes.
- or al,ah
- mov color,al
- mov al,[si+2] ;now the control attributes.
- or al,ah
- mov control_color,al
- mov al,[si+3] ;now the whitespace attributes.
- or al,ah
- mov whitespc_color,al
- ret
-
-
- public pick_init, pick_on, pick_off, check_pick, get_pick_values
- pick_init:
- call mouse_exists
- mov ax,0
- int 33h
- mov mouse_flag,al ;remember if the mouse exists.
- mov mouse_buttons,bl ;remember the number of buttons.
- mov ax,4 ;move the mouse to the upper right hand.
- mov cx,635
- mov dx,0
- int 33h
- mov ax,10 ;set text cursor (ignored on Z-100).
- mov bx,0 ;software text cursor.
- mov cx,77ffh ;screen mask
- mov dx,7700h ;cursor mask
- int 33h
-
- mov al,max_screen_line ;compute the "number of scan lines"
- add al,2
- mul scan_lines_per_char
- dec dx
- mov dx,ax ;set the "number of scan lines"
- mov cx,0
- mov ax,8
- int 33h
-
- mov al,8 ;we're assuming nine bits per char.
- mul screen_columns
- dec ax
- mov dx,ax ;set the "number of bit columns"
- mov cx,0
- mov ax,7
- int 33h
-
- call check_pick ;ensure that there are no up or down
- call check_pick ; events left.
- call check_pick
- call check_pick
- call check_pick
- call check_pick
- ret
-
-
- pick_on:
- call mouse_exists
- mov ax,1
- int 33h
- ret
-
-
- pick_off:
- call mouse_exists
- mov ax,1 ;ensure that we work with MOUSEKEY.
- int 33h
- mov ax,2
- int 33h
- ret
-
-
- check_pick:
- ;return nz and al=pick character. return zr if no pick.
- call mouse_exists
- push bx
- push cx
- push dx
- cmp mouse_flag,0 ;inhibit mouse presses if it isn't there.
- je check_pick_1
- mov ax,5
- mov bx,0 ;left button press
- int 33h
- mov ax,0feh
- or bx,bx
- jne check_pick_1
- mov ax,5 ;right button press
- mov bx,1
- int 33h
- mov ax,0fdh
- or bx,bx
- jne check_pick_1
- mov ax,6 ;left button release
- mov bx,0
- int 33h
- mov ax,0fch
- or bx,bx
- jne check_pick_1
- mov ax,6 ;right button release
- mov bx,1
- int 33h
- mov ax,0fbh
- or bx,bx
- jne check_pick_1
- cmp mouse_buttons,2 ;do we have only two buttons?
- je check_pick_1 ;yes - no pick.
- mov ax,6 ;middle button release
- mov bx,2
- int 33h
- mov ax,0f9h
- or bx,bx
- jne check_pick_1
- mov ax,5 ;middle button press
- mov bx,2
- int 33h
- mov ax,0fah
- or bx,bx
- jne check_pick_1
- check_pick_1:
- pop dx
- pop cx
- pop bx
- ret
-
- get_pick_values:
- mov cx,0
- mov dx,0
- call mouse_exists
- mov ax,3
- int 33h
-
- push cx ;save the x value.
-
- mov ax,dx
- div scan_lines_per_char
- mov ah,0
- push ax
- call read_linesbefore
- push ax
- call read_newrow
- pop bx
- sub bx,ax ;bx=linesbefore - newrow.
- pop dx
- add dx,bx ;add y-value.
- inc dx ;ax= y-value - newrow + linesbefore + 1.
- pop ax ;compute the x-value.
-
- push dx
-
- mov cl,8
- div cl
- mov ah,0
- inc ax
- push ax ;add in firstcolumn.
- call read_firstcolumn
- pop cx
- add cx,ax
-
- pop dx
-
- ret
-
- extrn read_firstcolumn: near
- extrn read_linesbefore: near
- extrn read_newrow: near
-
-
- ;this routine returns from the routine that called it if the mouse is not
- ; installed.
- mouse_exists:
- push ds
- xor ax,ax
- mov ds,ax
- mov ax,word ptr ds:[33h*4+2]
- pop ds
- cmp ax,0 ;any mouse interrupt at all?
- je mouse_exists_2 ;no - no mouse.
- cmp ax,40h ;is the mouse interrupt in the bios?
- jne mouse_exists_1 ;no - must be a real mouse.
- mouse_exists_2:
- add sp,2
- xor ax,ax
- ret
- mouse_exists_1:
- ret
-
- code ends
-
- end