home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
assemblr
/
library
/
edit
/
fremacsr
/
ibm.asm
< prev
next >
Wrap
Assembly Source File
|
1987-03-16
|
15KB
|
776 lines
;History:26,1
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 scan_lines_per_char
scan_lines_per_char db 8
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 0
key_table label byte
db 3,'C-@',0
db 15,'Back Space',0
db 71,'Home',0
db 79,'End',0
db 73,'Pg Up',0
db 81,'Pg Dn',0
db 75,'Left Arrow',0
db 77,'Right Arrow',0
db 72,'Up Arrow',0
db 80,'Down Arrow',0
db 82,'Ins',0
db 83,'Del',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 84,'F1',0
db 85,'F2',0
db 86,'F3',0
db 87,'F4',0
db 88,'F5',0
db 89,'F6',0
db 90,'F7',0
db 91,'F8',0
db 92,'F9',0
db 93,'F10',0
db 94,'F1',0
db 95,'F2',0
db 96,'F3',0
db 97,'F4',0
db 98,'F5',0
db 99,'F6',0
db 100,'F7',0
db 101,'F8',0
db 102,'F9',0
db 103,'F10',0
db 104,'F1',0
db 105,'F2',0
db 106,'F3',0
db 107,'F4',0
db 108,'F5',0
db 109,'F6',0
db 110,'F7',0
db 111,'F8',0
db 112,'F9',0
db 113,'F10',0
db 119,'Home',0
db 117,'End',0
db 132,'Pg Up',0
db 118,'Pg Dn',0
db 115,'Left Arrow',0
db 116,'Right Arrow',0
db 160,'Up Arrow',0
db 164,'Down Arrow',0
db 165,'Ins',0
db 166,'Del',0
db 129,'0',0 ;alt top row
db 120,'1',0
db 121,'2',0
db 122,'3',0
db 123,'4',0
db 124,'5',0
db 125,'6',0
db 126,'7',0
db 127,'8',0
db 128,'9',0
db 130,'-',0
db 131,'=',0
db 16,'q',0 ;alt second row
db 17,'w',0
db 18,'e',0
db 19,'r',0
db 20,'t',0
db 21,'y',0
db 22,'u',0
db 23,'i',0
db 24,'o',0
db 25,'p',0
db 30,'a',0 ;alt third row
db 31,'s',0
db 32,'d',0
db 33,'f',0
db 34,'g',0
db 35,'h',0
db 36,'j',0
db 37,'k',0
db 38,'l',0
db 44,'z',0 ;alt fourth row
db 45,'x',0
db 46,'c',0
db 47,'v',0
db 48,'b',0
db 49,'n',0
db 50,'m',0
db 0,'Unknown',0
one_key_string db ?,0
ctrl_flag equ 1
left_flag equ 2
right_flag equ 4
alt_flag equ 8
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.
public color
color db 07h ;xbbbxfff bbb=background, fff=fore.
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.
;a character must be chosen which causes the idling string to be reloaded.
; this one is ctrl-prtsc.
public breakchar
breakchar dw 114*256 + 0
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.
their_keybd dd ? ;-> their keyboard handler.
public init_entry
init_entry:
mov ax,0*256 + 3 ;25x80 color.
int 10h
push es
mov ax,3509h
int 21h
mov word ptr their_keybd+0,bx
mov word ptr their_keybd+2,es
pop es
push ds
mov ax,cs
mov ds,ax
mov dx,offset our_keybd
mov ax,2509h
int 21h
pop ds
ret
public uninit_exit
uninit_exit:
;called when exiting. May destroy any but seg-regs.
mov dh,0 ;put the cursor on the last scrollable line.
mov dl,max_screen_line
inc dl
call position_cursor
push ds
lds dx,their_keybd
mov ax,2509h
int 21h
pop ds
ret
bios_seg segment at 40h
org 1ah
buffer_head dw ?
buffer_tail dw ?
kb_buffer dw 16 dup(?)
kb_buffer_end label word
bios_seg ends
our_keybd:
push ax
push bx
push ds
mov ax,bios_seg
mov ds,ax
assume ds:bios_seg
in al,60h ;get the current keycode.
mov ah,al ;remember the keycode.
and al,7fh ;forget the shift.
cmp al,1dh ;ctrl
je our_keybd_2
cmp al,2ah ;left shift
je our_keybd_2
cmp al,36h ;right shift
je our_keybd_2
cmp al,38h ;alt
jne our_keybd_1
our_keybd_2:
mov al,80h ;make a 80h with special scan codes.
mov bx,buffer_tail
add bx,2
cmp bx,offset kb_buffer_end
jne our_keybd_3
mov bx,offset kb_buffer
our_keybd_3:
cmp bx,buffer_head ;any room?
je our_keybd_1 ; no.
xchg buffer_tail,bx ;save the new, get the old.
mov [bx],ax ;store the key at the old ptr.
our_keybd_1:
pop ds
pop bx
pop ax
jmp their_keybd
assume ds:data
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,1 ;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.
ret
check_for_key_1:
call detect_shifts
jne check_for_key_2
mov ah,0 ;must have been a shift key -
int 16h ; get rid of it.
xor ax,ax
check_for_key_2:
ret
public get_key_value
get_key_value:
;exit with ax=keycode.
mov ah,0
int 16h
call detect_shifts ;remove shift bytes from the buffer.
je get_key_value
ret
detect_shifts:
;enter with ax=keycode.
;exit with zr,ax=0 if it was a shift code.
;exit with nz,ax=key if a real key.
cmp al,80h ;our special code?
jne detect_shifts_1 ;no - must be a real key.
detect_shifts_5:
mov al,ctrl_flag
cmp ah,1dh ;ctrl down
je detect_shifts_6
cmp ah,1dh+80h ;ctrl up
je detect_shifts_6
mov al,left_flag
cmp ah,2ah ;left shift down
je detect_shifts_6
cmp ah,2ah+80h ;left shift up
je detect_shifts_6
mov al,right_flag
cmp ah,36h ;right shift down
je detect_shifts_6
cmp ah,36h+80h ;right shift up
je detect_shifts_6
mov al,alt_flag
cmp ah,38h ;alt down
je detect_shifts_6
cmp ah,38h+80h ;alt up
jne detect_shifts_7 ;unknown, but not a key.
detect_shifts_6:
or shift_flags,al ;assume down
or ah,ah ;down or up?
jns detect_shifts_7 ;go if down
not al ;up - make inverse flag.
and shift_flags,al ; and turn the bit off.
detect_shifts_7:
xor ax,ax ;return zero.
detect_shifts_1:
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
or al,al ;extended function key?
je decode_key_5
push ax
mov si,offset key_others
call decode_search ;search for the scan code names.
pop ax
jne decode_key_1
mov ah,al
mov si,offset key_names
call decode_search ;search for the literal names.
jne decode_key_7 ;copy it in, but don't do shifts.
mov al,ah
cmp al,' ' ;control char?
jae decode_key_6 ;no
add al,'@' ;yes - convert into letter.
mov one_key_string,al
mov si,offset one_key_string
jmp decode_key_1
decode_key_6:
mov one_key_string,al
mov si,offset one_key_string
cmp al,' '
je decode_key_1 ;interpret shift for space bar.
call decode_meta ;don't interpret shift key for printables.
call decode_ctrl
jmp decode_key_7
decode_key_5:
mov si,offset key_table ;search for the extended functions.
call decode_search
decode_key_1:
call decode_meta
call decode_ctrl
call decode_shift
decode_key_7:
lodsb ;copy to the next null.
stosb
or al,al
jne decode_key_7
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:
mov bx,6779
call beep
ret
;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:
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"
mov ah,al ; 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
sub cx,cx ; Sneaky way to put 0FFFFH into CX when
wait2: loop wait2 ; LOOP is first executed
mov al,ah ; Get original 8255 Port "PB" settings
out 61h,al ; Reset port to original values-speaker off
ret
code ends
code segment byte public
assume cs:code, ds:nothing, es:data
;all of the code in this segment is called with the above assumes.
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 si
push di
push bp
push bx
xchg dh,dl
mov bh,0
mov ah,2 ;set cursor position
int 10h
cld
xchg dh,dl
pop bx
pop bp
pop di
pop si
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 ;compute the source byte.
mov al,80*2
mul dl
mov si,ax
pop ax
mov ah,80*2 ;compute the destination byte.
mul ah
mov di,ax
call get_video_seg ;get the video card plane.
mov ds,ax
mov cx,80 ;move the line.
rep movsw
pop es
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,80
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_1 ;yes.
mov ah,color
mov al,' ' ;clear to the background color.
push ax
call get_video_ptr
pop ax
mov cl,bl ;compute the number of chars to clear.
sub cl,dh
mov ch,0
rep stosw
clear_count_1:
pop es
pop bp
pop di
pop si
pop cx
pop bx
pop ax
ret
get_video_ptr:
;enter with dl=current row, dh=current column.
;return with es:di->character position.
mov al,80 ;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 ;b/w card?
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
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,80 ;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,20h ;print control chars specially.
jb xychrout_control
cmp al,0ffh ;print 255 specially
je xychrout_del
jmp short xychrout_1
xychrout_control:
mov ah,color
or ah,10h ;bold chars.
add al,'@'
jmp short xychrout_1
xychrout_del:
mov ah,color
or ah,10h
mov al,7fh ;bold del.
jmp short xychrout_1
xychrout_5:
mov ah,color
mov bx,offset font_8_table
sub al,4dh ;first character in font 8.
xlat
xychrout_1:
mov bx,inversing ;set the inverse video flag.
and bl,77h ;strip out just the color.
xor ah,bl ;now flip the colors (if desired).
push ax
call get_video_ptr
pop ax
stosw
xychrout_3:
pop ds
pop es
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.
if 0
mov dl,24 ;move the 25th line up.
mov al,23
call move_line
push bx
mov cx,0*256 + 0
mov dx,24*256 + 79
mov bh,07h
mov ax,7*256 + 1
int 10h
pop bx
clc
else
stc
endif
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
push bx
mov cx,0*256 + 0
mov dx,24*256 + 79
mov bh,07h
mov ax,6*256 + 1
int 10h
pop bx
mov dl,23 ;now move the 25th line back down.
mov al,24
call move_line
clc
else
stc
endif
ret
public block_cursor
block_cursor:
mov ah,1
mov cx,0*256 + 7
int 10h
ret
public underscore_cursor
underscore_cursor:
mov ah,1
mov cx,6*256 + 7
int 10h
ret
public set_screen_color
set_screen_color:
;enter with al=fore color, ah=back color
shl ah,1
shl ah,1
shl ah,1
shl ah,1
or al,ah
mov color,al
ret
code ends
end