//------------------------------------------------------------------ // queryA20.s // // This program will report the state of the A20 address-line, // based on a comparison of memory-bytes at aliased addresses. // // to assemble: $ as queryA20.s -o queryA20.o // and to link: $ ld queryA20.o -T ldscript -o queryA20.b // and install: $ dd if=queryA20.b of=/dev/sda4 seek=1 // // NOTE: This code begins executing with CS:IP = 1000:0002. // // programmer: ALLAN CRUSE // written on: 05 NOV 2008 //------------------------------------------------------------------ .section .text #------------------------------------------------------------------- .word 0xABCD # our application signature #------------------------------------------------------------------- main: .code16 mov %sp, %cs:ipltos+0 # store loader's SP value mov %ss, %cs:ipltos+2 # store loader's SS value mov %cs, %ax # address program's arena mov %ax, %ss # using the SS register lea tos, %sp # and establish new stack # determine whether the A20 address-line is now enabled # by comparing memory seen at 0x00000000 and 0x00100000 mov $0x0000, %ax # address segment zero mov %ax, %ds # with DS register mov $0xFFFF, %ax # address high segment mov %ax, %es # with ES register mov $0x0000, %si # DS:SI is 0x00000000 mov $0x0010, %di # ES:DI is 0x00100000 # see if these memory-cells' values initially are unequal mov %es:(%di), %al # fetch the upper byte mov %ds:(%si), %ah # fetch the lower byte cmp %al, %ah # are the bytes equal? jne a20on # no, A20-line is ON # if they're equal, flip one and see if the other changes notb %es:(%di) # modify the upper byte mov %es:(%di), %bl # fetch new upper byte mov %ds:(%si), %bh # fetch old lower byte notb %es:(%di) # restore the upper byte cmp %bl, %bh # did lower byte change? jne a20on # no, A20-line is ON movw $1, %ss:same # else A20-line is OFF a20on: # setup registers DS and ES to address our variables mov %cs, %ax # address program data mov %ax, %ds # with DS register mov %ax, %es # also ES register # format the current value from System Control Port A in $0x92, %al # input port's setting mov $0x33, %ah # setup hi-nybble pair ror $4, %ax # format the MSB in AL ror $4, %ah # format the LSB in AH mov %ax, buf1 # store the digit-pair # format the 'yes/no' field in our report-message imul $4, same, %bx # BX = 4 times boolean mov yorn(%bx), %eax # select message-word mov %eax, buf2 # and store this text # display our report-message regarding this inquiry mov $0x0F, %ah # vram page-no to BH int $0x10 # invoke BIOS service mov $0x03, %ah # cursor into DH,DL int $0x10 # invole BIOS service lea msg, %bp # point ES:BP to string mov len, %cx # string-length into CX mov att, %bl # string-colors into BL mov $0x1301, %ax # write_string function int $0x10 # invole BIOS service lss %cs:ipltos, %sp # recover loader's stacktop lret # return to our boot-loader #------------------------------------------------------------------- ipltos: .word 0, 0 # stores loader's SS and SP #------------------------------------------------------------------- same: .word 0 # boolean-value for inquiry yorn: .ascii "Yes No " # lookup-table for messages msg: .ascii "\n\r Port 0x92: " # legend for message's info buf1: .ascii "xx \n\r\n" # buffer for i/o-port value .ascii " Memory-cells at 0-MB and 1-MB are different? " buf2: .ascii "xxxx \n\r\n" # buffer for 'yes' or 'no' len: .short . - msg # count of bytes in message att: .byte 0x0E # color-attributes for text #------------------------------------------------------------------- .align 16 # assures stack's alignment .space 256 # reserved for stack to use tos: # labels our "top-of-stack" #------------------------------------------------------------------- .end