📄 plane.asm
字号:
;Set up outer counter in DX
MOV DX,AX
POP CX ;Inner loop counter
POP AX ;AL = color
;AH = 11111111B(all bits set\)
;
OUTER: PUSH CX ;Save inner loop counter
PUSH BX ;Save start address
;
INNER: CALL WRITE_PIX
INC BX ;Index to next 8-pixel block
LOOP INNER
;Index to next column
POP BX ;Restore start of this row
ADD BX,80 ;Index to next row start
POP CX ;Restore inner loop counter
DEC DX ;Decrement total rows
JNZ OUTER ;Continue if not end of count
;Restore input registers
POP AX
POP DX
POP CX
RET
COARSE_FILL ENDP
;==========================================================================================
;on entry
; CH=pillar number (range 0 to 79)= x coordinate
; CL=rank number (range 0 to 59)= y coordinate
;Compute byte address in BX from pillar in CH and the rank in CL as follows:
; byte address=(CL*640)+CH
;on exit
; BX=byte offset into video buffer
;==========================================================================================
COARSE_ADD PROC NEAR
PUSH AX
PUSH DX
PUSH CX
MOV AX,CX
MOV AH,0
MOV CX,640
MUL CX
;The multiplier(640) is the product of 80 bytes per pillar
; times 8 vertical pixels in each rank
POP CX
POP DX
MOV CL,CH
MOV CH,0
ADD AX,CX
MOV BX,AX
POP AX
RET
COARSE_ADD ENDP
;==========================================================================================
;Text display procedures: display a message on the graphics screen
;on entry:
; DS:DI -> Address of graphics display block(e.g.,GALL_MS)
;==========================================================================================
GRAPHIC_TEXT PROC NEAR
MOV DH,[DI] ;Get row into DH
INC DI ;Bump pointer
MOV DL,[DI] ; and column to DL
MOV START_COL,DL ;Store start column
MOV AH,2 ;Set cursor position
MOV BH,0 ;Page 0
INT 10H ;BIOS video call
INC DI ;Bump pointer to attribute
MOV BL,[DI] ;Get color code into BL
CHAR_WRITE: INC DI ;Bump to message start
MOV AL,[DI] ;Get character
CMP AL,0FFH ;End of line?
JE BUMP_ROW ;Next row
CMP AL,0 ;Test for terminator
JZ END_TEXT ;Exit routine
CALL SHOW_CHAR
JMP CHAR_WRITE
END_TEXT: RET
BUMP_ROW: INC DH ;Row control register
MOV DL,START_COL ;Column control to start column
MOV AH,2 ;Set cursor position
MOV BH,0 ;Page 0
INT 10H ;BIOS video call
JMP CHAR_WRITE
RET
GRAPHIC_TEXT ENDP
;==========================================================================================
;Display character in AL and using the color code in BL
SHOW_CHAR PROC NEAR
MOV AH,9 ;BIOS service request number
MOV BH,0 ;Page
MOV CX,1 ;No repeat
INT 10H
;Bump cursor
INC DL
MOV AH,2 ;Set cursor position
MOV BH,0 ;Page 0
INT 10H ;BIOS video call
RET
SHOW_CHAR ENDP
;==========================================================================================
;Display an encoded graphics block
;On entry:
; SI -> Start of control area of graphics block to be displayed
; BX -> Start of block holding color codes
;Register setup:
; CX = x coordinate of block start
; DX = y coordinate of block start
; BL = number of rows in block
; BH = number of bytes per block row
; DI -> start of encoded graphics block
; SI -> start of encoded color codes
;Memory:
; COUNT_8......Counter for 8 bits
;==========================================================================================
VARI_PATTERN PROC NEAR
;Initialize registers
PUSH BX ;Save pointer in stack
MOV CX,WORD PTR [SI] ;X coordinate
MOV X_COORD,CX ;Store in variable
ADD SI,2 ;Bump pointer
MOV DX,WORD PTR [SI] ;Y coordinate
ADD SI,2 ;Bump pointer
MOV BL,BYTE PTR [SI] ;Number of rows
INC SI ;Bump pointer
MOV BH,BYTE PTR [SI] ;Bytes per block
MOV BYTES,BH ;Store in variable
INC SI ;Bump pointer
XCHG SI,DI ;Buffer start to DI
POP SI ;Color code block pointer
MOV COUNT_8,8 ;Prime bit counter
DISPLAY_BYTE:
MOV AH,[DI] ;High-order nibble to AH
TEST_BIT:
TEST AH,10000000B ;Is high-order bit set?
JZ NEXT_BIT ;Bit not set
MOV AL,[SI] ;Get color code
;Set the pixel
PUSH AX ;Save entry registers
PUSH BX
CALL PIXEL_ADD ;See 10.2
CALL WRITE_PIX ;See 10.3
POP BX ;Restore registers
POP AX
NEXT_BIT:
SAL AH,1 ;Shift AH to test next bit
INC CX ;Bump x coordinate counter
INC SI ;Bump color table pointer
DEC COUNT_8 ;Bit counter
JZ NEXT_BYTE ;Exit if counter rewound
JMP TEST_BIT ;Continue
;Index to next byte in row, if not at the end of row
NEXT_BYTE:
DEC BH ;Bytes per row counter
JZ NEXT_ROW ;End of graphics row
BYTE_ENTRY:
INC DI ;Bump grpahics code counter
MOV COUNT_8,8 ;Restore bits counter
JMP DISPLAY_BYTE
;Index to next row
NEXT_ROW:
;Test for last graphic row
DEC BL ;Row counter
JZ GRAPH_END ;Done,exit
MOV BH,BYTES ;Reset bytes counter
INC DX ;Bump y coordinate control
MOV CX,X_COORD ;Reset x coordinate control
JMP BYTE_ENTRY
GRAPH_END:
RET
VARI_PATTERN ENDP
;==========================================================================================
;Address computation from x and y pixel coordinates
;On entry:
; CX = x coordinate of pixel (range 0 ~ 639)
; DX = y coordinate of pixel (range 0 ~ 479)
;On exit:
; BX = byte offset into video buffer
; AH = bit mask for the write operation (using VGA write modes 0 or 2)
;==========================================================================================
PIXEL_ADD PROC NEAR
PUSH CX ;save all entry registers
PUSH DX
;Compute address
PUSH AX ;save accumulator
PUSH CX ;svae x coordinate
MOV AX,DX ;y coordinate to AX
MOV CX,80 ;multiplier (80 bytes per row)
MUL CX ;AX = y times 80
MOV BX,AX ;free AX and hold in BX
POP AX ;x coordinate from stack
;Prepair for division
MOV CL,8 ;divisor
DIV CL ;AX/CL = quotient in AL and
; remainder in AH
;Add in quotient
MOV CL,AH ;Save remainder in CL
MOV AH,0 ;Clear high-order byte
ADD BX,AX ;Offset into buffer to BX
POP AX ;Restore AX
;Compute bit mask from remainder
MOV AH,128 ;Unit mask for 0 remainder (128=10000000B)
SHR AH,CL ;Shift right CL times
;Restore all entry registers
POP DX
POP CX
RET
PIXEL_ADD ENDP
;==========================================================================================
;VGA mode 12H device driver for writing an individual pixel
; or a pixel pattern to the graphics screen
;On entry:
; ES = 0A000H
; BX = byte offset into the video buffer
; AL = pixel color in IRGB format
; AH = bit pattern to set
;This routine assumes that write mode 2 has been set
;==========================================================================================
WRITE_PIX PROC NEAR
PUSH DX ;Save outer loop counter
PUSH AX ;Color byte
PUSH AX ;Twice
;Set Bit Mask requster according to mask in AH
MOV DX,3CEH ;Graphics controller latch
MOV AL,8
OUT DX,AL ;Select data register 8
JMP SHORT $+2
INC DX ;To 3CFH
POP AX ;AX once from stack
MOV AL,AH ;Bit pattern
OUT DX,AL ;Load bit mask
JMP SHORT $+2
;Write color code
MOV AL,ES:[BX] ;Dummy read to load latch registers
POP AX ;Restore color code
MOV ES:[BX],AL ;Write the pixel with the color code in AL
POP DX ;Restore outer loop counter
RET
WRITE_PIX ENDP
;==========================================================================================
DATA_NORMAL PROC NEAR
PUSH DX
PUSH CX
;Set the Graphics controller data rotate register to the normal mode
MOV DX,03CEH ;Graphics controller port address
MOV AL,3 ;Select Data Rotate register
OUT DX,AL
JMP SHORT $+2
INC DX ;03CFH register
MOV AL,00000000B ;Reset bits 3 and 4 for normal
OUT DX,AL
JMP SHORT $+2
POP CX
POP DX
RET
DATA_NORMAL ENDP
;==========================================================================================
DATA_XOR PROC NEAR
PUSH DX
PUSH CX
;Set the Graphics controller Data Rotate register to the XOR mode
MOV DX,03CEH ;Graphics controller port address
MOV AL,3 ;Select Data Rotate register
OUT DX,AL
JMP SHORT $+2
INC DX ;03CFH register
MOV AL,00011000B ;Set bits 3 and 4 for XOR
OUT DX,AL
JMP SHORT $+2
POP CX
POP DX
RET
DATA_XOR ENDP
;==========================================================================================
;Cursor movement procedures
;Erase old cursor and reposition cross hair according to mouse movement detected
;If CH high-order bit set then horizontal movement is left
;If DH high-order bit set then vertical movement is up
;==========================================================================================
MOVE_CURSOR PROC NEAR
CALL XOR_XHAIR ;Erase old cross hair
CMP CX,0 ;Test for no x-axis movement
JE NO_HORZ ;No horizontal move if CX zero
CALL UPDATE_X ;Update horizontal position
;
NO_HORZ: CMP DX,0
JE NO_VERT ;Test for vertical movement
CALL UPDATE_Y ;Update vertical position
;
NO_VERT: CALL XOR_XHAIR ;Redisplay cursor
RET
MOVE_CURSOR ENDP
;==========================================================================================
UPDATE_X PROC NEAR
;Update counter CROSS_X with value in CL testing for limits
;CH high-order bit set if mouse movement was left
;==========================================================================================
TEST CH,10000000B ;Decrement counter if high-order bit set
JNZ X_COUNT_DOWN ;Go if bit set
;Increment counter in loop. Cursor movement is right
X_RIGHT: CMP CROSS_X,CUR_LIM_RIGHT ;Equate for right-hand limit
JA NO_RIGHT_X ;No right movement
INC CROSS_X ;Bump counter if not at limit
LOOP X_RIGHT
;
NO_RIGHT_X: RET
;Decrement horizontal position
X_COUNT_DOWN:
MOV CH,0 ;Clear high-order byte of counter
NOT CL ;Convert 2's complement values
INC CL ;To unsiqned binary
;
X_LEFT: CMP CROSS_X,CUR_LIM_LEFT ;Equate for left_hand limit
JB NO_LEFT
DEC CROSS_X ;Decrement counter
LOOP X_LEFT
NO_LEFT:
RET
UPDATE_X ENDP
;==========================================================================================
UPDATE_Y PROC NEAR
;Update counter CROSS_Y with value in DL testing for limits
;CH high-order bit set if mouse movement was up
;==========================================================================================
XCHG DX,CX ;Move value to CX
TEST CH,10000000B ;Decrement counter if high-order bit set
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -