Wang Shuang assembly language second edition curriculum design 2

Keywords: Vmware Assembly Language REST Programming

Wang Shuang course design of assembly language 2

  • The most important thing to master a programming language is practice. Wang Shuang's teacher's Curriculum Design II, if you write 400 to 800 lines of code completely, and complete this curriculum design independently, you will be proficient in 16 bit assembly and master the essence of 8086 assembly. This course design is not convenient for debugging. It will take a little time to complete independently. You may think that assembly is out of date and there is no need to waste time to study it carefully. However, learning assembly language is a shortcut to understand the principle of computer, and assembly language is the foundation of all languages. If you only know high-level language, you can only design things for others. You can only use API to give functions. If you learn to assemble and learn to program again, you will feel "Tao" in your heart, long sword in your hand. There is a kind of world where you can wield your passion and desire. There is no limit to your imagination and conception because of any function of a certain language. After learning assembly, you will know how lovely C language is as a hello world. Complete the course design of Professor Wang Shuang. 2. You will not learn the concept of object-oriented, because in the process of typing hundreds of lines of messy code, you will feel that one thing you urgently need is "Object-Oriented". Completed the course design 2, for the concept of pointer, you will never be confused, the opposite will feel more cordial, because you and his father pointer are already good friends, and the pointer his mother intimate contact, advertising so far, thank teacher Wang Shuang again!

1, Design requirements:

  • Write a self bootable computer that does not need to run in an existing operating system environment
    After power on, the CPU automatically enters the FFF0:0 unit for execution, where there is a jump instruction. After the CPU executes the instruction, it turns to execute the hardware system detection and initialization program in BIOS.

      The initialization program will establish the interrupt vector supported by BIOS, that is, the entry address of the interrupt history provided by BIOS is registered in the interrupt vector table.
    

After the completion of hardware system detection and initialization, INT 19H is called to boot the operating system.
If it is set to start the operating system from floppy disk, INT 19H will mainly complete the following work:
(1) Control floppy drive 0, read the contents of sector 1 of 0 channel 0 side to 0:7C 00.
(2) Point CS:IP to 0:7C 00.
The 0-channel 0-side 1 sector of the floppy disk contains the operating system boot program. After INT 19H installs it at 0:7C 00, the CPU is set to execute the boot program from 0:7C 00, and the operating system is activated to control the computer.
If there is no floppy disk in No.0 floppy drive, or there is a floppy I/O error, INT 19H will mainly complete the following work;
(1) Read the contents of 0 channel, 0 plane and 1 sector of hard disk C to 0:7C 00;
(2) Point CS:IP to 0:7C 00.
The task of this course design is to write a program that can start the computer by itself without running in the existing operating system environment.
The functions of the program are as follows:
(1) List the function options and let the user select through the keyboard. The interface is as follows:
1) reset pc; restart the computer
2) Start system; boot the existing operating system
3) Clock; enter clock program
4) Srt clock; set time
(2) Restart the computer after the user enters "1". (Note: consider FFFF:0)
(3) Boot the existing operating system after the user enters "2". (Note: consider 0-channel, 0-plane and 1 sector of hard disk C)
(4) After the user enters "3", the program of dynamic reality current date and time is executed.
The actual format is as follows: year / month / day hour: minute: Second

1. Show main menu

2. Display and second refresh clock

3. Set clock, left and right arrows to adjust cursor, esc exit, enter to save

2, Implementation steps

1. Write boot area

	Write 512 bytes of boot program to the first sector of A disk. Most computers have no soft driver, which is implemented by vmware virtual machine.

Byte 511 ends with 0aa55h, which is the boot flag.

Write A disk boot area code
        mov ax,data
		mov es,ax
		mov bx,offset bootdata;es:bx Memory data.

		mov dl,0;0Soft zone
		mov dh,0;0Noodles(head)
		mov ch,0;Track number
		mov cl,1;Fan area code
		mov al,1;Sector size
		mov ah,3;Write Sector
		int 13h      
;====================================================================

The boot sector is the sector 1 of 0-lane-0 side of the disk, which is 512 words and ends with 0aa55h. The above ones can't be exactly 510 bytes, so write the memory area with the size of 512 words and end with 0aa55h first.

data segment
bootdata db 510 dup(0)
         dw 0aa55h
data ends
;===========================
;......
;===========================
mov ax,cs
		mov ds,ax    ;ds:si Installation source
		mov si,offset boot

		mov ax,data
		mov es,ax
		mov di,offset bootdata


		mov cx,offset endboot-offset boot
		cld
		rep movsb

2. Boot on load

After power on, the CPU will automatically load the first sector of 0 plane 0 channel 0 of the guide disk to 7c00h of memory. After loading, cs:ip will point to 0:7c00h.

Code to write to sector 1 of 0-plane 0-channel

This code is also the generation that the boot is automatically loaded to 7c00h memory.

;=========================Below is A disc1Sector content=============================
boot:                 
		mov ax,0      
		mov es,ax     
		mov bx,7e00h;es:bx Memory data.        

		mov dl,0;0Soft zone
		mov dh,0;0Noodles(head)                  
		mov ch,0;Track number                     
		mov cl,2;Fan area code                     
		mov al,3;Sector size                   
		mov ah,2;Read sector                     
		int 13h       

		mov bx,offset s7e00-offset boot+7c00h                     
		jmp dword ptr cs:[bx]               
		s7e00 dw 7e00h,0                    
endboot:nop           
;====================================================================
	

3. Two functions of boot code
1. Load the remaining boot code on the disk into memory.

mov ax,0      
		mov es,ax     
		mov bx,7e00h;es:bx Memory data.        

		mov dl,0;0Soft zone
		mov dh,0;0Noodles(head)                  
		mov ch,0;Track number                     
		mov cl,2;Fan area code                     
		mov al,3;Sector size                   
		mov ah,2;Read sector                     
		int 13h       

2. Give control to the rest of the boot code

mov bx,offset s7e00-offset boot+7c00h                     
		jmp dword ptr cs:[bx]               
		s7e00 dw 7e00h,0      

3, Implementation of core code

1. Design a loop kernel

Because there are three interfaces according to the design requirements
1) Show menu
2) Display and refresh the clock interface
3) Clock setting interface
There are 5 functions in total: display menu, restart, boot from C disk again, display clock, set clock
In order to implement these five functions, a single byte digital sign is designed to mark
1) The scan code of display menu sign=1 ESC is 1, so set sign=1 when the scan code is 1 captured with int 9h
2) Restart sign=2, the scan code of number key 1 is 2, so set sign=2 when the scan code is 2 captured with int 9h
3) Boot sign=3 from disk C again as above
4) Display clock sign=4
5) Set clock sign=5
So the loop kernel only detects the value of sign. sign=1 will refresh the display menu all the time, restart when sign=2, start a new boot when sign=3, refresh the display clock all the time when sign=4, and set the clock when sign=5.
Cyclic code

color        db 4
functionlist dw offset endloopcore-offset do0+7e00h
			 dw offset showmenu   -offset do0+7e00h
			 dw offset reset      -offset do0+7e00h
			 dw offset startsys   -offset do0+7e00h
			 dw offset showclock  -offset do0+7e00h
			 dw offset setclock	  -offset do0+7e00h
sign         db 5      ;Set as0Exit from time to time.1,Display menu,4,Time display clock 5,set clock
;These lines of programs are looping all the time, equivalent to microkernel================================
;sign=1The menu is displayed,    
;sign=2Time call reset     
;sign=3Call the first sector of the hard disk                    
;sign=4Time display clock      
;sign=5Time setting clock      
;These lines of programs are looping all the time, equivalent to microkernel================================
loopcore:              
        mov bx,offset sign        -offset sysboot+7e00h            
		mov bl,cs:[bx];  Take out the numerical value of menu selection
		mov bh,0       
		               
		cmp bl,dl ; Check whether the selection key changes       
		je loopcore1   
		call clear     
		               
		loopcore1:     
		mov dl,bl; Staging for next comparison          
		mov di,offset functionlist-offset sysboot+7e00h            
		add bl,bl ;functionlist The address of each function is 2 Byte.          
		add di,bx      
		call word ptr cs:[di]                
		jmp loopcore   
ret                    
;=======================These lines of programs are looping all the time, equivalent to microkernel=================

2. Keyboard capture

There are three states to capture
1) When sgin=1, it is the menu status, and the number 1, 2, 3 and 4 keys are captured.
For example, when you press key 1, the scan code is 2, that is, when you capture the scan code is 2, set sgin=2. The keyboard capture module only sets the value of sign, and does not call other functions. If you call complex functions, int 9 will make unexpected errors. When the value of sign changes, loopcore calls the corresponding function.
2) When sgin=4, it is the clock display state. Only esc key is captured and sgin=1 is set
3) When sgin=5, 1. To capture the number 0 to 9, set the clock. 2. Left and right arrow keys to adjust the cursor position. 3. The ese key exits. 4. Enter saves the clock.
Keyboard capture code

color        db 4
sign         db 5      ;Set as0Exit from time to time.1,Display menu,4,Time display clock 5,set clock
keycheck:
		push ax
		push bx
		push dx
		push di
		
		
		mov bx, offset sign-offset do0+7e00h
		mov ah,cs:[bx]
		
		cmp al,3bh; F1 Color change
		jne keyF2
			mov bx, offset color-offset do0+7e00h
			inc byte ptr cs:[bx]
			jmp quitkeycheck
			
			
		
		keyF2: 
		cmp al,3ch ; meet F2 Time setting sign=0,Exit the loop.
		jne keymenu
			mov byte ptr cs:[bx],0;  endloopcore
			jmp quitkeycheck
		
			
		;================================================================	
		;1,Receive scan code only in three states 1,sign=1 Menu status 2,sign =4 display clock 3, sign=5 Time setting clock
		;
		;In the menu state, if you press no1,2,3,4Jump to the end.		
		keymenu:
		mov ah,cs:[bx]
		cmp ah,1
		jne keyshowclock
			cmp al,2
			jb quitkeycheck
			cmp al,5
			ja quitkeycheck
			
			mov cs:[bx],al
			
		jmp	quitkeycheck 
		;===============================================================
		;Only detect when the clock is displayed esc
		keyshowclock: 
		cmp ah,4
		jne keysetclock
		cmp al,1
		jne quitkeycheck
			
			
			mov cs:[bx],al
			
		jmp	quitkeycheck
		;===============================================================
		
		
		;===============================================================
		;When setting the clock:
		;1,Test four buttons, left arrow, right arrow ess,enter
		;2,Testing1,2,3,4,5,6,7,8,9,0
		; 4Menu key detection completed, jump to the end.
		keysetclock:
		cmp ah,5
		jne quitkeycheck
			cmp al,2
			jb keyleft
			cmp al,0bh
			ja keyleft
			
			call settime
		
			keyleft:
			cmp al,4bh
			jne keyright
			
				call setfocus
			
			keyright:
			cmp al,4dh
			jne keyesc			
			
				call setfocus
			
			keyesc:
			cmp al,1
			jne keyenter
			
				mov cs:[bx],al
			
			keyenter:
			cmp al,1ch
			jne quitkeycheck
			
				call saveclock
		
		;=================================================================
		quitkeycheck:
		pop di
		pop dx
		pop bx
		pop ax
ret

3. Clock settings

timestr 	 db '00/00/00 00:00:00',0
timedata     db 6 dup (0)
timelimitb   db  0, 1, 1, 0, 0,0
timelimita   db 99h,12h,31h,23h,60h,60h

Timedata is a 6-byte memory used to save time data. Instead of putting the clock data directly into timestr, it uses the maximum allowable value of time data, timelimit a, and the minimum allowable value, timelimit B, to check whether it is the allowable value of time setting. If the time data that meets the requirements is put into timedata, you will see that the number is displayed. If the time data that does not meet the requirements is not put into timedata Will not be displayed or saved.
Time setting code

timedata     db 6 dup (0)
timeaddr     db 9,8,7,4,2,0
timestr 	 db '00/00/00 00:00:00',0
timelimitb   db  0, 1, 1, 0, 0,0
timelimita   db 99h,12h,31h,23h,60h,60h
focusplaces	 db 0,1,3,4,6,7,9,10,12,13,15,16
focus        db 3
settime:
		push si
		push di
		push ax
		push bx
		push cx
		push dx
		push bp
		
		call scantodigit
			
		mov bp,offset timedata  -offset do0 +7e00h
		
		
		mov bx,offset focus     - offset do0+7e00h
		;[focusplaces]= 0,1,3,4,6,7,9,10,12,13,15,16
		mov bx,cs:[bx]    ;Fetch cursor index value	
		
		mov dx,bx
		and dx,1b ;If focus When singular, take out timedata[focus/2],Replace with typed value timedata[focus/2+1]
		
		shr bx,1
		
		add bp,bx
		
		cmp dl,0
		jne getts1			
			;If focus When double, type a value to replace timedata[focus/2],take out timedata[focus/2+1]
			mov dh,cs:[bp]
			shl al,1
			shl al,1
			shl al,1
			shl al,1
			and dh,1111b
			add al,dh
			jmp gett2
			
		getts1:
			;If focus When singular, take timedata[focus/2],Replace with typed value timedata[focus/2+1]
			mov dh,cs:[bp]
			and dh,11110000b
			add al,dh			
		gett2:
			
			mov di,offset timelimitb-offset do0 +7e00h
			mov si,offset timelimita-offset do0 +7e00h
						
			mov dl,cs:[di+bx]
			mov dh,cs:[si+bx]
			
			cmp al,dl
			jb quitgettime
			cmp al,dh
			ja quitgettime
			;call bcdtochar
			mov cs:[bp],al			
			
		quitgettime:
		pop bp
		pop dx
		pop cx
		pop bx
		pop ax
		pop di
		pop si
ret

4, Operating environment

Operating system: windows10
Debugging environment: DOSBox 0.74-3
Last operating environment: VMware Workstation Pro15
The complete course design 2 writes data to the floppy disk boot area. If you do not need any tools, you can write data to the floppy disk by running it once under Dos, and then boot the floppy disk drive.
You can see the demonstration effect by running it directly in VMWare DOS. You can see the real boot interface when you reboot.

Operation steps:

1. In the DOS environment of VMWare, compile connection runs.
2. Set the floppy drive boot.
3. Restart to see the boot interface

VMWare settings

1. Edit virtual machine in shutdown state

2. Add floppy

3. Setting up floppy drive boot


5, Debugging of course design 2

1. Debugging of single module

   Because the second course is boot code, which leads code data from disk to disk, and a keyboard interrupt code, it is very inconvenient to debug.

You can debug the function of a single module on line 55.

2. Demonstration effect debugging

  • In order to achieve the demonstration effect, when debugging, you can first write the import code to sectors 0, 0 and 1 of disk A, and the rest of the boot code to sectors 2, 3 and 4. Then write the code to simulate int 19h, read the boot code from the boot sector to memory 7c00h, and then point cs:ip to 0:7c00h. If the following code works normally, you can boot normally.

    Demo code

     copyToDiskAsector:
		mov ax,cs
		mov ds,ax    ;ds:si Installation source
		mov si,offset boot

		mov ax,data
		mov es,ax
		mov di,offset bootdata


		mov cx,offset endboot-offset boot
		cld
		rep movsb
		

		mov ax,data
		mov es,ax
		mov bx,offset bootdata;es:bx Memory data.

		mov dl,0;0Soft zone
		mov dh,0;0Noodles(head)
		mov ch,0;Track number
		mov cl,1;Fan area code
		mov al,1;Sector size
		mov ah,3;Write Sector
		int 13h

		mov ax,cs
		mov es,ax
		mov bx,offset sysboot;es:bx Memory data.

		mov dl,0;0Soft zone
		mov dh,0;0Noodles(head)
		mov ch,0;Track number
		mov cl,2;Fan area code
		mov al,3;Sector size
		mov ah,3;Write Sector
		int 13h
		
		mov ax,0
		mov es,ax
		mov bx,7c00h;es:bx Memory data.

		mov dl,0;0Soft zone
		mov dh,0;0Noodles(head)
		mov ch,0;Track number
		mov cl,1;Fan area code
		mov al,1;Sector size
		mov ah,2;Read sector
		int 13h

		mov bx,offset s7c00h
		jmp dword ptr ds:[bx]
		s7c00h dw 7c00h,0
		
		mov ah,4ch
		int 21h
copyToDiskAsectorEnd:nop

6, About offset addresses

1. All offset label s of the code segment are based on the current CS, that is, the segment is the current CS, and the offset value of the code segment is 0.
2. The difference between jmp label and jmp word ptr [offset label]: suppose that the address represented by the label is A, the former directly jumps to the label to execute the code, and the execution result is IP=A, the latter takes out the address B of double bytes stored in A, and then jumps to B, and the execution effect is IP=B. So is call.

mov bx,offset address -offset boot
jmp dword ptr cs:[bx]
call dword ptr cs:[bx]
address:
dw 2000h,0
;cs:[offset address -offset boot]It can accurately locate address,Not afraid to copy back and forth.
;jmp or call You can jump to0: 2000h

7, Complete code

assume cs:code,ds:data
data segment
bootdata db 510 dup(0)
         dw 0aa55h
data ends
code segment




;=======================Below is A disc2to4Sector content===========================
             
    ;offset sysbootend-offset sysboot The content between is copied to A disc2-4The contents of the sector.
                 
;=======================Below is A disc2to4Sector content===========================

sysboot:
jmp  near ptr dostart
oldint9addr  dw 0,0
;If not offset Error in offset address
menudata     dw  offset md0-offset sysboot+7e00h
			 dw  offset md1-offset sysboot+7e00h
   			 dw  offset md2-offset sysboot+7e00h
			 dw  offset md3-offset sysboot+7e00h
			 dw  offset md4-offset sysboot+7e00h
			 dw  offset md5-offset sysboot+7e00h
md0 		 db '------ welcome ------',0
md1 		 db '1) reset pc',0
md2 		 db '2) start system',0
md3 		 db '3) clock',0
md4 		 db '4) set clock',0
md5 		 db 'copyright @ 2020 LiuJianKun,Inc.All rights reserved.',0
timedata     db 20h,2h,18h,17h,51h,0h
timeaddr     db 9,8,7,4,2,0
timestr 	 db '00/00/00 00:00:00',0
timelimitb   db  0, 1, 1, 0, 0,0
timelimita   db 99h,12h,31h,23h,60h,60h
focusplaces	 db 0,1,3,4,6,7,9,10,12,13,15,16
focus        db 0
color        db 4
functionlist dw offset endloopcore-offset sysboot+7e00h
			 dw offset showmenu   -offset sysboot+7e00h
			 dw offset reset      -offset sysboot+7e00h
			 dw offset startsys   -offset sysboot+7e00h
			 dw offset showclock  -offset sysboot+7e00h
			 dw offset setclock	  -offset sysboot+7e00h
sign         db 5      ;Set as0Exit from time to time.1,Display menu,4,Time display clock 5,set clock
stack		 db 128 dup (0)
		
dostart:
mov ax,cs;cs=0
mov ds,ax
mov ss,ax
add ax,offset dostart-offset sysboot+7e00h
mov sp,ax

call setint9    ;Capture keyboard, settings9No. interrupt.
jmp loopcore    ;Cycle through the menu.
;call saveclock ;Debug save clock
;call showclock ;Debug display clock

;================Debug clock settings================
;mov al,0ah
;call settime
;call showtimedata
;================Debug clock settings================

mov ax,4c00h
int 21h
;ret
;These lines of programs are looping all the time, equivalent to microkernel================================
;sign=1The menu is displayed,    
;sign=2Time call reset     
;sign=3Call the first sector of the hard disk                    
;sign=4Time display clock      
;sign=5Time setting clock      
;These lines of programs are looping all the time, equivalent to microkernel================================
loopcore:              
        mov bx,offset sign        -offset sysboot+7e00h            
		mov bl,cs:[bx];  Take out the numerical value of menu selection
		mov bh,0       
		               
		cmp bl,dl ; Check whether the selection key changes       
		je loopcore1   
		call clear     
		               
		loopcore1:     
		mov dl,bl; Staging for next comparison          
		mov di,offset functionlist-offset sysboot+7e00h            
		add bl,bl ;functionlist The address of each function is 2 Byte.          
		add di,bx      
		call word ptr cs:[di]                
		jmp loopcore   
ret                    
;=======================These lines of programs are looping all the time, equivalent to microkernel=================




;sign=2
reset:
		push bx
		mov bx,offset rebootdata-offset sysboot+7c00h
		jmp dword ptr cs:[bx]
		rebootdata   dw 0,0ffffh
		pop bx
ret

;sign=3
startsys:
		mov ax,0
		mov es,ax
		mov bx,7c00h;es:bx Memory data.

		mov dl,80h;Hard diskC
		mov dh,0;0Noodles(head)
		mov ch,0;Track number
		mov cl,1;Fan area code
		mov al,1;Sector size
		mov ah,2;Read sector
		int 13h

		mov bx,offset startsys7c00h-offset sysboot+7e00h
		jmp dword ptr cs:[bx]
		startsys7c00h dw 7c00h,0
ret

;sign=4
showclock:
		call gettimedata
		call showtimedata
ret

;sign=5
setclock:		
		call showtimedata
ret

gettimedata:
		push si
		push di
		push ax		
			mov si,offset timeaddr  - offset sysboot+7e00h
			mov di,offset timedata  - offset sysboot+7e00h		
			mov cx,6
			gettimedatas0:
				mov al,cs:[si]
				out 70h,al
				in  al,71h
				mov cs:[di],al
				inc si
				inc di
			loop gettimedatas0
		pop ax
		pop di
		pop si
ret

showtimestr:
		push si
		push bx
			mov si,offset timestr  - offset sysboot+7e00h
			mov bl,32;column
			mov bh,13;That's ok		
			call showstr
		pop si
		pop bx
ret

setfocus:
		push ax
		push bx
		push dx
		push si
		push di		
			mov si,offset focus    - offset sysboot+7e00h
			mov bl,cs:[si]
			cmp al,4bh
			jne rightfocus
				cmp bl,0
				jne focusdec
					mov bl,11
					jmp showfocus
				
				focusdec:
					dec bl
					jmp showfocus
			
			
			rightfocus:
			cmp al,4dh
			jne showfocus
			cmp bl,11
				jne focusinc
					mov bl,0
					jmp showfocus
					
				focusinc:
					inc bl
					jmp showfocus
				
				
			showfocus:
			mov cs:[si],bl;Save cursor index value after move		
			mov di,offset focusplaces - offset sysboot+7e00h
			mov bh,0
			mov dl,cs:[di+bx];Take out the actual position of the cursor
			
			mov ah,2
			mov bh,0
			mov dh,13;That's ok
			add dl,32;column
			
			int 10h
		;setfocusquit:
		pop di
		pop si
		pop dx
		pop bx
		pop ax
		
ret

settime:
		push si
		push di
		push ax
		push bx
		push cx
		push dx
		push bp
		
		call scantodigit
			
		mov bp,offset timedata  -offset sysboot +7e00h
		
		
		mov bx,offset focus     - offset sysboot+7e00h
		mov bl,cs:[bx]    ;Fetch cursor index value
		mov bh,0
		
		mov dx,bx
		and dx,1b ;If focus When singular, take out timedata[focus/2],Corresponding with the entered value timedata[focus/2+1]
				  
		shr bx,1
		
		add bp,bx
		
		cmp dl,0
		jne getts1			
			;If focus When it is a double number, type the value corresponding to timedata[focus/2],take out timedata[focus/2+1]
			mov dh,cs:[bp]
			shl al,1
			shl al,1
			shl al,1
			shl al,1
			and dh,1111b
			or al,dh
			jmp gett2
			
		getts1:
			;If focus If it is singular, take timedata[focus/2],Corresponding with the entered value timedata[focus/2+1]
			mov dh,cs:[bp]
			and dh,11110000b
			or al,dh			
		gett2:
			
			mov di,offset timelimitb-offset sysboot +7e00h 
			mov si,offset timelimita-offset sysboot +7e00h 
						
			mov dl,cs:[di+bx];Minimum allowable value of clock
			mov dh,cs:[si+bx];Maximum allowed value of clock
							 ;use timedata[focus/2][focus/2+1] Compare with the maximum allowable value and the minimum allowable value of clock
							 ;Determine whether the clock you type is the most available, if available
							 ;Then put timedata[focus/2][focus/2+1]Fill timedata
			cmp al,dl
			jb quitgettime
			cmp al,dh
			ja quitgettime
			;call bcdtochar
			mov cs:[bp],al			
		quitgettime:
		pop bp
		pop dx
		pop cx
		pop bx
		pop ax
		pop di
		pop si
ret

showtimedata:
		push si
		push di
		push ax
		push bx
		push cx		
			mov si,offset timedata  - offset sysboot+7e00h
			mov di,offset timestr   - offset sysboot+7e00h		
			mov cx,6
			showclocks0:		   
			   mov al,cs:[si]
				call bcdtochar
				
				mov cs:[di+0],ah
				mov cs:[di+1],al
				add di,3
				inc si
			loop showclocks0
			mov si,offset timestr  - offset sysboot+7e00h
			mov bl,32;column
			mov bh,13;That's ok
			call showstr
			showclockquit:
		pop cx
		pop bx
		pop ax
		pop di
		pop si
ret

newint9:
		push ax
		push bx
		push es		
			in al,60h
			
			mov bx,0
			mov es,bx
			pushf
			mov bx,offset oldint9addr-offset sysboot+7e00h
			call dword ptr es:[bx]
			call keycapture		
		pop es
		pop bx
		pop ax		
iret

setint9:
		push di
		push ax
		push es
		push ds		
			mov ax,0
			mov es,ax
			
			mov bx,offset oldint9addr-offset sysboot+7e00h
			push es:[9*4]
			pop es:[bx]
			push es:[9*4+2]
			pop  es:[bx+2]
			
			cli
			mov word ptr es:[9*4],offset newint9-offset sysboot+7e00h
			mov word ptr es:[9*4+2],0
			sti
		
		pop ds
		pop es
		pop ax
		pop di

ret
;stay bh That's ok, bl Column, show si At the beginning0Ending character
showstr:;9E
		push es
		push ax
		push di
		push cx
		push bx
		push bp		
			mov ax,0b800h
			mov es,ax
			
			mov al,160;Per row display80Characters, two bytes of memory is required to display a word1Each character1Bytes, color1word
			mul bh   ;dh Row number
			
			mov cx,bx;Preservation bx
			mov bh,0 ;Total column data saved ax
			
			add ax,bx;Calculate the number of columns, if usingadd al,bl Overflow error
			add ax,bx;Count columns, characters1Bytes, color1Byte, so add twice
			
			mov di,ax;Destination address
			mov bx,cx;recovery bx
			mov bp,offset color-offset sysboot+7e00h
			mov ah,cs:[bp];High byte storage color
			mov ch,0
			showstr1:
			  mov al,cs:[si];Low byte is data
			  mov es:[di],ax;High byte is color
			  
			  inc si   
			  add di,2
			  mov cl,al
			  jcxz showstr2
			jmp showstr1
showstr2:  ;D7
    pop bp
    pop bx
    pop cx
	pop di
	pop ax
	pop es
ret



clear:
		push bx
	    push dx
	    push cx
		push es		 
			mov bx,0b800h
			mov es,bx
			mov bx,0
			mov ds,bx
			
			mov bx,0
			mov dx,0700h   ;The character property should be set to07h,Instead of0
			mov cx,2000
				clear1:
				mov es:[bx],dx
				add bx,2
				loop clear1
		pop es
		pop cx
		pop dx
		pop bx
		ret

endloopcore:
		mov bx,offset sysboot-offset oldint9addr
		push es:[bx]
		pop es:[9*4]
		push  es:[bx+2]
		pop es:[9*4+2]
		mov ah,4ch
		int 21h
ret

saveclock:
	push ax
	push si
	push di
	mov di,offset timedata  -offset sysboot +7e00h
	mov si,offset timeaddr  -offset sysboot +7e00h
	
	mov cx,6
	saveclocks:
		mov al,cs:[si]
		out 70h,al
		mov al,cs:[di]
		out 71h,al
		inc di
		inc si
	loop saveclocks
	
	pop di
	pop si
	pop ax
	
ret
scantodigit:
		mov ah,al
		cmp al,0bh
		jne gettnum1 
			mov al,0
			jmp quitscantodigit
		gettnum1:
			cmp al,2
			jb quitscantodigit            			
			cmp al,0bh
			ja quitscantodigit
				dec al
		quitscantodigit:
ret



resetfocus:
		push ax
		push bx
		push dx
			mov ah,2
			mov bh,0
			mov dh,25
			mov dl,0
			int 10h
		pop dx
		pop bx
		pop ax
ret

;al yes bcd Code, return ah High character, al Low character
bcdtochar:
		push dx		
			mov dl,al			
			shr al,1
			shr al,1
			shr al,1
			shr al,1
			add al,30h
			mov ah,al
			mov al,dl
			and al,1111b
			add al,30h		
		pop dx
ret

setcolor:
		push ax
		push bx
			mov bx,offset color-offset sysboot+7e00h
			mov al,cs:[bx]
			inc al
			mov cs:[bx],al
		pop bx
		pop ax
ret
sysbootend:nop
;=======================Above is A disc2to4Sector content===========================
                    
    ;offset sysbootend-offset sysboot The content between is copied to A disc2-4The contents of the sector.           
               
;=======================Above is A disc2to4Sector content===========================



;==========================Below is A disc1Sector content===========================
                   
             ;boot:The first sector of the disk is loaded into7c00h                    
             ;The function of boot sector is to realize2,3,4,5Sector               
             ;Load into7e00h,And jump to7e00h.                    
                   
;=========================Below is A disc1Sector content=============================
boot:                 
		mov ax,0      
		mov es,ax     
		mov bx,7e00h;es:bx Memory data.        

		mov dl,0;0Soft zone
		mov dh,0;0Noodles(head)                  
		mov ch,0;Track number                     
		mov cl,2;Fan area code                     
		mov al,3;Sector size                   
		mov ah,2;Read sector                     
		int 13h       

		mov bx,offset s7e00-offset boot+7c00h                     
		jmp dword ptr cs:[bx]               
		s7e00 dw 7e00h,0                    
endboot:nop           
;====================================================================

testRun7e00h:

		mov ax,cs
		mov ds,ax
		
		mov si,offset sysboot
		mov ax,0h
		mov es,ax
		mov di,7e00h
		mov cx,offset sysbootend-offset sysboot
		cld
		rep movsb


		mov bx,offset s7e00h-offset sysboot
		jmp dword ptr cs:[bx]
		s7e00h dw 7e00h,0
		testRun7e00hEnd:nop
		
	ret


copyToDiskAsector:
		mov ax,cs
		mov ds,ax    ;ds:si Installation source
		mov si,offset boot

		mov ax,data
		mov es,ax
		mov di,offset bootdata


		mov cx,offset endboot-offset boot
		cld
		rep movsb
		

		mov ax,data
		mov es,ax
		mov bx,offset bootdata;es:bx Memory data.

		mov dl,0;0Soft zone
		mov dh,0;0Noodles(head)
		mov ch,0;Track number
		mov cl,1;Fan area code
		mov al,1;Sector size
		mov ah,3;Write Sector
		int 13h

		mov ax,cs
		mov es,ax
		mov bx,offset sysboot;es:bx Memory data.

		mov dl,0;0Soft zone
		mov dh,0;0Noodles(head)
		mov ch,0;Track number
		mov cl,2;Fan area code
		mov al,3;Sector size
		mov ah,3;Write Sector
		int 13h
		
		mov ax,0
		mov es,ax
		mov bx,7c00h;es:bx Memory data.

		mov dl,0;0Soft zone
		mov dh,0;0Noodles(head)
		mov ch,0;Track number
		mov cl,1;Fan area code
		mov al,1;Sector size
		mov ah,2;Read sector
		int 13h

		mov bx,offset s7c00h
		jmp dword ptr ds:[bx]
		s7c00h dw 7c00h,0
		
		mov ah,4ch
		int 21h
copyToDiskAsectorEnd:nop


start:
;call copyToDiskAsector
call testRun7e00h
code ends

end start
Published 7 original articles, praised 0, visited 1986
Private letter follow

Posted by Logical1 on Sun, 19 Jan 2020 22:13:48 -0800