****
* Original library for CS255
*
* It supports a linked list with 1 int value
* If you need to print a linked iwth with different
* number of elements,change the line marked "Cheung"
****
 
        xdef ReadLn,WriteLn,malloc
        xdef ReadInt,WriteInt
        xdef PrintList
        xdef PrintList2

* ReadLn: input: a0 = address of length
*		 a1 = address of buffer
* Return: read line from termin0,return length (# bytes read)
*	  Return length -1 if end of file
*
ReadLn: 
        move.l #-1,$140C	; Clobber status
        move.l a1,$1408	; Set buffer address
        move.l #0,$1400;       ; Read
rloop:  cmpi.l #-1,$140c       ; Test if status is still -1
        beq         rloop       ; Repeat testing until status changes
	cmpi.l #0,$140C	; Test termination status
	beq    normal
	move.l #-1,(a0)	; End of file
	bra    rend
normal: move.l $1404,(a0)	; Put length in string structure
rend:   rts

* WriteLn: input: d0 = length of string
*		  a0 = buffer containing string
* Print d0 characters from memory location a0 to termout0
*
WriteLn:
	move.l #-1,$140C       ; Clobber status
	move.l d0,$1404	; Set length 
	move.l a0,$1408	; Set buffer address
	move.l #1,$1400;       ; Write
wloop:  cmpi.l #-1,$140c       ; Test if status is still -1
        beq         wloop       ; Repeat testing until status changes
        rts

* malloc(): input d0 = size of memory
*	    return: a0 = address of dynamically allocated memory segment
malloc:
	move.l d0,-(a7)
	move.l d1,-(a7)
	movea.l maddr,a0
	move.l  a0,d1
	add.l   d1,d0

	move.l  d0,d1
	and.l   #1,d1
	beq     store

	addq.l  #1,d0
store:  move.l  d0,maddr

	move.l (a7)+,d1
	move.l (a7)+,d0
	rts

maddr:	dc.l  $10000


ReadInt:
	move.l a0,-(sp)
	move.l a1,-(sp)

	move.l  #length,a0
	move.l  #buffer,a1
        jsr     ReadLn          ; Read string in buffer

	move.l  length,d0
	cmp.l   #-1,d0
	beq	ReadIntErr

	move.l  #length,a0
	move.l  #buffer,a1
        jsr     atoi            ; Convert string to integer representation

	move.l	#0,d1		; Set error code to 0

ReadIntErr:
	move.l (sp)+,a1
	move.l (sp)+,a0
	move.l #-1,d1		; Set error code to -1
	rts

WriteInt:
	move.l a0,-(sp)
	move.l a1,-(sp)
	move.l d0,-(sp)

        move.l  #length,a0
        move.l  #buffer,a1
        jsr     itoa            ; convert sum to ascii


	move.l  length,d0
	move.l  #buffer,a0
        jsr     WriteLn         ; Write sum to terminal

	move.l (sp)+,d0
	move.l (sp)+,a1
	move.l (sp)+,a0
	rts

length: ds.l	1
buffer: ds.b    80


atoi:   move.l (a0)+,d1	; d1 = length of string
	clr.l  d0		; d0 = integer repr.
	clr.b  d7		; d7 = 0 indicate positive number

	cmpi.b #'-',(a0)	; Test if first char is '-'
	bne    nosign		;

	move.b #1,d7		; Indicate negative number
	adda.l #1,a0		; Move to digit
	subq.l #1,d1		; Discount length

nosign:
	cmpi.l #0,d1		; d1 = 0 means done (checked all digits)
	beq    atoiclean

	mulu   #10,d0
	move.b (a0)+,d2
	subi.b #'0',d2
	ext.w  d2
	ext.l  d2
	add.l  d2,d0

	subq.l #1,d1
	bra    nosign

atoiclean:
	cmpi.b #0,d7
	beq    atoidone
	
	neg.l  d0		; Number was negative
atoidone:
        rts

itoa:   clr.b  d7		; d7 = 0 if number is positive

	cmpi.l #0,d0
	bne   itoanext

	move.b #'0',(a1)	; 0 detected
	move.l #1,(a0)
	rts

itoanext:
	bge    pos

	neg.l  d0
	move.b #1,d7

pos:    clr.l  d1		; d1 = length of string (not including sign)
	move.l #help,a1	; construct reverse string in help

itoaloop:
	cmpi.l #0,d0
	beq    itoaclean

	divu   #10,d0
	move.w d0,d2		; save quotient in d2
	swap   d0
	add.b  #'0',d0		; Make ascii digit
	move.b d0,(a1)+
	addq.l #1,d1		; Keep count of length of string
	move.w d2,d0
	ext.l  d0
	bra    itoaloop

itoaclean:
	cmpi.b #0,d7
	beq    itoaclean2

	move.b #'-',(a1)+
	addq.l #1,d1

itoaclean2:
	move.l d1,(a0)+	; Put the length in place

itoamove:
	move.b -(a1),(a0)+
	subq.l #1,d1
	bgt    itoamove
        rts

help:   ds.b  80		; reverse string




PrintList:
	move.l a0,-(a7)	; Save a0
	move.l d0,-(a7)	; Save d0
	move.l a0,tmp

	move.l #line1,a0
	move.l #12,d0
	bsr WriteLn


xxx:	
	move.l tmp,a0
	cmpa.l #0,a0
	beq    xxx_done

*************************************************
	move.l 4(a0),tmp	; move to next list element - Cheung 
*************************************************

	move.l (a0),d0		; for printing
	bsr    WriteInt
	bra xxx

xxx_done:
	move.l #line2,a0
	move.l #12,d0
	bsr WriteLn

	move.l (a7)+,d0	; Restore d0
	move.l (a7)+,a0	; Restore a0
	rts




PrintList2:
	move.l a0,-(a7)	; Save a0
	move.l d0,-(a7)	; Save d0
	move.l a0,tmp

	move.l #line1,a0
	move.l #12,d0
	bsr WriteLn


xxx2:	
	move.l tmp,a0
	cmpa.l #0,a0
	beq    xxx_done2
	move.l 8(a0),tmp	; next list element
	move.l (a0),d0		; for printing
	bsr    WriteInt
	bra xxx2

xxx_done2:
	move.l #line2,a0
	move.l #12,d0
	bsr WriteLn

	move.l (a7)+,d0	; Restore d0
	move.l (a7)+,a0	; Restore a0
	rts



tmp:	ds.l 1

line1:  dc.b   'The list is:     '
line2:  dc.b   '-----------------'
        end