Category : Assembly Language Source Code
Archive   : EMAC15ES.ZIP
Filename : TI.ASM

 
Output of file : TI.ASM contained in archive : EMAC15ES.ZIP
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 80
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

mouse_flag db ?
mouse_buttons db ?


public computer_name, computer_name_len
computer_name db 'TI-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.

key_names label byte
db ',','Comma',0
db '(','LPar',0
db ')','RPar',0
db 7fh,'Delete',0

db -1,'Timeout',0
if 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
endif
db 0


if 0
; This table contains the scan codes of ASCII control characters that
; have dedicated keys. (This table is not used on the TI PC since
; the scan code is not returned for ASCII characters.)
key_others label byte
db 21,'Back Space',0
db 26,'Tab',0
db 77,'Return',0
db 65,'Escape',0
db 62,'Line Feed',0
db 0

; This table contains the control states of keys from the "others" table.
; Since the search in the "others" table never succeeds on the TI PC,
; this table table is not used on the TI PC.

key_special label byte
db 7Fh,'C-Back Space',0
db 0Ah,'C-Return',0
db 0
endif

; The following table maps extended functions codes returned by the TI
; PC BIOS to associate key names.
key_table label byte
db 01h,'Pause',0

db 03h,'C-@',0

db 08h,'S-F11',0
db 09h,'S-F12',0
db 0Ah,'C-F11',0
db 0Bh,'C-F12',0
db 0Ch,'M-F11',0
db 0Dh,'M-F12',0

db 0Fh,'S-Tab',0
db 10h,'M-q',0
db 11h,'M-w',0
db 12h,'M-e',0
db 13h,'M-r',0
db 14h,'M-t',0
db 15h,'M-y',0
db 16h,'M-u',0
db 17h,'M-i',0
db 18h,'M-o',0
db 19h,'M-p',0

db 1Eh,'M-a',0
db 1Fh,'M-s',0
db 20h,'M-d',0
db 21h,'M-f',0
db 22h,'M-g',0
db 23h,'M-h',0
db 24h,'M-j',0
db 25h,'M-k',0
db 26h,'M-l',0

db 28h,'S-Ins',0
db 29h,'C-Ins',0
db 2Ah,'M-Ins',0

db 2Ch,'M-z',0
db 2Dh,'M-x',0
db 2Eh,'M-c',0
db 2Fh,'M-v',0
db 30h,'M-b',0
db 31h,'M-n',0
db 32h,'M-m',0

db 38h,'S-Del',0
db 39h,'C-Del',0
db 3Ah,'M-Del',0
db 3Bh,'F1',0
db 3Ch,'F2',0
db 3Dh,'F3',0
db 3Eh,'F4',0
db 3fH,'F5',0
db 40h,'F6',0
db 41h,'F7',0
db 42h,'F8',0
db 43h,'F9',0
db 44h,'F10',0
db 45h,'F11',0
db 46h,'F12',0
db 47h,'Home',0
db 48h,'Up Arrow',0
db 49h,'M-Up Arrow',0

db 4Bh,'Left Arrow',0
db 4Ch,'M-Left Arrow',0
db 4Dh,'Right Arrow',0
db 4Eh,'M-Right Arrow',0
db 4Fh,'M-Line Feed',0
db 50h,'Down Arrow',0
db 51h,'M-Down Arrow',0
db 52h,'Ins',0
db 53h,'Del',0
db 54h,'S-F1',0
db 55h,'S-F2',0
db 56h,'S-F3',0
db 57h,'S-F4',0
db 58h,'S-F5',0
db 59h,'S-F6',0
db 5Ah,'S-F7',0
db 5Bh,'S-F8',0
db 5Ch,'S-F9',0
db 5Dh,'S-F10',0
db 5Eh,'C-F1',0
db 5Fh,'C-F2',0
db 60h,'C-F3',0
db 61h,'C-F4',0
db 62h,'C-F5',0
db 63h,'C-F6',0
db 64h,'C-F7',0
db 65h,'C-F8',0
db 66h,'C-F9',0
db 67h,'C-F10',0
db 68h,'M-F1',0
db 69h,'M-F2',0
db 6Ah,'M-F3',0
db 6Bh,'M-F4',0
db 6Ch,'M-F5',0
db 6Dh,'M-F6',0
db 6Eh,'M-F7',0
db 6Fh,'M-F8',0
db 70h,'M-F9',0
db 71h,'M-F10',0
db 72h,'Print',0
db 73h,'C-Left Arrow',0
db 74h,'C-Right Arrow',0
db 75h,'C-Line Feed',0
db 76h,'C-Down Arrow',0
db 77h,'C-Home',0
db 78h,'M-1',0
db 79h,'M-2',0
db 7Ah,'M-3',0
db 7Bh,'M-4',0
db 7Ch,'M-5',0
db 7Dh,'M-6',0
db 7Eh,'M-7',0
db 7Fh,'M-8',0
db 80h,'M-9',0
db 81h,'M-0',0
db 82h,'M--',0
db 83h,'M-=',0
db 84h,'C-Up Arrow',0
db 85h,'M-Home',0
db 86h,'S-Home',0

db 88h,'S-Up Arrow',0
db 89h,'S-Down Arrow',0
db 8Ah,'S-Right Arrow',0
db 8Bh,'S-Left Arrow',0
db 8Ch,'PF1',0
db 8Dh,'PF2',0
db 8Eh,'PF3',0
db 8Fh,'PF4',0

db 0,'Unknown',0

break_key:
db 'Break',0


one_key_string db ?,0
ctrl_key_string db 'C-'
ctrl_key_char db ?,0

shift_flag equ 4
ctrl_flag equ 1
alt_flag equ 2
all_flags equ shift_flag + ctrl_flag + alt_flag
shift_flags db ?

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.

; The following are initialized since screen writes occur before
; init_entry is called.

fore_color db ? ; 000reccc r: reverse; e: enable;
back_color db ? ; c: color

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.

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_break dd ?
our_break proc far
mov cs:break_flag,1
stc
ret 2
our_break endp

their_map dd ?
our_map proc far

; This temporary keyboard mapping routine replaces C-space,
; M-space, and M-C-space by C-@, M-@, and M-C-@, respectively,
; provided Shift is not depressed.

; A more complex mapping routine could be used to permit combinations
; such as M-C-x and to disambiguate the special ASCII keys such as Tab
; and Line Feed from their control equivalents; they cannot be
; distnguished on the TI PC since the BIOS does not return the scan
; code for a normal ASCII character. (Note that disambiguating the
; special ASCII keys would force usage of a nonstandard character
; representation such as an addition to the extended function codes;
; however this might introduce problems with chained keyboard mapping
; routines or characters that are left in the keyboard buffer when
; subtasks are invoked.)

; AH contains the mode bits and AL the scan code.
test ah,alt_flag+ctrl_flag
je our_map_exit ; jump if neither alt or ctrl
test ah,shift_flag
jne our_map_exit ; jump if shift
cmp al,81 ; space
jne our_map_exit ; jump if not space
or ah,shift_flag ; replace space with @
mov al,10
our_map_exit:
jmp their_map ; give others a chance

our_map endp


public init_entry
init_entry:
push es ; get their C-break.
mov al,5Dh ; keyboard break interrupt
mov ah,35h
int 21h
mov word ptr their_break+0,bx
mov word ptr their_break+2,es
pop es

push ds ;set our C-break.
mov ax,cs
mov ds,ax
mov dx,offset our_break
mov al,5Dh ; keyboard break interrupt
mov ah,25h
int 21h
pop ds

push es ; get their keyboard mapping vector
mov al,5Bh
mov ah,35h
int 21h
mov word ptr their_map+0,bx
mov word ptr their_map+2,es
pop es

push ds ; set our keyboard mapping interrupt
mov ax,cs
mov ds,ax
mov dx,offset our_map
mov al,5Bh ; keyboard mapping interrupt
mov ah,25h
int 21h
pop ds

push ax
push dx
push di
push es

; Use the attributes of the character at the approximate middle of the
; screen to set the original foreground and background colors. This is
; not completely satisfactory since the screen IO used by COMMAND.COM
; apparently sets the attributes of trailing blanks on output lines to
; the color white. The best approach is to select colors using
; EDIT-OPTIONS.
mov dh,num_screen_cols ; last column
dec dh
mov dl,max_screen_line ; last line
add dl,2
shr dh,1 ; approximate mid points
shr dl,1
call get_video_ptr
mov al,es:[di] ; read a character to get its attributes
mov ax,0DF80h ; read the attribute latch
mov es,ax
mov al,es:[0]
and al,07h ; isolate the color
mov fore_original,al
or al,08h ; The TI PC does not have a background
mov back_original,al ; color; use reverse video.

; Set the current colors since the copyright notice is written before
; the screen colors are set.
push ds
pop es
mov ah,back_original
mov al,fore_original
call set_screen_color

pop es
pop di
pop dx
pop ax

ret


public uninit_exit
uninit_exit:
; called when exiting (including suspending to invoke another program).
; May destroy any but seg-regs.
push ds ; restore C-break.
mov al,5Dh ; keyboard break interrupt
lds dx,their_break
mov ah,25h
int 21h
pop ds

push ds ; restore keyboard mapping
mov al,5Bh
lds dx,their_map
mov ah,25h
int 21h
pop ds

; set the attribute latch to the default foreground color and position
; the cursor on the last line.

mov dl,max_screen_line ; last line
add dl,2
mov dh,0 ; column 0
call clear_to_eol
call position_cursor

ret


public store_ibm_cga
store_ibm_cga:
ret


public store_debug
store_debug:
if 0
push ds
push es
push ax
mov ax,data
mov ds,ax
mov es,ax
mov dh,num_screen_cols
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 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,01h ; check keyboard status
int 4Ah
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,00h ; keyboard input
int 4Ah
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

if 0
cmp ax,0f9h ;one of the mouse buttons?
jb decode_key_7
cmp ax,0feh
ja decode_key_7

; mouse buttons:
push ax
mov ah,02h ; keyboard mode
int 4Ah
and al,all_flags ;isolate the flags we're interested in.
mov shift_flags,al
call decode_meta
call decode_ctrl
call decode_shift
pop ax

decode_key_7:
endif

or al,al ;extended function key?
je decode_key_5
cmp al,0e0h
je decode_key_5

if 0
; The following code searches for ASCII control characters that have
; dedicated keys so those keys can be distinguished from their C-
; counterparts; for example, Return and C-m return different strings.
; (Since the TI PC BIOS always returns 0 in AH if the value in AL is not
; 0, this technique does not work on the TI PC.)
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.
endif

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

if 0
; This code decodes dedicated keys found in the "others" table whose
; C- version is special; e.g., the C- form of Back Space is 7Fh, which
; is Delete or C-Back Space. Since the search in the "others" table
; never succeeds on the TI PC, this code cannot be reached.
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
endif

; Process a non-control ASCII character.
decode_key_6:
mov one_key_string,al
mov si,offset one_key_string
jmp short decode_key_1

; Process an extended function key. On the TI PC, 00h is the
; representation of the Break key, which requires special processing due
; 00h being used to indicate the end of a table. (Since the break is
; detected via an interrupt, this special handling for Break not needed.)
decode_key_5:
mov si,offset break_key
cmp ah,0
je decode_key_1
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


if 0
; The following decode pseudo keys entered via the mouse, so are not
; needed on the TI PC.
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
endif


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:
mov cx,1563 ; 1250000 Hz / 800 Hz
mov ah,02h ; set frequency
int 48h ; speaker DSR
mov al,20 ; 0.5 sec = 20 * 25 msec
mov ah,0 ; sound speaker
int 48h ; speaker DSR
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,0
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 ax
push cx
push dx
mov ah,02h
int 49h
pop dx
pop cx
pop ax
ret


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
xor dh,dh ; compute source address
call get_video_ptr
mov si,di
assume es:nothing
mov ax,es
mov ds,ax

pop dx ; compute destination address
xor dh,dh
call get_video_ptr

mov cx,word ptr num_screen_cols ; move the line.
rep movsb

move_line_3:
pop es
assume es:data
pop ds
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.
cmp dh,bl ;already past it?
jae clear_count_0 ;yes.

push ax
push bx
push cx
push dx
push di
push es

mov ah,fore_color
; mov cx,inversing ; inverse video flag - 0000 or FFFFh
; and cl,10h ; inverse bit only
; xor ah,cl ; flip inverse bit in attribute byte
mov cx,0DF80h ; attribute latch at DF80:0000
mov es,cx
assume es:nothing
mov es:[0],ah
xor cx,cx
mov cl,bl
sub cl,dh
call get_video_ptr
mov al,' '
rep stosb

pop es
assume es:data
pop di
pop dx
pop cx
pop bx
pop ax

clear_count_0:
ret

get_video_ptr:
;enter with dl=current row, dh=current column.
;return with es:di->character position.
push ax
push cx
push dx
mov al,num_screen_cols ;compute the offset of the char.
mul dl
add al,dh
adc ah,0
mov di,ax
mov ah,17h ; get physical display address
int 49h
add di,dx
mov ax,0DE00h
mov es,ax
pop dx
pop cx
pop ax
ret

public xychrout
xychrout:
;enter with dh=col, dl=row, al=character to print, ah=font to print it in.
push ax
push bx
push cx
push dx
push di
push ds
push es

cmp dh,num_screen_cols ; past the right margin?
jae xychrout_1 ; yes - do not print
cmp ah,0 ; font zero?
jne xychrout_not_font_0 ; no
mov ah,fore_color

; The following will display characters in the range 80h to FFh using
; inverse video of the corresponding character in the range 00h to 7Fh.
; Otherwise, the characters will be displayed using whatever the PC
; has in its font.
if 0
cmp al,80h ; meta character?
jb xychrout_not_meta ; no
xor ah,10h ; yes - inverse video
and al,7Fh ; mask meta bit
xychrout_not_meta:
endif

cmp al,20h ; control character?
jae xychrout_not_control ; no
or ah,20h ; yes - underline
add al,'@' ; convert to printable
xychrout_not_control:
jmp short xychrout_2
xychrout_not_font_0:
mov ah,fore_color
mov bx,offset font_8_table
sub al,4Dh ; first character in font 8
mov cx,es
mov ds,cx
xlat
xychrout_2:
mov bx,inversing ; inverse video flag - 0000 or FFFFh
and bl,10h ; inverse bit only
xor ah,bl ; flip inverse bit in attribute byte
mov bx,0DF80h ; attribute latch at DF80:0000
mov es,bx
assume es:nothing
mov es:[0],ah
call get_video_ptr
stosb
xychrout_1:
pop es
assume es:data
pop ds
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.

if 0
; The following BIOS call is too slow since the screen is repainted
; after each line.
push bx
push cx
push dx
mov dh,0 ; source column
mov dl,ah ; source row
mov bh,0 ; destination column
mov bl,dl ; destination row
inc bl
mov ch,num_screen_cols ; column length
mov cl,al ; lines to scroll
sub cl,ah
mov al,0 ; blank exposed lines
mov ah,07h
int 49h
pop dx
pop cx
pop bx
clc
ret
endif
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.

if 0
; The following BIOS call is too slow since the screen is repainted
; after each line.
push bx
push cx
push dx
mov bh,0 ; destination column
mov bl,ah ; destination row
mov dh,0 ; source column
mov dl,bl ; source row
inc dl
mov ch,num_screen_cols ; column length
mov cl,al ; lines to scroll
sub cl,ah
mov al,0 ; blank exposed lines
mov ah,06h
int 49h
pop dx
pop cx
pop bx
clc
ret
endif
no_roll_up:
stc
ret


public set_screen_color
set_screen_color:
;enter with al=fore color, ah=back color

; Process the foreground color.
push ax
mov ah,al
and al,07h ; isolate the color bits
and ah,08h ; isolate bit 3
shl ah,1 ; shift into position for reverse video
or ah,08h ; add the character enable bit
or al,ah ; combine with the color bits
mov fore_color,al
pop ax

; Process the background color.
mov al,ah
and al,07h ; isolate the color bits
and ah,08h ; isolate bit 3
shl ah,1 ; shift into position for reverse video
or ah,08h ; add the character enable bit
or al,ah ; combine with the color bits
mov back_color,al
ret


public pick_init, pick_on, pick_off, check_pick, get_pick_values
pick_init:
mov mouse_flag,0
ret


pick_on:
pick_off:
ret


check_pick:
;return nz and al=pick character. return zr if no pick.
xor al,al
ret


get_pick_values:
mov cx,0
mov dx,0
ret

code ends

end


  3 Responses to “Category : Assembly Language Source Code
Archive   : EMAC15ES.ZIP
Filename : TI.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/