www.pudn.com > czxtsycx1.zip > LOAD.ASM


CODE        SEGMENT PARA USE16         ;can't run alone 
            ASSUME CS:CODE 
            ORG 800H 
START:       
            .386P 
            ;MOV AX,0600H         ;clear screen 
            ;MOV BH,07H 
            ;MOV CX,0 
            ;MOV DX,184FH 
            ;INT 10H 
            MOV AX,1301H         ;M1 
            MOV DX,0A00H 
            MOV BX,7H 
            MOV BP,OFFSET M1 
            MOV SI,BP 
            MOV CL,[SI] 
            XOR CH,CH 
            INC BP 
            INT 10H 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAAAAAAA 
            ;load the file "GFAT16.EXE" to 1000:0  
            MOV  SI,7C00H          ;COS_BOOT sector moved to 70:0 
            MOV  DI,700H 
            MOV  CX,03EH 
            REPZ MOVSB 
 
            MOV  SI,700H 
            XOR AX,AX 
            CMP [SI+13H],AX 
            JZ  L1 
            MOV CX,[SI+13H] 
            MOV [SI+20H],CX 
L1:         MOV AL,[SI+10H] 
            MUL WORD PTR [SI+16H] 
            ADD AX,[SI+0EH] 
            ADC DX,+0 
            MOV WORD PTR DIR_FS+7,AX  ;7C50 save root dir 1st sector_no 
            MOV WORD PTR DIR_FS+9,DX  ;7C52 
            MOV WORD PTR DIR_FS,AX    ;7C49 
            MOV WORD PTR DIR_FS+2,DX  ;7C4B 
            MOV AX,20H 
            MUL WORD PTR [SI+11H]     ;dx:ax bytes of root_dir 
            MOV BX,[SI+0BH]           ;bx=bytes per sector 
            ADD AX,BX 
            DEC AX 
            DIV BX 
            ADD WORD PTR DIR_FS,AX   ;save file area 1st sector_no 
            ADC WORD PTR DIR_FS+2,+0 
            MOV DX,WORD PTR DIR_FS+9 ;7c52h 
            MOV AX,WORD PTR DIR_FS+7 ;7c50h   dx:ax  root dir 1st sector_no 
            CALL SECTOR_ADDR 
            JB  ERROR_IN 
            MOV AL,1 
            MOV BX,0500H             ;input buf----root 1st sector 
            CALL READ_SECTOR         ;gfat16.exe should be in 1st sector 
            JB  ERROR_IN 
            MOV BL,16 
            cld 
            MOV WORD PTR DIR_FS+13,SI 
            MOV DI,0500H 
L2:         MOV CX,000BH 
            MOV WORD PTR DIR_FS+15,DI 
            MOV SI,OFFSET FNAME0 
            REPZ CMPSB 
            JZ  READ_OK 
            DEC BL 
            JZ  ERROR_IN 
            MOV DI,WORD PTR DIR_FS+15 
            ADD DI,32 
            JMP L2 
             
READ_OK:    ;found GFAT16.EXE di point just after file_name 
            MOV SI,WORD PTR DIR_FS+13 
            MOV AX,DI 
            ADD AX,15 
            MOV DI,AX    
            MOV AX,[DI]         ;begin cluster_no 
            MOV WORD PTR DIR_FS+17,AX  ;cluster_no 
            MOV BX,0H 
            MOV WORD PTR DIR_FS+19,BX  ;offset of Input buf 
            ; read GFAT16.EXE--->1000H:0  
            ; in:DIR_FS+17=1st cluster_no 
            ;  & DIR_FS+19=offset of Input buf    
            ;from cluster -->logical sector_no 
CLUSTER_L:  MOV SI,700h 
            MOV AX,WORD PTR DIR_FS+17 
            CMP AX,0FFF8H 
            JAE READ_FILE_END 
            XOR DX,DX 
            SUB AX,2 
            MOV BL,BYTE PTR [SI+0DH] 
            XOR BH,BH 
            MUL BX 
            ADD AX,WORD PTR DIR_FS 
            ADC DX,+0         ;dx:ax logical sector_no 
            ; Read gfat16.exe 
READ_FILE:   
            ;MOV WORD PTR DIR_FS,AX 
            ;MOV WORD PTR DIR_FS+2,DX 
            CALL SECTOR_ADDR 
            JB  ERROR_IN 
            MOV AL,BYTE PTR [SI+0DH] 
            PUSH ES 
            MOV BX,1000H 
            MOV ES,BX 
            MOV BX,WORD PTR DIR_FS+19 
            CALL READ_SECTOR         ;cos.exe should be in 1st sector 
            JB  ERROR_IN0 
            JMP READ_FILE_NEXT 
ERROR_IN0:  POP ES 
            JMP ERROR_IN 
READ_FILE_NEXT: 
            POP ES 
            ;************find next cluster_start 
            PUSH EBX 
            PUSH ECX 
            PUSH EDX 
            MOV CX,WORD PTR DS:[SI+0BH]  ;bytes per setctor 
            MOVZX ECX,CX 
            MOV AX,WORD PTR DIR_FS+17    ;current cluster 
            MOVZX EAX,AX 
            MOV EBX,EAX 
            ADD EAX,EBX         ;eax=offset of the cluster_no  
            XOR EDX,EDX 
            DIV ECX             ;eax=sectors before the cluster_no  
            INC EAX             ;ADD boot now eax=logical sector_no 
NEXT_CLUSTER1:                  ;EAX=sector_no of the cluster 
             ;;;;;;; 
            PUSH DX            ;remains = offset of cluster_no 
            ;read one_sector eax=logical sector_no 
            MOV EDX,EAX 
            SHR EDX,16 
            CALL SECTOR_ADDR 
            JB  ERROR_IN 
            MOV AL,1 
            MOV BX,OFFSET TTSECTOR 
            CALL READ_SECTOR         ;read fat 
            JB  ERROR_IN1 
            JMP READ_FILE_NEXT1 
ERROR_IN1:   
            JMP ERROR_IN 
READ_FILE_NEXT1: 
            ;read one_sector eax=logical sector_no 
            MOV BX,OFFSET TTSECTOR 
            POP DX      ;remains 
            ADD BX,DX 
            MOV AX,[BX]     ;next cluster 
            CLD 
            MOV WORD PTR DIR_FS+17,AX 
            POP EDX 
            POP ECX 
            POP EBX 
            ;************find next cluster_end 
            MOV AL,[SI+0DH] 
            MOV AH,0 
            MUL WORD PTR [SI+0BH] 
            CLD 
            ADD WORD PTR DIR_FS+19,AX 
            JMP CLUSTER_L 
READ_FILE_END: 
            MOV AX,1000H 
            MOV GS,AX 
            CALL G_EXEC_LOAD 
            CMP AX,1 
            JE ERROR_IN 
            ; 
            CLI 
            MOV AX,GS:0EH 
            MOV SS,AX 
            MOV AX,GS:11H 
            MOV SP,AX 
            STI 
            ;MOV BX,GS:16H 
            ;ADD BX,1000H 
            ;MOV SI,GS:14H 
 
DB 0EAH 
DW 0,1CDFH         ;for ok  1000+20+CBF=cos.exe 
 
jmp ttt 
 
ERROR_IN:   MOV BP,OFFSET ERROR1 
            CALL DO_ERROR 
;tt:         jmp tt           ;cut off comment 
TTT:                          ;cut off after test 
MOV ax,4c00h        ;for test 
int 21h 
 
T1:         JMP T1  ; ok 
mov ax,word ptr dir_fs+17 
CALL DISP_EXT_AX_dos 
mov ax,word ptr dir_fs+19 
CALL DISP_EXT_AX_dos 
 
READ_SECTOR PROC NEAR 
            ;in:es:bx input buf 
            ;ds:dir_fs   ds=0 
            MOV AH,2 
            MOV DX,WORD PTR DIR_FS+4 ;cylinder=7C4D 
            MOV CL,6 
            SHL DH,CL 
            OR  DH,DIR_FS+6          ;sector=7C4F 
            MOV CX,DX 
            XCHG CH,CL 
            MOV DL,[SI+24H] 
            MOV DH,[SI+25H]         ;head 
            INT 13H 
            RET 
READ_SECTOR ENDP 
 
SECTOR_ADDR PROC NEAR 
            ;in : dx:ax= logical sector_no 
            ADD AX,1 
            ADC DX,+0 
            ADD AX,[SI+1CH] 
            ADC DX,[SI+1EH]       ;DX:AX =A 
            PUSH AX 
            PUSH DX 
            MOV AX,[SI+1AH] 
            MUL WORD PTR [SI+18H] 
            MOV WORD PTR DIR_FS+11,AX 
            POP DX 
            POP AX 
            DIV WORD PTR DIR_FS+11 
            MOV WORD PTR DIR_FS+4,AX        ;Cylinder_no 
            XCHG AX,DX    
            XOR DX,DX 
            DIV WORD PTR [SI+18H] 
            MOV [SI+25H],AL        ;head_no 
            MOV DIR_FS+6,DL        ;Sector_no 7C4f 
            CLC 
            RET 
EEE:        STC 
            RET  
SECTOR_ADDR ENDP 
DO_ERROR    PROC NEAR 
            MOV AX,1301H         ;display M1 
            MOV DX,0A00H 
            MOV BX,7H 
            ;MOV BP,OFFSET ERROR1 
            MOV SI,BP 
            MOV CL,[SI] 
            XOR CH,CH 
            INC BP 
            INT 10H 
;DO_ERROR0:   JMP DO_ERROR0     ;OK after test 
            RET 
DO_ERROR    ENDP 
;;;;;;;;;;;AAAAAAAAA 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
G_EXEC_LOAD PROC FAR 
            ;in---- (ds)=system data segment 
            ;       (gs)=head+program(cos.exe)=1000H 
            ;       DS:G_WORK 100 DB PARA AREA 
            PUSH ES 
            MOV BX,GS:00H 
            CMP BX,5A4DH 
            JZ  G_EXEC0 
            MOV AX,1           ;Not DOS .exe  first 2 bytes is 4D5AH 
            JMP G_EXEC_END 
            ;*********************get program_size 
G_EXEC0:     
            ;                    set ldt_desc for CS OF USER PROCESS  -->START 
            MOV AX,GS:08H       ;SIZE_HEAD PARA 
            SHL AX,4            ;SIZE_HEAD BYTE 
            PUSH AX             ;SS:1=SIZE_HEAD BYTE INTO STACK 
            ;;;;;;;;;           ;GET FILE_SIZE 
            MOV BX,GS:02H       ;mod512 
            MOV AX,GS:04H       ;file_sectors 
            CMP BX,0 
            JZ  g_exec1 
            DEC AX 
g_exec1:    XOR DX,DX 
            MOV CX,512 
            MUL CX          
            ADD AX,BX       
            ADC DX,0            ;DX:AX  file_size 
            MOV DS:G_WORK,AL        
            MOV DS:G_WORK[1],AH       
            MOV DS:G_WORK[2],DL 
            MOV DS:G_WORK[3],DH ;0-3=FILE SIZE 
            POP BX              ;GET SIZE_HEAD  
            ;PUSH BX 
            MOVZX EBX,BX 
            MOV DWORD PTR DS:G_WORK[4],EBX   ;4-7=SIZE_HEAD  
            MOV CX,WORD PTR GS:6H            ;reposit_count  LOOP 
            MOV BX,WORD PTR GS:18H           ;position for re_position item 
g_exec_1:    
            MOV AX,WORD PTR GS:[BX] 
            ADD AX,WORD PTR DS:G_WORK[4]    ;OFFFSET 
            MOV DI,AX 
            MOV AX,WORD PTR GS:[BX+2] 
            ADD AX,1000H 
            MOV ES,AX 
 
            MOV AX,ES:[DI] 
            ADD AX,1000H 
            ADD AX,GS:08H 
            MOV ES:[DI],AX 
            ADD BX,4 
            LOOP g_exec_1 
G_EXEC_END1: 
            ;                  LOOP OTHER SEGMENT-----END 
            ;POP DX 
            ;*********************A  -->end   deal with loading .exe 
G_EXEC_END:  
            POP ES 
            RET 
G_EXEC_LOAD ENDP 
 
;call DISP_EXT_AX_dos 
;jmp G_EXEC_END1 
 
M1          DB 17,'Start NUAA 3G-COS' 
FNAME0      DB 'COS     EXE' 
ERROR1      DB 15H,'Non-System disk error' 
ERROR2      DB 10H,'Error loading OS'   
DIR_FS      DB 21 DUP(0) 
G_WORK      DB 100 DUP(0) 
TTSECTOR    DB 512 DUP(?) 
t_string    DB 100 DUP(0) 
G_END: 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
;;xxxxxxxxxxxxxx next for test 
DISP2_16_dos    PROC FAR 
            ;in al code 2 using ah 
            ;out ah:al:code 16 
            mov ah,al 
            MOV CL,4 
            shr ah,CL 
            cmp ah,9 
            jle disp2_16_1_dos 
            add ah,7     
disp2_16_1_dos: add ah,30h 
            and al,0fh 
            cmp al,9 
            jle disp2_16_2_dos 
            add al,7 
disp2_16_2_dos: add al,30h 
            RET 
DISP2_16_dos    ENDP 
 
DISP_EXT_AX_dos PROC FAR 
            ;in cx:position 
            PUSH AX 
            PUSH BX 
            PUSH CX 
            PUSH DX 
 
            MOV BX,AX 
            mov al,BH 
            CALL DISP2_16_dos 
            mov DS:t_string,ah 
            mov DS:t_string[1],al 
            MOV AL,BL 
            CALL DISP2_16_dos 
            mov DS:t_string[2],ah 
            mov DS:t_string[3],al 
            mov DS:t_string[4],' ' 
            mov DS:t_string[5],'$' 
            MOV AH,9 
            MOV DX,OFFSET t_string 
            ;add dx,16 
            INT 21H 
            POP DX 
            POP CX 
            POP BX 
            POP AX 
            RET 
DISP_EXT_AX_dos     ENDP 
;;xxxxxxxxxxxxxx next for test 
 
START_TEST: 
            CLI 
            MOV  AX,SEG CODE 
            MOV  SS,AX 
            MOV  AX,OFFSET STACK0 
            ADD  AX,1024 
            MOV  SP,AX 
            MOV  AX,SEG CODE 
            MOV  ES,AX 
            MOV  DS,AX 
            CLD 
 
            ;;;;;;;;;;;;;;;;;;;;; save to C:\TC\G\LOAD.3G 
            MOV DX,OFFSET FNAME 
            MOV CX,0 
            MOV AH,3CH     ;CREAT FILE 
            INT 21H 
            MOV AL,01H     ;FOR WRITE 
            MOV AH,3DH     ;OPEN FILE 
            INT 21H 
            MOV BX,AX      ;BX=FILE HANDLE 
            MOV DX,OFFSET START 
            MOV CX,start_test ; OFFSET G_END   ;for test     1/1 
            SUB CX,DX 
            MOV AH,40H     ;WRITE FILE 
            INT 21H 
            MOV AH,3EH     ;CLOSE FILE 
            INT 21H 
 
            MOV AX,4C00H 
            INT 21H 
 
FNAME       DB 'C:\TC\G\LOAD.3G',0 
STACK0      DB 1024 DUP(?) 
CODE        ENDS 
END START_TEST