|
||||
ASSEMBLY PROGRAMMING AND OS DESIGN
<HOME>
|
CH2.6 String Routines
You've used DOS to display stuff. You've used BIOS as well.
Now it's time to do everything without any help. The title of this
section may be string routines, but by the time you finish this section,
you will have written a fully functional, 16 BIT terminal output library. TERM_X db 0 TERM_Y db 0 TEXT_PROPERTY db 1fh TERM_CURSOR db "_" CURSOR_MEM dw 0 ;==================================== ; cls ;==================================== _CLS: push CX push GS push BX mov AX,0b800h mov GS,AX mov AL,0 mov AH,[TEXT_PROPERTY] mov CX,3200 mov BX,0 .LOOP: mov [GS:BX],AX inc BX inc BX dec CX jnz .LOOP mov [CURSOR_MEM],AX pop BX pop GS pop CX ret ;==================================== ; putc(ch) where BL contains ch ;==================================== _PUTC: push DX push ES push SI mov AX,0b800h mov ES,AX ;set up screen segment mov BH,[TEXT_PROPERTY] ;load display property mov SI,0 ;screen address mov AL,160 ;screen is 160 BYTES in width mul byte [TERM_Y] ;AX=160*TERM_Y mov DL,[TERM_X] ;DL=TERM_X movzx DX,[TERM_X] ;DX=DL shl DX,1 ;DX=DX*2 - 2 BYTES per char add AX,DX ;AX=AX+DX - offset in screen add SI,AX mov AL,[TERM_X] ;AL=TERM_X for updating cmp BL,13 ;process CR je CARRIAGE_RETURN cmp BL,10 ;ignore LF je DONE2 cmp BL,0 je DRAW_CURSOR mov [ES:SI],BX inc SI inc SI inc AL cmp AL,40 jb DRAW_CURSOR CARRIAGE_RETURN: mov BX,[CURSOR_MEM] ;replace old cursor with mem mov [ES:SI],BX xor AL,AL inc byte [TERM_Y] ;adjust x and y to next line cmp byte [TERM_Y],25 jb DRAW_CURSOR dec byte [TERM_Y] mov SI,160 mov DI,0 mov CX,24*160 rep ES movsw mov CX,160 mov AH,[TEXT_PROPERTY] mov AL,0 rep stosw DRAW_CURSOR: mov [TERM_X],AL ;recompute address for cursor mov SI,0 ;screen address mov AL,160 ;screen is 160 BYTES in width mul byte [TERM_Y] ;AX=160*TERM_Y mov DL,[TERM_X] ;DL=TERM_X movzx DX,[TERM_X] ;DX=DL shl DX,1 ;DX=DX*2 - 2 BYTES per char add AX,DX ;AX=AX+DX - offset in screen add SI,AX DONE1: mov AH,[TEXT_PROPERTY] mov AL,[TERM_CURSOR] mov BX,[ES:SI] mov [CURSOR_MEM],BX mov [ES:SI],AX DONE2: pop SI pop GS pop DX ret ;==================================== ; puts(string*) - where BX points to ; NULL terminated string ;==================================== _PUTS: push BX xor AX,AX mov SI,BX .LOOP: mov BL,byte [SI] cmp BL,0 je DONE_PUTS call _PUTC inc SI inc AX jmp .LOOP DONE_PUTS: pop BX ret ;==================================== ; puthex(hex) - where BL contains ; value to display in hex ;==================================== _PUTHEX: push BX push CX shl BX,4 shr BL,4 cmp BL,10 jb ITS_A_NUMBERL add BL,7 ;48+17=65 which is ASCII for 'A' ITS_A_NUMBERL: add BL,48 mov CL,BL shr BX,4 shr BL,4 cmp BL,10 jb ITS_A_NUMBERH add BL,7 ;48+17=65 which is ASCII for 'A' ITS_A_NUMBERH: add BL,48 call _PUTC mov BL,CL call _PUTC pop CX pop BX ret ;======================================= ; set_term_xy(x,y) - where BH contains y ; coordinate and BL contains x ;======================================= _SET_TERM_XY: push BX push DX push ES push SI mov AX,0b800h mov GS,AX ;set up screen segment mov SI,0 ;screen address mov AL,160 ;screen is 160 BYTES in width mul byte [TERM_Y] ;AX=160*TERM_Y mov DL,[TERM_X] ;DL=TERM_X movzx DX,[TERM_X] ;DX=DL shl DX,1 ;DX=DX*2 - 2 BYTES per char add AX,DX ;AX=AX+DX - offset in screen add SI,AX mov AX,[CURSOR_MEM] mov [ES:SI],AX mov [TERM_X],BX mov BH,[TEXT_PROPERTY] ;load display property mov SI,0 ;screen address mov AL,160 ;screen is 160 BYTES in width mul byte [TERM_Y] ;AX=160*TERM_Y mov DL,[TERM_X] ;DL=TERM_X movzx DX,[TERM_X] ;DX=DL shl DX,1 ;DX=DX*2 - 2 BYTES per char add AX,DX ;AX=AX+DX - offset in screen add SI,AX mov AX,[ES:SI] mov [CURSOR_MEM],AX mov BL,[TERM_CURSOR] mov [ES:SI],BX pop SI pop ES pop DX pop BX ret ;==================================== ; set_text_property(pr) - where BL ; contains pr ;==================================== _SET_TEXT_PROPERTY: mov [TEXT_PROPERTY],BL ret |
| www.cynergysoft.com |
Email any questions to the author, Nathan Daniels. |
Copyright © 2001 |