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