The IBM Personal Computer MACRO Assembler 10-15-86 PAGE 1-1 RHBOOT -- BOOTSTRAP LOAD PROGRAM ; page 86,131 title RHBOOT -- BOOTSTRAP LOAD PROGRAM ;* ------------------------------------------------------------------- ;* RHBOOT.COM is a sample Remote Program Load program. ;* ;* (C) Copyright IBM Corp., 1986 ;* This program is the property of IBM. All rights reserved. ;* ;* RHBOOT.COM is exactly 512. The last 6 bytes contain ;* a diskette header initialized to the default values ;* for a single sided 8 sector per track 160K diskette. ;* Refer to the IBM Token-Ring Remote Program Load User's ;* Guide for more details on the diskette header. ;* ;* RHBOOT.COM is designed to have a DOS system diskette image ;* appended to it. Refer to documentation on GEMIMAG.COM ;* for instructions on how to create this image. ;* ;* RHBOOT.COM computes the diskette image size from the ;* data in the header; reduces memory size for DOS ;* the amount of space required for the diskette image ;* and header; moves the diskette image and header to ;* high memory; initializes the pointer to the diskette ;* image header for the disk drive emulator; issues a ;* DIR.CLOSE.ADAPTER command; and transfers control ;* through XFER.ADDR to force a reboot from the ;* relocated system diskette image. ;* ;* ;* -------------------------------------------------------------------  The IBM Personal Computer MACRO Assembler 10-15-86 PAGE 1-2 RHBOOT -- BOOTSTRAP LOAD PROGRAM page ; ;********************************************************************** ; EQUATES ;********************************************************************** = 0006 HDR_SIZE equ 6 = 0012 MEM_SIZE equ 12h = 0120 DISK_ADDR equ 0120h = 0413 DOS_MEM equ 0413h = 068C XFER_ADDR equ 068ch  The IBM Personal Computer MACRO Assembler 10-15-86 PAGE 1-3 RHBOOT -- BOOTSTRAP LOAD PROGRAM page 0000 code segment public public rhboot 0000 rhboot proc far assume cs:code,ds:code ; 0000 start: 0000 E8 0003 R call setds ; GET INSTRUCTION POINTER 0003 setds: 0003 5E pop si ; SI = INSTRUCTION POINTER 0004 8B C6 mov ax,si ; AX = INSTRUCTION POINTER 0006 D1 E8 shr ax,1 ; AX = IP / 02 0008 D1 E8 shr ax,1 ; AX = IP / 04 000A D1 E8 shr ax,1 ; AX = IP / 08 000C D1 E8 shr ax,1 ; AX = IP / 16 000E 8C CF mov di,cs ; DI = CODE SEGMENT 0010 03 F8 add di,ax ; DI = NORMALIZED SEGMENT 0012 81 E6 000F and si,0fh ; DI:SI = NORMALIZED HEADER @ ; SI = DISKETTE HEADER OFFSET 0016 81 C6 01F7 add si,offset header-setds 001A 8E DF mov ds,di ; DS:SI = DISKETTE IMAGE HEADER @ ; ;********************************************************************** ; CALCULATE SIZE OF DISKETTE IMAGE IN BYTES * ;********************************************************************** 001C A0 01FA R mov al,heads ; AL = NUMBER OF HEADS 001F F6 26 01FC R mul sectors ; AX = HEADS * SECTORS 0023 F6 26 01FB R mul tracks ; AX = HEADS * SECTORS * TRKS 0027 F7 26 01FD R mul sec_size ; DX:AX = DISK IMAGE SIZE w/o header 002B 05 0006 add ax,HDR_SIZE ; DX:AX = DISK IMAGE SIZE w/ header 002E 83 D2 00 adc dx,0 ; ADJUST FOR THE CARRY FLAG 0031 8B D8 mov bx,ax ; BX = SEGMENT SIZE 0033 8B EA mov bp,dx ; BP:BX = SIZE OF DISK IMAGE 0035 B9 0010 mov cx,16 ; CX = DIVISOR 0038 F7 F1 div cx ; AX = SEGMENT; DX = OFFSET 003A 03 C7 add ax,di ; AX = LAST DATA SEGMENT 003C 03 F2 add si,dx ; SI = LAST DATA OFFSET 003E 73 03 jnc rhboot01 ; CF = 1 ==> OVERFLOW 0040 80 C4 10 add ah,16 ; ADJUST FOR NEXT 64K SEGMENT 0043 rhboot01: 0043 8E D8 mov ds,ax ; DS:DX = LAST @ OF DISK IMAGE ; ;********************************************************************** ; GET MEMORY SIZE IN K BYTES * ;********************************************************************** 0045 CD 12 int MEM_SIZE ; AX = # OF K BYTES OF MEMORY 0047 B9 0040 mov cx,1024/16 ; CONVERT AX TO A SEGMENT 004A F7 E1 mul cx ; AX = LAST VALID SEGMENT OF MEMORY 004C 8B FA mov di,dx ; AX:DI = DESTINATION @  The IBM Personal Computer MACRO Assembler 10-15-86 PAGE 1-4 RHBOOT -- BOOTSTRAP LOAD PROGRAM page ;********************************************************************** ; ADJUST SEGMENT REGISTERS * ;********************************************************************** 004E FD std ; DF = 1 ==> BACKWARD 004F 4E dec si ; DS:SI = SOURCE @ 0050 4F dec di ; ES:DI = DESTINATION @ 0051 rhboot02: 0051 B9 FFFF mov cx,0ffffh ; CX = COMPARE VALUE 0054 8B D0 mov dx,ax ; DX = CURRENT DEST SEGMENT VALUE 0056 3B F9 cmp di,cx ; DI = NEXT DESTINATION @ 0058 75 03 jnz rhboot03 ; DON'T ADJUST FOR NOW 005A 80 EC 10 sub ah,16 ; AX = PREVIOUS SEGMENT VALUE 005D rhboot03: 005D 8E C0 mov es,ax ; ES:DI = DESTINATION @ 005F 3B F1 cmp si,cx ; SI ON A BOUNDARY ?? 0061 75 07 jnz rhboot04 ; SI NOT ON A BOUNDARY 0063 8C D9 mov cx,ds ; CX = SOURCE SEGMENT 0065 80 ED 10 sub ch,16 ; ADJUST SOURCE SEGMENT 0068 8E D9 mov ds,cx ; DS:SI = SOURCE ADDRESS ; ;********************************************************************** ; CALCULATE THE MOVE SIZE * ;********************************************************************** 006A rhboot04: 006A 8B CF mov cx,di ; CX = DEFAULT MOVE SIZE 006C 3B CE cmp cx,si ; CHECK FOR SMALLER VALUE 006E 72 02 jc rhboot05 ; DI IS SMALLER THAN SI 0070 8B CE mov cx,si ; SI IS SMALLER THAN DI 0072 rhboot05: 0072 0B ED or bp,bp ; BP = OVERFLOW REGISTER 0074 75 09 jnz rhboot06 ; BP HAS A VALUE IN IT 0076 3B D9 cmp bx,cx ; BX = REMAINING MOVE SIZE 0078 77 05 ja rhboot06 ; MOVE COMPLETE IF SIZE EQUAL ZERO 007A 8B CB mov cx,bx ; CX = NEW MOVE SIZE 007C E3 0A jcxz rhboot07 ; NO MORE DATA TO MOVE 007E 49 dec cx ; CX = MOVE SIZE ; ;********************************************************************** ; NOW MOVE THE DATA * ;********************************************************************** 007F rhboot06: 007F 41 inc cx ; MOVE AT LEASE ONE BYTE 0080 2B D9 sub bx,cx ; BX = NEW MOVE SIZE 0082 F3/ A4 rep movsb ; MOVE BLOCK OF DISKETTE IMAGE 0084 1B E9 sbb bp,cx ; BP = OVERFLOW VALUE 0086 EB C9 jmp rhboot02 ; LOOP AGAIN  The IBM Personal Computer MACRO Assembler 10-15-86 PAGE 1-5 RHBOOT -- BOOTSTRAP LOAD PROGRAM page ;********************************************************************** ; ADJUST MEMORY SIZE AND EXIT * ;********************************************************************** 0088 rhboot07: 0088 47 inc di ; DX:DI = DISKETTE IMAGE @ 0089 8E D9 mov ds,cx ; DS = SEGMENT 0000 008B BE 0120 mov si,disk_addr ; ES:DI = DISKETTE IMAGE @ 008E 92 xchg ax,dx ; AX = DISKETTE IMAGE SEGMENT 008F 89 3C mov 0[si],di ; DISKETTE IMAGE OFFSET 0091 89 44 02 mov 2[si],ax ; DISKETTE IMAGE SEGMENT 0094 BB 0010 mov bx,16 ; BX = MULTIPLIER 0097 2B D2 sub dx,dx ; PREPARE FOR MULTIPLY 0099 F7 E3 mul bx ; DX:AX = SEGMENT * 16 009B 03 C7 add ax,di ; ADD IN THE OFFSET 009D 13 D1 adc dx,cx ; DX:AX = SEGMENT * 16 + OFFSET 009F BB 0400 mov bx,1024 ; BX = DIVISOR 00A2 F7 F3 div bx ; AX = # OF K BYTES OF MEMORY 00A4 BE 0413 mov si,DOS_MEM 00A7 89 04 mov 0[si],ax ; UPDATE MEMORY SIZE 00A9 BE 068C mov si,XFER_ADDR ; REBOOT FROM RAM DISKETTE IMAGE 00AC FF 2C jmp dword ptr 0[si] ; ; ;********************************************************************** ; DISKETTE IMAGE HEADER * ;********************************************************************** 00AE 28 43 29 20 43 6F db '(C) Copyright IBM Corp., 1986',13,10 70 79 72 69 67 68 74 20 49 42 4D 20 43 6F 72 70 2E 2C 20 31 39 38 36 0D 0A 00CD 54 68 69 73 20 70 db 'This program is the property of IBM.',13,10 72 6F 67 72 61 6D 20 69 73 20 74 68 65 20 70 72 6F 70 65 72 74 79 20 6F 66 20 49 42 4D 2E 0D 0A 01FA org $+512-($-rhboot+HDR_SIZE) 01FA header label byte 01FA 01 heads db 1 01FB 28 tracks db 40 01FC 08 sectors db 8 01FD 0200 sec_size dw 512 01FF 00 status db 0 0200 rhboot endp 0200 code ends end start  The IBM Personal Computer MACRO Assembler 10-15-86 PAGE Symbols-1 RHBOOT -- BOOTSTRAP LOAD PROGRAM Segments and groups: N a m e Size align combine class CODE . . . . . . . . . . . . . . 0200 PARA PUBLIC Symbols: N a m e Type Value Attr DISK_ADDR. . . . . . . . . . . . Number 0120 DOS_MEM. . . . . . . . . . . . . Number 0413 HDR_SIZE . . . . . . . . . . . . Number 0006 HEADER . . . . . . . . . . . . . L BYTE 01FA CODE HEADS. . . . . . . . . . . . . . L BYTE 01FA CODE MEM_SIZE . . . . . . . . . . . . Number 0012 RHBOOT . . . . . . . . . . . . . F PROC 0000 CODE Global Length =0200 RHBOOT01 . . . . . . . . . . . . L NEAR 0043 CODE RHBOOT02 . . . . . . . . . . . . L NEAR 0051 CODE RHBOOT03 . . . . . . . . . . . . L NEAR 005D CODE RHBOOT04 . . . . . . . . . . . . L NEAR 006A CODE RHBOOT05 . . . . . . . . . . . . L NEAR 0072 CODE RHBOOT06 . . . . . . . . . . . . L NEAR 007F CODE RHBOOT07 . . . . . . . . . . . . L NEAR 0088 CODE SECTORS. . . . . . . . . . . . . L BYTE 01FC CODE SEC_SIZE . . . . . . . . . . . . L WORD 01FD CODE SETDS. . . . . . . . . . . . . . L NEAR 0003 CODE START. . . . . . . . . . . . . . L NEAR 0000 CODE STATUS . . . . . . . . . . . . . L BYTE 01FF CODE TRACKS . . . . . . . . . . . . . L BYTE 01FB CODE XFER_ADDR. . . . . . . . . . . . Number 068C Warning Severe Errors Errors 0 0