460 Assignment #1

   
                          REQUIREMENTS 

##########################################################################
                     (DUE in ONE WEEK)
  Turn in a floppy disk and a hard copy. Sign up for DEMO in Sloan 327.
##########################################################################


The following assembly file may be used as part of a boot program.
As shown, the assembly code calls _main, which can be written in C.

In YOUR main() : call setVideo() to clear the screen.

                 while(1){
                      call myprints() to print a string, e.g. What's you name?
                      call mygets()   to read (and echo each char) user's NAME.
                      display a message such as   Welcome! NAME
                      if NAME equals "quit" : return;
                 }

YOU MUST implement the functions 
         myprints(s) char *s;
         mygets(s)   char *s;
in C, which call putc(), getc() in assembly.

With YOUR myc.c file, generate a bootable diskette as follows:  

                Under Linux (as a sh script file)
      #===================================================
      bcc  -c   myc.c                            
      as86 -o   mys.o  mys.s
      ld86 -d   mys.o  myc.o  /usr/lib/bcc/libc.a

      # check a.out size, NUST be <= 1024 bytes
      dd   if=a.out of=/dev/fd0
      #==================================================

Boot from the floppy disk. You should see the printed messages. If not, modify
YOUR .c file and try again.

The file  ~cs460/samples/lab1.bin.gz  is a sample solution.  
Download the file.  Run  gunzip  lab1.bin.gz   to uncompress it.
Dump it to a floppy disk by
 
      dd   if=lab1.bin   of=/dev/fd0   bs=1024

Then, reboot from the floppy disk. 

To boot the floopy disk under DOSEMU, run 
      xdosemu -A

!============================ mys.s file ====================================

        BOOTSEG =  0x9000        ! Boot block is loaded here.
        SSP     =    4096        ! Stack pointer at 4KB relative to SS

.globl begtext, begdata, begbss                      ! these are needed by linker

.globl _setVideo, _diskr, _getc, _putc               ! EXPORT
.globl _main, _myprints                              ! IMPORT 

.text                                                ! these tell as:	
begtext:                                             ! text,data,bss segments
.data                                                ! are all the same.
begdata:
.bss
begbss:
.text       
                                         
! this is the entry point
        !---------------------------------------------------------------------------------
        ! Only one SECTOR loaded at (0000:7C00). We shall get entire BLOCK0 to (0x9000,0)
        !---------------------------------------------------------------------------------
start:	
        mov  ax,cs          
	mov  ss,ax          ! set SS=CS=0x0000
	mov  sp,#0          ! sp at 0x1000, now we have a stack

        mov  ax,#BOOTSEG    
        mov  es,ax          ! set ES to 0x9000 for memory location (ES,BX)

! call diskr(cyl, head, sector, buf) with (0,0,0,0)
        xor  ax,ax          ! clear AX
        push ax             ! push 0 for buf=0
	push ax             ! push 0 for sector=0 (diskr will inc it by 1)
	push ax             ! push 0 for head=0
	push ax             ! push 0 for cyl=0
        call _diskr         ! call diskr() to read 2 sectors to (ES,BX)=(0x9000,0)	 
	
! jump indirect to (0x9000, start) to continue execution there
        jmpi    go_on,BOOTSEG           ! CS=BOOTSEG, IP=go_on

go_on:
        mov     ax,cs                   ! establish segments CS, DS, SS, again 
        mov     ds,ax                   ! we know ES,CS=0x9000. Let DS=CS  
        mov     ss,ax                   ! SS = CS ===> all point at 0x9000
        mov     sp,#SSP                 ! SP = SS + 4KB

        mov     ax, #0x0012             ! color
        int     0x10                    

        call _main                      ! call main() in C

dead:   jmp   dead                      ! fall into an infinite loop

        !----------------------------------------
        ! setVideo() : clear screen, home cursor
        !----------------------------------------
_setVideo:	
        mov     ax, #0x0012    ! color
        int     0x10                    
        mov     ax, #0x0200    ! home cursor        
        xor     bx, bx
        xor     dx, dx
        int     0x10                   
        ret 

	!---------------------------------------
	! diskr(cyl, head, sector, buf)
	!        4     6     8      10
	!---------------------------------------
_diskr:
	push  bp
	mov   bp,sp            ! bp = stack frame pointer

	movb  dl, #0x00        ! drive 0=FD0
	movb  dh, 6[bp]        ! head
	movb  cl, 8[bp]        ! sector
	incb  cl               ! inc sector by 1 to suit BIOS
	movb  ch, 4[bp]        ! cyl
	mov   bx, 10[bp]       ! BX=buf ==> memory addr=(ES,BX)
	mov   ax, #0x0202      ! READ 2 sectors to (EX, BX)

	int  0x13              ! call BIOS to read the block
	jb   error             ! to error if CarryBit is on [read failed]

	pop  bp
	ret

        !------------------------------
        !       error & reboot
        !------------------------------
error:	
        mov  bx, #bad
        push bx
        call _prints

        int  0x19                       ! reboot
	
bad:    .asciz  "Error!"
	
		
        !---------------------------------------------
        !  char getc()   function: returns a char
        !---------------------------------------------
_getc:
        xorb   ah,ah           ! clear ah
        int    0x16            ! call BIOS to get a char in AX
        ret 

        !----------------------------------------------
        ! void putc(char c)  function: print a char
        !----------------------------------------------
_putc:           
        push   bp
        mov    bp,sp

        movb   al,4[bp]        ! get the char into aL
        movb   ah,#14   
        mov    bx,#0x000B      ! BL=0B => cyan    
        int    0x10            ! call BIOS to display the char

        pop    bp
        ret
!===========================================================================