brucee@runx.ips.oz (Bruce Evans) (11/26/88)
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 5 (of 7)."
# Contents: kernel/db/lib88.s
# Wrapped by sys@besplex on Sat Nov 26 06:00:26 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'kernel/db/lib88.s' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'kernel/db/lib88.s'\"
else
echo shar: Extracting \"'kernel/db/lib88.s'\" \(12769 characters\)
sed "s/^X//" >'kernel/db/lib88.s' <<'END_OF_FILE'
X| lib88.s
X
X| exported functions
X
X .define _codeseg
X .define _dataseg
X .define _get_processor
X .define _inportb
X .define _oportb
X .define _peek8
X .define _peekb
X .define _peek16
X .define _peekw
X .define _peek32
X .define _poke8
X .define _pokeb
X .define _poke16
X .define _pokew
X .define _poke32
X .define _scrclose
X .define _scrin
X .define _scrioctl
X .define _scropen
X .define _scrout
X .define _symswap
X .define _ttyclose
X .define _ttyioctl
X .define _ttyin
X .define _ttyopen
X .define _ttyout
X
X| imported functions
X
X .extern _get_con_state
X .extern _reset_con_state
X
XBACKSPACE = 8
XBIOS_DATA_SEG = 0x40
X ACTIVE_PAGE = 0x62 | byte
X ADDR_6845 = 0x63 | word
X CURSOR = 14 | indexes
X CUR_SIZE = 10
X CURSOFF = 0x1000 | no scan lines in range
X CURSON = 0x0F | scan lines 0 to 15
X VID_ORG = 12
X CRT_COLS = 0x4A | byte
X| CRT_LEN = 0x4C | word
X CRT_MODE_SET = 0x49 | byte
X MONO_MODE = 7
X| CRT_PALETTE = 0x66 | byte
X CRT_START = 0x4E | word
X CURSOR_MODE = 0x60 | word
X CURSOR_POSN = 0x50 | word[8]
XCOM1 = 0x3F8 | COM1 serial port (see data for one used)
XCOM2 = 0x2F8 | COM2 serial port (see data)
XCR = 13
XEOF = -1
XLF = 10
XSCR_ATTRIB = 0x3 | cyan text on black background
XSCR_CSEGMENT = 0xB800 | color screen segment
XSCR_LENGTH = 4000
X HSCR_LENGTH = SCR_LENGTH/2
XSCR_MSEGMENT = 0xB000 | mono screen segment
XSCR_START = 0
X HSCR_START = SCR_START/2
XSCR_TOP = SCR_START+SCR_LENGTH
XSCR_WIDTH = 160
X HSCR_WIDTH = SCR_WIDTH/2
XTAB = 9
XTRUE = 1
X
X| phys_clicks codeseg()
X
X_codeseg:
X mov ax,cs
X ret
X
X| phys_clicks dataseg()
X
X_dataseg:
X mov ax,ds
X ret
X
X| get some parameters from documented BIOS work area
X| MINIX must update these parameters when db is entered
X
Xget_crtc_port:
X mov cx,ds
X mov ax,#BIOS_DATA_SEG
X mov ds,ax
X mov ax,ADDR_6845
X mov ds,cx
X ret
X
Xget_cstype:
X mov cx,ds
X mov ax,#BIOS_DATA_SEG
X mov ds,ax
X mov ax,CURSOR_MODE
X mov ds,cx
X ret
X
Xget_cursor_ptr:
X mov cx,ds
X mov ax,#BIOS_DATA_SEG
X mov ds,ax
X movb bl,ACTIVE_PAGE
X movb bh,#0
X shl bx,#1
X mov ax,CURSOR_POSN(bx) | row, column in ah, al
X movb bl,al | but offset is required
X movb al,ah | row, column stored in inferior order
X mulb CRT_COLS | slow in the BIOS too
X add ax,bx
X shl ax,#1
X add ax,CRT_START
X mov ds,cx
X ret
X
Xgetscr_segment:
X mov cx,ds
X mov ax,#BIOS_DATA_SEG
X mov ds,ax
X movb al,CRT_MODE_SET
X cmpb al,#MONO_MODE
X mov ax,#SCR_MSEGMENT
X je got_scr_segment
X mov ax,#SCR_CSEGMENT
Xgot_scr_segment:
X mov ds,cx
X ret
X
Xgetscr_org:
X mov cx,ds
X mov ax,#BIOS_DATA_SEG
X mov ds,ax
X mov ax,CRT_START
X mov ds,cx
X ret
X
X| PUBLIC unsigned get_processor()
X| decide processor type among 8088=8086, 80188=80186, 80286, 80386
X| return 86, 186, 286 or 386
X| 8088=8086 and 80188=80186 push sp as new sp, 80286 and 80386 as old sp
X| all but 8088=8086 do shifts mod 32 or 16
X| 386 stores 0 for the upper 8 bits of the GDT pointer in 16 bit mode,
X| while 286 stores 0xFF
X| Preserves all registers except the flags and the return register ax
X
X_get_processor:
X push sp
X pop ax
X cmp ax,sp
X jz new_processor
X push cx
X mov cx,#0x0120
X shlb ch,cl | zero tells if 86
X pop cx
X mov ax,#86
X jz got_processor
X mov ax,#186
X ret
X
Xnew_processor:
X push bp
X mov bp,sp
X sub sp,#6 | space for GDT ptr
X| sgdt -6(bp) | save 3 word GDT ptr
X .byte 0x0F,0x01,0x46,0xFA
X add sp,#4 | discard 2 words of GDT ptr
X pop ax | top word of GDT ptr
X pop bp
X cmpb ah,#0 | zero only for 386
X mov ax,#286
X jnz got_processor
X mov ax,#386
Xgot_processor:
X ret
X
X| PUBLIC unsigned inportb( port_t port );
X| reads an (unsigned) byte from the i/o port port and returns it
X
X_inportb:
X pop bx
X pop dx
X dec sp
X dec sp
X in
X subb ah,ah
X| jmp bx
X push bx
X ret
X
X| void oportb( port_t port, u8_pt value );
X| writes the byte value to the i/o port port
X| this would be outportb except for feeble linkers
X
X_oportb:
X pop bx
X pop dx
X pop ax
X sub sp,#4
X out
X| jmp bx
X push bx
X ret
X
X| PUBLIC u8_pt peek8( struct adr *adr );
X| returns then (unsigned) byte at the address adr
X
X_peek8:
X mov cx,es
X pop dx
X pop bx
X push bx
X mov es,4(bx) | les can no longer be used
X mov bx,(bx) | since space is reserved for 32 bit offset
X seg es
X movb al,(bx)
X xorb ah,ah
X mov es,cx
X| jmp dx | asld does this non-portably
X push dx
X ret
X
X| PUBLIC u8_pt peekb( segment_t segment, u8_t *offset );
X| returns the (unsigned) byte at the far pointer segment:offset
X
X_peekb:
X mov cx,ds
X pop dx
X pop ds
X pop bx
X sub sp,#4
X movb al,(bx)
X subb ah,ah
X mov ds,cx
X| jmp dx
X push dx
X ret
X
X| PUBLIC u16_t peek16( struct adr *adr );
X
X_peek16:
X mov cx,es
X pop dx
X pop bx
X push bx
X mov es,4(bx)
X mov bx,(bx)
X seg es
X mov ax,(bx)
X mov es,cx
X| jmp dx
X push dx
X ret
X
X| PUBLIC u16_t peekw( segment_t segment, u16_t *offset );
X| returns the word at the far pointer segment:offset
X
X_peekw:
X mov cx,ds
X pop dx
X pop ds
X pop bx
X sub sp,#4
X mov ax,(bx)
X mov ds,cx
X| jmp dx
X push dx
X ret
X
X| PUBLIC u32_t peek32( struct adr *adr );
X
X_peek32:
X pop cx
X pop bx
X push bx
X push es
X mov es,4(bx)
X mov bx,(bx)
X seg es
X mov ax,(bx)
X seg es
X mov dx,2(bx)
X pop es
X| jmp cx
X push cx
X ret
X
X| PUBLIC void poke8( struct adr *adr, u8_pt value );
X
X_poke8:
X mov cx,es
X pop dx
X pop bx
X pop ax
X push ax
X push bx
X mov es,4(bx)
X mov bx,(bx)
X seg es
X movb (bx),al
X mov es,cx
X| jmp dx
X push dx
X ret
X
X| PUBLIC void pokeb( segment_t segment, u8_t *offset, u8_pt value );
X| writes the byte value at the far pointer segment:offset
X
X_pokeb:
X mov cx,ds
X pop dx
X pop ds
X pop bx
X pop ax
X sub sp,#6
X movb (bx),al
X mov ds,cx
X| jmp dx
X push dx
X ret
X
X| PUBLIC void poke16( struct adr *adr, u16_t value );
X
X_poke16:
X mov cx,es
X pop dx
X pop bx
X pop ax
X push ax
X push bx
X mov es,4(bx)
X mov bx,(bx)
X seg es
X mov (bx),ax
X mov es,cx
X| jmp dx
X push dx
X ret
X
X| PUBLIC void pokew( segment_t segment, u16_t *offset, u16_t value );
X| writes the word value at the far pointer segment:offset
X
X_pokew:
X mov cx,ds
X pop dx
X pop ds
X pop bx
X pop ax
X sub sp,#6
X mov (bx),ax
X mov ds,cx
X| jmp dx
X push dx
X ret
X
X| PUBLIC void poke32( struct adr *adr, u32_t value );
X
X_poke32:
X pop cx
X pop bx
X pop ax
X pop dx
X push dx
X push ax
X push bx
X push es
X mov es,4(bx)
X mov bx,(bx)
X seg es
X mov (bx),ax
X seg es
X mov 2(bx),dx
X pop es
X| jmp cx
X push cx
X ret
X
X| PUBLIC void scrclose();
X| reverse everything done by scropen()
X
X_scrclose:
X push di
X push si
X push es
X mov bx,u_cstype
X call set_cstype
X mov bx,u_cursor_ptr
X call set_cursor_ptr
X mov bx,u_scr_org
X call set_scr_org
X
X push ds
X pop es
X lds si,scr_ptr | just to get screen segment
X mov si,#SCR_START
X mov di,#db_screen
X mov cx,#HSCR_LENGTH
X rep
X movw
X push es
X push ds
X pop es
X pop ds
X mov si,#u_screen
X mov di,#SCR_START
X mov cx,#HSCR_LENGTH
X rep
X movw
X
X call _reset_con_state | just for keyboard
X pop es
X pop si
X pop di
X ret
X
X| PUBLIC char_pt scrin();
X
X_scrin:
X ret
X
X| PUBLIC void scrioctl( int command );
X| turn cursor on or off
X
X_scrioctl:
X pop dx
X pop ax
X push ax
X push dx
X or ax,ax
X mov bx,#CURSOFF
X je set_cstype | off, don't bother locating
X mov bx,scr_ptr
X dec ax
X jne scrio_ret
X call set_cursor_ptr
X mov bx,#CURSON
X
X| set cursor type to bx { ax, bx, dx }
X
Xset_cstype:
X mov ax,#CUR_SIZE * 256 + CUR_SIZE + 1 | pair of indexes
X
X| set crtc register pair al:ah to bl:bh { ax, bx, dx }
X
Xset_crtc:
X mov dx,crtc_port
X xchgb ah,bl | get low data in ah, high index in bl
X outw | write index:data ports in succession
X | don't know if this works with 16 bit bus
X xchg ax,bx | get high index in al, high data in ah
X outw
Xscrio_ret:
X ret
X
X| set hardware cursor to offset bx { ax, bx, dx }
X
Xset_cursor_ptr:
X shr bx,#1
X mov ax,#CURSOR * 256 + CURSOR + 1
X j set_crtc
X
X| set screen origin to offset bx { ax, bx, dx }
X
Xset_scr_org:
X shr bx,#1
X mov ax,#VID_ORG * 256 + VID_ORG + 1
X j set_crtc
X
X| PUBLIC void scropen();
X| set up independent db screen
X| save underlying piece of user screen
X| with Minix, there are many gotchas
X| Minix scrolls by moving the screen origin and there is a glitch when we
X| replace it. But it is too much work to use Minix coordinates
X| stupid CRTC regs are read-only so we must call O/S to get their state
X| the cursor position and size must also be saved
X| and all this assumes that the screen mode does not need switching!
X
X_scropen:
X push di
X push si
X push es
X call _get_con_state
X call get_crtc_port
X mov crtc_port,ax
X call get_cstype
X mov u_cstype,ax
X call get_cursor_ptr
X mov u_cursor_ptr,ax
X call getscr_org
X mov u_scr_org,ax
X
X call getscr_segment
X mov scr_ptr + 2,ax
X push ds
X pop es
X mov ds,ax
X mov si,#SCR_START
X mov di,#u_screen
X mov cx,#HSCR_LENGTH
X rep
X movw
X seg es
X cmpb scr_garbage,cl | cl is 0
X je over_setup_screen
X mov di,#db_screen
X mov ax,#SCR_ATTRIB * 256 + ' '
X mov cx,#HSCR_LENGTH
X rep
X stow
X seg es
X movb scr_garbage,cl | cl is 0
Xover_setup_screen:
X push es
X push ds
X pop es
X pop ds
X mov si,#db_screen
X mov di,#SCR_START
X mov cx,#HSCR_LENGTH
X rep
X movw
X
X mov bx,#CURSOFF | don't bother locating while off
X call set_cstype
X mov bx,#HSCR_START
X call set_scr_org
X pop es
X pop si
X pop di
X ret
X
X| PUBLIC void scrout( char_pt c );
X
X_scrout:
X pop cx
X pop ax
X dec sp
X dec sp
X push es
X movb ah,scr_attrib
X les bx,scr_ptr
X cmpb al,#' '
X jb scro_control
Xscro_normal:
X seg es | avoiding stow here, would have to push di
X mov (bx),ax
X inc bx
X inc bx
Xscro_checktop:
X cmp bx,#SCR_TOP
X jae scro_scroll
Xscro_exit:
X mov scr_ptr,bx
X pop es
X| jmp cx
X push cx
X ret
X
Xscro_control:
X cmpb al,#CR
X je scro_cr
X cmpb al,#LF
X je scro_lf
X cmpb al,#TAB
X je scro_tab
X cmpb al,#BACKSPACE
X jne scro_normal
X cmp bx,#0
X je scro_exit
X dec bx
X j scro_exit
X
Xscro_tab:
X movb al,#' '
Xscro_totab:
X seg es
X mov (bx),ax
X inc bx
X inc bx
X test bx,#0xF | make bx multiple of 16 to get tabs every 8
X jne scro_totab
X j scro_checktop
X
Xscro_cr:
X xchg ax,bx
X mov bx,#SCR_WIDTH
X xor dx,dx
X div bx
X mul bx
X xchg bx,ax
X j scro_exit
X
Xscro_lf:
X add bx,#SCR_WIDTH
X cmp bx,#SCR_TOP
X jb scro_exit
Xscro_scroll:
X sub bx,#SCR_WIDTH
X mov scr_ptr,bx
X push cx
X push ds
X push di
X push si
X push es
X pop ds
X mov di,#SCR_START
X mov si,#SCR_START+SCR_WIDTH
X mov cx,#HSCR_LENGTH-HSCR_WIDTH
X rep
X movw
X mov di,#SCR_TOP-SCR_WIDTH
X movb al,#' '
X mov cx,#SCR_WIDTH/2
X rep
X stow
X pop si
X pop di
X pop ds
X pop cx
X pop es
X| jmp cx
X push cx
X ret
X
X| PUBLIC void symswap( left, right, tableseg, length )
X| struct nlist *left;
X| struct nlist *right;
X| segment_t tableseg;
X| unsigned length; /* must be even */
X
X_symswap:
X push bp
X mov bp,sp
X push di
X push si
X push es
X push ds
X mov di,4(bp)
X mov si,6(bp)
X mov ax,8(bp)
X mov es,ax
X mov ds,ax
X mov cx,10(bp)
X shr cx,#1
Xssloop:
X mov ax,(di)
X movw
X mov -2(si),ax
X loop ssloop
X pop ds
X pop es
X pop si
X pop di
X pop bp
X ret
X
X| PUBLIC void ttyclose();
X
X_ttyclose:
X mov dx,serial_port
X
X| attempt to restore state
X
X addb dl,#3 | line control
X movb al,#0x80 | divisor latch
X out
X addb dl,#-3 | divisor low
X mov ax,baud_divisor
X out
X inc dx | divisor high
X movb al,ah
X out
X addb dl,#2 | line control
X movb al,u_line_control
X out
X inc dx | modem control
X movb al,u_modem_control
X out
X addb dl,#-3 | irq enable
X movb al,u_irq_enable
X out
X ret
X
X| PUBLIC char_pt ttyin();
X| input char from tty, return EOF if none
X
X_ttyin:
X mov dx,serial_port
X addb dl,#5
X in
X testb al,#1
X jne got_ttyin
X mov ax,#EOF
X ret
X
Xgot_ttyin:
X addb dl,#-5
X in
X xorb ah,ah
X ret
X
X| PUBLIC void ttyioctl( int command );
X| copy the user's tty state
X
X_ttyioctl:
X pop dx
X pop ax
X push ax
X push dx
X cmp ax,#2
X jne ttyio_ret
X mov ax,u_baud_divisor
X mov baud_divisor,ax
X movb al,u_line_control
X movb line_control,al
X movb al,u_modem_control
X movb modem_control,al
X call _ttyclose
X | fall into _ttyopen
X
X| PUBLIC void ttyopen();
X
X_ttyopen:
X mov dx,serial_port
X
X| attempt to save state in combination with setting baud rate,
X
X addb dl,#3 | line control
X in
X movb u_line_control,al
X movb al,#0x80 | divisor latch
X out
X addb dl,#-2 | divisor high
X in
X movb ah,al
X dec dx | divisor low
X in
X mov u_baud_divisor,ax
X mov ax,baud_divisor
X out
X inc dx
X movb al,ah
X out
X addb dl,#2 | line control
X movb al,line_control
X out
X inc dx | modem control
X in
X movb u_modem_control,al
X movb al,modem_control
X out
X addb dl,#-3 | irq enable
X in
X movb u_irq_enable,al
X movb al,#0 | no irqs
X out
Xttyio_ret:
X ret
X
X| PUBLIC void ttyout( char_pt c );
X
X_ttyout:
X mov dx,serial_port
X addb dl,#5
Xttyoloop:
X in
X testb al,#0x20
X je ttyoloop
X pop bx
X pop ax
X push ax
X addb dl,#-5
X out
X| jmp bx
X push bx
X ret
X
X .data
X .even
Xbaud_divisor:
X .word 12 | 115200/9600 for 9600 baud
Xcursor_ptr:
X .word HSCR_START
Xline_control:
X .byte 3 | no div latch, 1 stop bit, no parity, 8 bits
Xmodem_control:
X .byte 3 | no master irq, yes dtr and rts
Xscr_attrib:
X .byte SCR_ATTRIB
Xscr_garbage:
X .byte TRUE
Xscr_ptr:
X .word SCR_START,SCR_CSEGMENT
Xserial_port:
X .word COM1
X
X .bss
X .even
Xcrtc_port:
X .zerow 1
Xdb_screen:
X .space SCR_LENGTH
Xkbd_shift:
X .zerow 1
Xu_cstype:
X .zerow 1
Xu_cursor_ptr:
X .zerow 1
Xu_baud_divisor:
X .zerow 1
Xu_irq_enable:
X .space 1
Xu_line_control:
X .space 1
Xu_modem_control:
X .space 1
X .even
Xu_screen:
X .space SCR_LENGTH
Xu_scr_org:
X .zerow 1
END_OF_FILE
if test 12769 -ne `wc -c <'kernel/db/lib88.s'`; then
echo shar: \"'kernel/db/lib88.s'\" unpacked with wrong size!
fi
# end of 'kernel/db/lib88.s'
fi
echo shar: End of archive 5 \(of 7\).
cp /dev/null ark5isdone
MISSING=""
for I in 1 2 3 4 5 6 7 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 7 archives.
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
Bruce Evans
Internet: brucee@runx.ips.oz.au UUCP: uunet!runx.ips.oz.au!brucee