Line-by-line comment on part of the assembly source code:
;sybc 16-bit color character output based on x86 v 1.1.32
;Parameter list:
;1. No parameters
; Example: sybc
; Call: When called from the command line without additional parameters or when the 0080 data is "00" when called by debug, the choice function is enabled.
; Function: Pause the command line and wait for the user to press a keyboard key. It is ineffective for shift and other keys, but effective for keys like esc, f1, space, enter, etc.
; Technology: In the , interrupt 15 is called, and al = ah, and it exits and returns al to erroelrvrer.
;2. Standard mode
; Example: sybc 10000$f1sybn$f22010 sybc 10000$f1sybn;$f22010;:10308f4sybn
; set v=`a80`db 10 0d "%sybcc%" 0d``rcx`ff`g`q
; (echo.%sybcom:`=&echo.dw %&echo.%v:`=&echo.%)|debug>nul
; Call: When called from the command line with parameters or when the 0080 of the debug call is not "00" and 0081 is not "01", it is enabled.
; Function: Output on one line (without semicolon) or multiple lines (with semicolon) or at non-consecutive positions (with semicolon colon).
; Technology: First, read a coordinate information (read 5 bytes),
; Then read a color information a dollar sign plus 2 bytes of color information. Here, the dollar sign can be omitted.
; Then read the data and output it to the b800 display buffer with the previous color information, so as to display it on the character interface.
; Until a control character is encountered. The control characters are:
; {24 "$"} color marker. When the program encounters the , it jumps to , reads 2 bytes of color information. Only the that is immediately followed by the coordinate information can be omitted.
; {3b ";"} line feed marker. When the program encounters the , it jumps to , then line feed, unless used in conjunction with {3a ":"}.
; {23 "#"} skip marker. When the program encounters the , it adds 1 to di, so as to reserve a character, only change the color, and do not modify the original content at the position of #.
; {0d " "} end marker. When the program encounters the , it ends the program.
; {3a ":"} start marker. Only effective when used in conjunction with , jumps to , reads a new coordinate color information to execute, can be used to connect 2 sybc commands.
; Note: In theory, ";:" can connect sybc infinitely, but the parameter length is limited to 124.
;3. Debug exclusive mode
; Example: set v=`a80`db ff``a282`db "%sybcc:~0,75%"`db "%sybcc:~75,75%"`db "%sybcc:~150,75%"`db "%sybcc:~225,75%"`db 0d``rcx`ff`g`q
; (echo.%sybcom:`=&echo.dw %&echo.%v:`=&echo.%)|debug>nul
; Call: Only for debug call, write ff in the 0080 position, and write parameters in the 0282 position, so as to skip the 124 parameter limit. The parameter limit of the example code is extended to 300.
; Technology: When reading, if 0080 = ff, then the parameter entry is modified to 0282. It is impossible to have 0080 = ff in normal call.
; Note: If needed, the example code can be modified to further extend the parameter limit.
mov si,0080 ; Set SI = 0080 Modify pointer address to 0080 Parameter entry
mov DX,0000 ; Set DX = 0000
lodsb ; Read data from DS:SI pointer address to AL At this time, SI = 0080
mov ah,al ; Set AH = AL AL = data read from 0080
lodsb ; Read data from DS:SI pointer address to AL At this time, SI = 0081
lodsb ; Read data from DS:SI pointer address to AL At this time, SI = 0082
mov BL,al ; Set BL = AL AL = data read from 0082
cmp ah,00 ; Compare Ah value and 0 At this time Ah = value of 0080
jz #TOchoice ; Jump to label TOchoice if equal To get keyboard input
cmp ah,ff ; Compare Ah value and FF At this time Ah = value of 0080
mov si,0082 ; Modify pointer address to 0082 Skip 0081
jnz #hqzb ; Jump to label hqzb if not equal Get output coordinates
mov si,002c ; Set SI = 0080 Modify pointer to 002c Memory variable segment address
lodsb ; Read data from DS:SI pointer address to AL At this time, SI = 002c
mov ah,al ; Set AH = AL AL = read data
lodsb ; Read data from DS:SI pointer address to AL At this time, SI = 002d
xchg al,ah ; Exchange AL and AH
push ax ; Push data onto the stack AX is pushed onto the stack
pop ds ; Pop data from the stack DS = AX from the previous line
mov si,0000 ; Set SI = 0080 Modify pointer to 0000 Because we need to search for variables from the beginning of the memory variable segment
#SSBL
lodsb ; Read data from DS:SI pointer address to AL
cmp al,53 ; Compare Al and 53 53 = "S"
jnz #SSBL ; Jump to label SSBL if not equal
lodsb ; Read data from DS:SI pointer address to AL
cmp al,59 ; Compare Al and 59 53 = "Y"
jnz #SSBL ; Jump to label SSBL if not equal
lodsb ; Read data from DS:SI pointer address to AL
cmp al,42 ; Compare Al and 42 53 = "B"
jnz #SSBL ; Jump to label SSBL if not equal
lodsb ; Read data from DS:SI pointer address to AL
cmp al,43 ; Compare Al and 43 53 = "C"
jnz #SSBL ; Jump to label SSBL if not equal
lodsb ; Read data from DS:SI pointer address to AL
cmp al,53 ; Compare Al and 53 53 = "S"
jnz #SSBL ; Jump to label SSBL if not equal
lodsb ; Read data from DS:SI pointer address to AL
cmp al,3d ; Compare Al and 3d 53 = "="
jnz #SSBL ; Jump to label SSBL if not equal
jmp #hqzb ; Jump unconditionally to label hqzb If the above conditions are met, get output coordinates
#TOchoice
JMP #choice ; Jump unconditionally to label choice Conditional addressing is short addressing, can't reach choice, can only use JMP to transfer
;Processing after encountering semicolon
#wz
lodsb ; Read data from DS:SI pointer address to AL
cmp al,3a ; Compare Al and 3a 3a = ":"
jz #hqzb ; Jump to label hqzb if equal For :, read new coordinates
cmp al,0d ; Compare Al and 0d OD = end character
jz #quit ; Jump to label quit if equal For end character, end
cmp al,00 ; Compare Al and 0 3a = empty
jz #quit ; Jump to label quit if equal For end character, end
sub si,01 ; Set SI minus 1
jmp #xhn ; Jump unconditionally to label XHN Others, line feed and continue
;Read coordinate information, store in di
#hqzb
lodsb ; Read data from DS:SI pointer address to AL Skip one character
; Some content will be added here in the future
call #DQ2SJ ; Call subroutine DQ2SJ Read 2 data
call #ZH10JZ ; Call subroutine ZH10JZ Convert to decimal
cmp al,18 ; Compare Al and 18 AL is the just obtained row number
jg #quit ; Jump to label QUIT if greater than If the row number exceeds 24, end
mov dh,al ; Set DH = AL Save row number to DH
call #DQ2SJ ; Call subroutine DQ2SJ Read 2 data
call #ZH10JZ ; Call subroutine ZH10JZ Convert to decimal
cmp al,4f ; Compare Al and 4f AL is the just obtained column number
jg #quit ; Jump to label QUIT if greater than If the row number exceeds 80, end
mov dl,al ; Set DL = AL Save column number to DL
;Convert row and column coordinates from DH and DL to memory address and save to DI
#ZBZH
mov al,02 ;
mul dl ;
push ax ;
mov al,a0 ;
mul dh ;
pop di ;
add di,ax ;
push di ;
;Read color information
#dcx
lodsb ; Read data from DS:SI pointer address to AL
cmp al,24
jz #color ; For $, skip and read again
call #DQ2SJ0 ; If not $, read normally
call #dc0
mov cl,dl
jmp #dwz
#color
call #dc
mov cl,dl
jmp #dwz
;Choice function
#choice
mov al,0
int 16
mov al,ah
;Quit
#quit
mov ah,4c
int 21
;Line feed and continue from original starting point
#xhn
pop di
add di,a0
push di
;Locate character output position
#dwz
push ax
mov ax,b800
push ax
pop es
pop dx
sub bp,si
mov dl,cl
;Write data
#xr
lodsb ; Read data from DS:SI pointer address to AL
cmp al,24
jz #color ; For $, read new color information
cmp al,3b
jz #wz ; For ;, end, execute from the beginning again
cmp al,0d
jz #quit ; For end character, end
cmp al,0
jz #quit ; For end character, end
cmp al,23
jnz #xr2 ; For #, then
adc di,1
jmp #xr3
#xr2
stosb ; Write one data
#xr3
mov al,dl
stosb ; Write color information
jmp #xr
;Read 2 bytes of character content, convert to color information
#dc
call #DQ2SJ
#dc0
xchg ax,bx
cmp al,39
jle #dc1
add al,9
#dc1
cmp bl,39
jle #dc2
add bl,9
#dc2
and al,0f
and bl,0f
mov dl,10
mul dl
add al,bl
mov dl,al
ret
;Read 2 bytes of content
#DQ2SJ
lodsb ; Read data from DS:SI pointer address to AL
#DQ2SJ0
cmp al,20
jz #DQ2SJ
cmp al,0d
jz #quit ; For end character, end
cmp al,0
jz #quit ; For end character, end
mov bl,al
#DQ2SJ1
lodsb ; Read data from DS:SI pointer address to AL
cmp al,20
jz #DQ2SJ
cmp al,0d
jz #quit ; For end character, end
cmp al,0
jz #quit ; For end character, end
ret
;10进制 character to hexadecimal digit
#ZH10JZ
xchg ax,bx
sub al,30
sub bl,30
mov ah,0a
mul ah
add al,bl
ret