ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/AmigaOS/asm_support.asm
(Generate patch)

Comparing BasiliskII/src/AmigaOS/asm_support.asm (file contents):
Revision 1.2 by cebix, 1999-10-19T19:28:13Z vs.
Revision 1.6 by cebix, 2000-10-11T17:55:05Z

# Line 28 | Line 28
28                  XDEF    _AtomicAnd
29                  XDEF    _AtomicOr
30                  XDEF    _MoveVBR
31                XDEF    _TimevalTo64
32                XDEF    _TimevalToMacTime
31                  XDEF    _Execute68k
32                  XDEF    _Execute68kTrap
33                  XDEF    _TrapHandlerAsm
# Line 37 | Line 35
35                  XDEF    _Scod060Patch1
36                  XDEF    _Scod060Patch2
37                  XDEF    _ThInitFPUPatch
38 +                XDEF    _AsmTriggerNMI
39  
40                  XREF    _OldTrapHandler
41                  XREF    _OldExceptionHandler
# Line 48 | Line 47
47                  XREF    _MainTask
48                  XREF    _SysBase
49                  XREF    _quit_emulator
50 +                XREF    _kprintf
51  
52                  SECTION text,CODE
53  
# Line 108 | Line 108 | setvbr         movec   d0,vbr
108                  rte
109  
110   *
111 * Convert timeval to 64 bit microseconds
112 *
113
114 _TimevalTo64    move.l  4(sp),a0                ;Pointer to timeval
115                move.l  8(sp),a1                ;Pointer to high longword of result, low longword is returned in d0
116
117                move.l  d2,-(sp)
118
119                move.l  TV_SECS(a0),d0          ;Convert to 64 bit microseconds
120                mulu.l  #1000000,d1:d0
121                add.l   TV_MICRO(a0),d0
122                moveq   #0,d2
123                addx.l  d2,d1
124                move.l  d1,(a1)
125
126                move.l  (sp)+,d2
127                rts
128
129 *
130 * Convert timeval to Mac time value (>0: milliseconds, <0: microseconds)
131 *
132
133 _TimevalToMacTime
134                move.l  4(sp),a0                ;Pointer to timeval
135
136                move.l  d2,-(sp)
137
138                move.l  TV_SECS(a0),d0          ;Convert to 64 bit microseconds
139                mulu.l  #1000000,d1:d0
140                add.l   TV_MICRO(a0),d0
141                moveq   #0,d2
142                addx.l  d2,d1
143
144                tst.l   d1                      ;Too large for 32 bit microseconds?
145                bne.s   1$
146                cmp.l   #$7fffffff,d0
147                bhi.s   1$
148
149                neg.l   d0                      ;No, return negative microseconds
150                bra.s   2$
151
152 1$              divu.l  #1000,d1:d0             ;Yes, return milliseconds
153
154 2$              move.l  (sp)+,d2
155                rts
156
157 *
111   * Execute 68k subroutine (must be ended with rts)
112   * r->a[7] and r->sr are unused!
113   *
# Line 232 | Line 185 | _ExceptionHandlerAsm
185                  pea     1$
186                  move.w  _EmulatedSR,d0
187                  move.w  d0,-(sp)
188 <                or.w    #$0100,d0               ;Set interrupt level in SR
188 >                or.w    #$2100,d0               ;Set interrupt level in SR, enter (virtual) supervisor mode
189                  move.w  d0,_EmulatedSR
190 <                move.l  $64.w,a0                ;Jump to MacOS interrupt handler
191 <                jmp     (a0)
190 >                move.l  $64.w,-(sp)             ;Jump to MacOS interrupt handler
191 >                rts
192  
193   1$              move.l  (sp)+,d0                ;Restore d0
194                  rts
# Line 326 | Line 279 | _ThInitFPUPatch        tst.b   $40(a4)
279   * Trap handler of main task
280   *
281  
282 < _TrapHandlerAsm cmp.l   #4,(sp)                 ;Illegal instruction?
282 > _TrapHandlerAsm:
283 >                cmp.l   #4,(sp)                 ;Illegal instruction?
284                  beq.s   doillinstr
285                  cmp.l   #10,(sp)                ;A-Line exception?
286                  beq.s   doaline
287                  cmp.l   #8,(sp)                 ;Privilege violation?
288                  beq.s   doprivviol
289 +                cmp.l   #9,(sp)                 ;Trace?
290 +                beq     dotrace
291 +                cmp.l   #3,(sp)                 ;Illegal Address?
292 +                beq.s   doilladdr
293 +
294 +                cmp.l   #32,(sp)
295 +                blt     1$
296 +                cmp.l   #47,(sp)
297 +                ble     doTrapXX                ; Vector 32-47 : TRAP #0 - 15 Instruction Vectors
298 +
299 + 1$:             move.l  _OldTrapHandler,-(sp)   ;No, jump to old trap handler
300 +                rts
301 +
302 + *
303 + * TRAP #0 - 15 Instruction Vectors
304 + *
305 +
306 + doTrapXX:       move.l  a0,(sp)                 ;Save a0
307 +                move.l  usp,a0                  ;Get user stack pointer
308 +                move.l  2*4(sp),-(a0)           ;Copy 4-word stack frame to user stack
309 +                move.l  1*4(sp),-(a0)
310 +                move.l  a0,usp                  ;Update USP
311 +                move.l  (sp)+,a0                ;Restore a0
312 +
313 +                addq.l  #4*2,sp                 ;Remove exception frame from supervisor stack
314 +                andi    #$d8ff,sr               ;Switch to user mode, enable interrupts
315  
316 <                move.l  _OldTrapHandler,-(sp)   ;No, jump to old trap handler
316 >                move.l  $2d*4.w,-(sp)           ;Jump to MacOS exception handler
317                  rts
318  
319 +
320 + *
321 + * trace Vector
322 + *
323 +
324 + dotrace:        move.l  a0,(sp)                 ;Save a0
325 +
326 +                move.l  usp,a0                  ;Get user stack pointer
327 +                move.l  3*4(sp),-(a0)           ;Copy 6-word stack frame to user stack
328 +                move.l  2*4(sp),-(a0)
329 +                move.l  1*4(sp),-(a0)
330 +                move.l  a0,usp                  ;Update USP
331 +                move.l  (sp)+,a0                ;Restore a0
332 +
333 +                lea     6*2(sp),sp              ;Remove exception frame from supervisor stack
334 +                andi    #$18ff,sr               ;Switch to user mode, enable interrupts, disable trace
335 +
336 +                move.l  $24.w,-(sp)             ;Jump to MacOS exception handler
337 +                rts
338 +
339 +
340   *
341   * A-Line handler: call MacOS A-Line handler
342   *
# Line 350 | Line 351 | doaline                move.l  a0,(sp)                 ;Save a0
351                  addq.l  #8,sp                   ;Remove exception frame from supervisor stack
352                  andi    #$d8ff,sr               ;Switch to user mode, enable interrupts
353  
354 +        IFNE    0
355 +
356 + ;               move.w  ([2,sp]),($3800)
357 +
358 +                cmp.w   #$a9c3,([2,sp])
359 +                bne     1$
360 +
361 +                move.l  d0,-(sp)
362 +                move.l  a0,-(sp)
363 +                pea     afmt(pc)
364 +                jsr     _kprintf
365 +                lea     3*4(sp),sp
366 + 1$:
367 +        ENDC
368 +
369                  move.l  $28.w,-(sp)             ;Jump to MacOS exception handler
370                  rts
371  
372 + afmt:           dc.b    'a0=%08lx  d0=%08lx\n',0
373 +                cnop    0,4
374 +
375 + *
376 + * Illegal address handler
377 + *
378 +
379 + doilladdr:      move.l  a0,(sp)                 ;Save a0
380 +
381 +                move.l  usp,a0                  ;Get user stack pointer
382 +                move.l  3*4(sp),-(a0)           ;Copy 6-word stack frame to user stack
383 +                move.l  2*4(sp),-(a0)
384 +                move.l  1*4(sp),-(a0)
385 +                move.l  a0,usp                  ;Update USP
386 +                move.l  (sp)+,a0                ;Restore a0
387 +
388 +                lea     6*2(sp),sp              ;Remove exception frame from supervisor stack
389 +                andi    #$d8ff,sr               ;Switch to user mode, enable interrupts
390 +
391 +                move.l  $0c.w,-(sp)             ;Jump to MacOS exception handler
392 +                rts
393 +
394 +
395   *
396   * Illegal instruction handler: call IllInstrHandler() (which calls EmulOp())
397   *   to execute extended opcodes (see emul_op.h)
398   *
399  
400 < doillinstr      move.l  a6,(sp)                 ;Save a6
400 > doillinstr
401 >                movem.l a0/d0,-(sp)
402 >                move.w  ([6+2*4,sp]),d0
403 >                and.w   #$ff00,d0
404 >                cmp.w   #$7100,d0
405 >                movem.l (sp)+,a0/d0
406 >                beq     1$
407 >
408 >                move.l  a0,(sp)                 ;Save a0
409 >                move.l  usp,a0                  ;Get user stack pointer
410 >                move.l  8(sp),-(a0)             ;Copy stack frame to user stack
411 >                move.l  4(sp),-(a0)
412 >                move.l  a0,usp                  ;Update USP
413 >                move.l  (sp)+,a0                ;Restore a0
414 >
415 >                add.w   #3*4,sp                 ;Remove exception frame from supervisor stack
416 >                andi    #$d8ff,sr               ;Switch to user mode, enable interrupts
417 >
418 >                move.l  $10.w,-(sp)             ;Jump to MacOS exception handler
419 >                rts
420 >
421 > 1$:
422 >                move.l  a6,(sp)                 ;Save a6
423                  move.l  usp,a6                  ;Get user stack pointer
424  
425                  move.l  a6,-10(a6)              ;Push USP (a7)
# Line 413 | Line 474 | doprivviol     move.l  d0,(sp)                 ;Save d0
474                  cmp.w   #$40d0,d0               ;move sr,(a0)?
475                  beq     movefromsra0
476                  cmp.w   #$40d7,d0               ;move sr,(sp)?
477 <                beq     movefromsra0
477 >                beq     movefromsrsp
478  
479                  cmp.w   #$f327,d0               ;fsave -(sp)?
480                  beq     fsavepush
481                  cmp.w   #$f35f,d0               ;frestore (sp)+?
482                  beq     frestorepop
483 +                cmp.w   #$f32d,d0               ;fsave xxx(a5) ?
484 +                beq     fsavea5
485 +                cmp.w   #$f36d,d0               ;frestore xxx(a5) ?
486 +                beq     frestorea5
487  
488                  cmp.w   #$4e73,d0               ;rte?
489                  beq     pvrte
# Line 467 | Line 532 | doprivviol     move.l  d0,(sp)                 ;Save d0
532                  cmp.w   #$f4f8,d0               ;cpusha dc/ic?
533                  beq     cpushadcic
534  
535 +                cmp.w   #$4e69,d0               ;move usp,a1
536 +                beq     moveuspa1
537 +                cmp.w   #$4e68,d0               ;move usp,a0
538 +                beq     moveuspa0
539 +
540 +                cmp.w   #$4e61,d0               ;move a1,usp
541 +                beq     moved1usp
542 +
543   pv_unhandled    move.l  (sp),d0                 ;Unhandled instruction, jump to handler in main.cpp
544                  move.l  a6,(sp)                 ;Save a6
545                  move.l  usp,a6                  ;Get user stack pointer
# Line 508 | Line 581 | popsr          move.l  a0,-(sp)                ;Save a0
581                  move.w  (a0)+,d0                ;Get SR from user stack
582                  move.w  d0,8(sp)                ;Store into CCR on exception stack frame
583                  and.w   #$00ff,8(sp)
584 <                and.w   #$2700,d0               ;Extract supervisor bits
584 >                and.w   #$e700,d0               ;Extract supervisor bits
585                  move.w  d0,_EmulatedSR          ;And save them
586  
587                  and.w   #$0700,d0               ;Rethrow exception if interrupts are pending and reenabled
# Line 534 | Line 607 | orisr          move.w  4(sp),d0                ;Get CCR from st
607                  or.w    ([6,sp],2),d0           ;Or with immediate value
608                  move.w  d0,4(sp)                ;Store into CCR on stack
609                  and.w   #$00ff,4(sp)
610 <                and.w   #$2700,d0               ;Extract supervisor bits
610 >                and.w   #$e700,d0               ;Extract supervisor bits
611                  move.w  d0,_EmulatedSR          ;And save them
612                  move.l  (sp)+,d0                ;Restore d0
613                  addq.l  #4,2(sp)                ;Skip instruction
# Line 546 | Line 619 | andisr         move.w  4(sp),d0                ;Get CCR from s
619                  and.w   ([6,sp],2),d0           ;And with immediate value
620   storesr4        move.w  d0,4(sp)                ;Store into CCR on stack
621                  and.w   #$00ff,4(sp)
622 <                and.w   #$2700,d0               ;Extract supervisor bits
622 >                and.w   #$e700,d0               ;Extract supervisor bits
623                  move.w  d0,_EmulatedSR          ;And save them
624  
625                  and.w   #$0700,d0               ;Rethrow exception if interrupts are pending and reenabled
# Line 633 | Line 706 | frestorepop    move.l  (sp),d0                 ;Restore d0
706                  addq.l  #2,2(sp)                ;Skip instruction
707                  rte
708  
709 < ; rte (only handles format 0)
710 < pvrte           move.l  a0,-(sp)                ;Save a0
709 > ; frestore xxx(a5) +jl+
710 > frestorea5      move.l  (sp),d0                 ;Restore d0
711 >                move.l  a0,(sp)                 ;Save a0
712 >                move.l  a5,a0                   ;Get base register
713 >                add.w   ([6,sp],2),a0           ;Add offset to base register
714 >                frestore (a0)                   ;Restore FP state from (a0)
715 >                move.l  (sp)+,a0                ;Restore a0
716 >                addq.l  #4,2(sp)                ;Skip instruction
717 >                rte
718 >
719 > ; fsave xxx(a5) +jl+
720 > fsavea5:        move.l  (sp),d0                 ;Restore d0
721 >                move.l  a0,(sp)                 ;Save a0
722 >                move.l  a5,a0                   ;Get base register
723 >                add.w   ([6,sp],2),a0           ;Add offset to base register
724 >                fsave   (a0)                    ;Push FP state to (a0)
725 >                move.l  (sp)+,a0                ;Restore a0
726 >                addq.l  #4,2(sp)                ;Skip instruction
727 >                rte
728 >
729 > ; rte
730 > pvrte           movem.l a0/a1,-(sp)             ;Save a0 and a1
731                  move.l  usp,a0                  ;Get user stack pointer
732 +
733                  move.w  (a0)+,d0                ;Get SR from user stack
734 <                move.w  d0,8(sp)                ;Store into CCR on exception stack frame
735 <                and.w   #$00ff,8(sp)
736 <                and.w   #$2700,d0               ;Extract supervisor bits
734 >                move.w  d0,8+4(sp)              ;Store into CCR on exception stack frame
735 >                and.w   #$c0ff,8+4(sp)
736 >                and.w   #$e700,d0               ;Extract supervisor bits
737                  move.w  d0,_EmulatedSR          ;And save them
738 <                move.l  (a0)+,10(sp)            ;Store return address in exception stack frame
739 <                addq.l  #2,a0                   ;Skip format word
738 >                move.l  (a0)+,10+4(sp)          ;Store return address in exception stack frame
739 >
740 >                move.w  (a0)+,d0                ;get format word
741 >                lsr.w   #7,d0                   ;get stack frame Id
742 >                lsr.w   #4,d0
743 >                and.w   #$001e,d0
744 >                move.w  (StackFormatTable,pc,d0.w),d0   ; get total stack frame length
745 >                subq.w  #4,d0                   ; count only extra words
746 >                lea     16+4(sp),a1             ; destination address (in supervisor stack)
747 >                bra     1$
748 >
749 > 2$:             move.w  (a0)+,(a1)+             ; copy additional stack words back to supervisor stack
750 > 1$:             dbf     d0,2$
751 >
752                  move.l  a0,usp                  ;Update USP
753 <                move.l  (sp)+,a0                ;Restore a0
753 >                movem.l (sp)+,a0/a1             ;Restore a0 and a1
754                  move.l  (sp)+,d0                ;Restore d0
755                  rte
756  
757 + ; sizes of exceptions stack frames
758 + StackFormatTable:
759 +                dc.w    4                       ; Four-word stack frame, format $0
760 +                dc.w    4                       ; Throwaway four-word stack frame, format $1
761 +                dc.w    6                       ; Six-word stack frame, format $2
762 +                dc.w    6                       ; MC68040 floating-point post-instruction stack frame, format $3
763 +                dc.w    8                       ; MC68EC040 and MC68LC040 floating-point unimplemented stack frame, format $4
764 +                dc.w    4                       ; Format $5
765 +                dc.w    4                       ; Format $6
766 +                dc.w    30                      ; MC68040 access error stack frame, Format $7
767 +                dc.w    29                      ; MC68010 bus and address error stack frame, format $8
768 +                dc.w    10                      ; MC68020 and MC68030 coprocessor mid-instruction stack frame, format $9
769 +                dc.w    16                      ; MC68020 and MC68030 short bus cycle stack frame, format $a
770 +                dc.w    46                      ; MC68020 and MC68030 long bus cycle stack frame, format $b
771 +                dc.w    12                      ; CPU32 bus error for prefetches and operands stack frame, format $c
772 +                dc.w    4                       ; Format $d
773 +                dc.w    4                       ; Format $e
774 +                dc.w    4                       ; Format $f
775 +
776   ; move sr,dx
777   movefromsrd0    addq.l  #4,sp                   ;Skip saved d0
778                  moveq   #0,d0
# Line 709 | Line 834 | movefromsrd7   move.l  (sp)+,d0
834   movetosrd0      move.l  (sp),d0
835   storesr2        move.w  d0,4(sp)
836                  and.w   #$00ff,4(sp)
837 <                and.w   #$2700,d0
837 >                and.w   #$e700,d0
838                  move.w  d0,_EmulatedSR
839  
840                  and.w   #$0700,d0               ;Rethrow exception if interrupts are pending and reenabled
# Line 754 | Line 879 | movecfromcr    move.w  ([6,sp],2),d0           ;Get n
879                  beq.s   movecvbra0
880                  cmp.w   #$9801,d0               ;movec vbr,a1?
881                  beq.s   movecvbra1
882 +                cmp.w   #$1801,d0               ;movec vbr,d1?
883 +                beq     movecvbrd1
884                  cmp.w   #$0002,d0               ;movec cacr,d0?
885                  beq.s   moveccacrd0
886                  cmp.w   #$1002,d0               ;movec cacr,d1?
# Line 762 | Line 889 | movecfromcr    move.w  ([6,sp],2),d0           ;Get n
889                  beq.s   movectcd0
890                  cmp.w   #$1003,d0               ;movec tc,d1?
891                  beq.s   movectcd1
892 +                cmp.w   #$1000,d0               ;movec sfc,d1?
893 +                beq     movecsfcd1
894 +                cmp.w   #$1001,d0               ;movec dfc,d1?
895 +                beq     movecdfcd1
896 +                cmp.w   #$0806,d0               ;movec urp,d0?
897 +                beq     movecurpd0
898 +                cmp.w   #$0807,d0               ;movec srp,d0?
899 +                beq.s   movecsrpd0
900 +                cmp.w   #$0004,d0               ;movec itt0,d0
901 +                beq.s   movecitt0d0
902 +                cmp.w   #$0005,d0               ;movec itt1,d0
903 +                beq.s   movecitt1d0
904 +                cmp.w   #$0006,d0               ;movec dtt0,d0
905 +                beq.s   movecdtt0d0
906 +                cmp.w   #$0007,d0               ;movec dtt1,d0
907 +                beq.s   movecdtt1d0
908  
909                  bra     pv_unhandled
910  
# Line 789 | Line 932 | movecvbra1     move.l  (sp)+,d0
932                  addq.l  #4,2(sp)
933                  rte
934  
935 + ; movec vbr,d1
936 + movecvbrd1      move.l  (sp)+,d0
937 +                moveq.l #0,d1                   ;VBR always appears to be at 0
938 +                addq.l  #4,2(sp)
939 +                rte
940 +
941   ; movec tc,d0
942   movectcd0       addq.l  #4,sp
943                  moveq   #0,d0                   ;MMU is always off
944                  addq.l  #4,2(sp)
945                  rte
946  
947 < ; movec tc,d1
948 < movectcd1       addq.l  #4,sp
947 > ; movec tc,d1   +jl+
948 > movectcd1       move.l  (sp)+,d0                ;Restore d0
949                  moveq   #0,d1                   ;MMU is always off
950                  addq.l  #4,2(sp)
951                  rte
952  
953 + ; movec sfc,d1  +jl+
954 + movecsfcd1:     move.l  (sp)+,d0                ;Restore d0
955 +                moveq   #0,d1
956 +                addq.l  #4,2(sp)
957 +                rte
958 +
959 + ; movec dfc,d1  +jl+
960 + movecdfcd1:     move.l  (sp)+,d0                ;Restore d0
961 +                moveq   #0,d1
962 +                addq.l  #4,2(sp)
963 +                rte
964 +
965 + movecurpd0:             ; movec urp,d0  +jl+
966 + movecsrpd0:             ; movec srp,d0
967 + movecitt0d0:            ; movec itt0,d0
968 + movecitt1d0:            ; movec itt1,d0
969 + movecdtt0d0:            ; movec dtt0,d0
970 + movecdtt1d0:            ; movec dtt1,d0
971 +                addq.l  #4,sp
972 +                moveq.l #0,d0                   ;MMU is always off
973 +                addq.l  #4,2(sp)                ;skip instruction
974 +                rte
975 +
976   ; movec x,cr
977   movectocr       move.w  ([6,sp],2),d0           ;Get next instruction word
978  
979                  cmp.w   #$0801,d0               ;movec d0,vbr?
980                  beq.s   movectovbr
981 +                cmp.w   #$1801,d0               ;movec d1,vbr?
982 +                beq.s   movectovbr
983                  cmp.w   #$0002,d0               ;movec d0,cacr?
984                  beq.s   movectocacr
985                  cmp.w   #$1002,d0               ;movec d1,cacr?
986                  beq.s   movectocacr
987 +                cmp.w   #$1000,d0               ;movec d1,sfc?
988 +                beq.s   movectoxfc
989 +                cmp.w   #$1001,d0               ;movec d1,dfc?
990 +                beq.s   movectoxfc
991  
992                  bra     pv_unhandled
993  
# Line 827 | Line 1005 | movectocacr    movem.l d1/a0-a1/a6,-(sp)       ;M
1005                  addq.l  #4,2(sp)
1006                  rte
1007  
1008 + ; movec x,sfc
1009 + ; movec x,dfc
1010 + movectoxfc      move.l  (sp)+,d0                ;Ignore moves to SFC, DFC
1011 +                addq.l  #4,2(sp)
1012 +                rte
1013 +
1014   ; cpusha
1015   cpushadc
1016   cpushadcic      movem.l d1/a0-a1/a6,-(sp)       ;Clear caches
# Line 837 | Line 1021 | cpushadcic     movem.l d1/a0-a1/a6,-(sp)       ;Cl
1021                  addq.l  #2,2(sp)
1022                  rte
1023  
1024 + ; move usp,a1   +jl+
1025 + moveuspa1:      move.l  (sp)+,d0
1026 +                move    usp,a1
1027 +                addq.l  #2,2(sp)
1028 +                rte
1029 +
1030 + ; move usp,a0   +jl+
1031 + moveuspa0:      move.l  (sp)+,d0
1032 +                move    usp,a0
1033 +                addq.l  #2,2(sp)
1034 +                rte
1035 +
1036 + ; move a1,usp   +jl+
1037 + moved1usp:      move.l  (sp)+,d0
1038 +                move    a1,usp
1039 +                addq.l  #2,2(sp)
1040 +                rte
1041 +
1042 + ;
1043 + ; Trigger NMI (Pop up debugger)
1044 + ;
1045 +
1046 + _AsmTriggerNMI:
1047 +                move.l  d0,-(sp)                ;Save d0
1048 +                move.w  #$007c,-(sp)            ;Yes, fake NMI stack frame
1049 +                pea     1$
1050 +                move.w  _EmulatedSR,d0
1051 +                and.w   #$f8ff,d0               ;Set interrupt level in SR
1052 +                move.w  d0,-(sp)
1053 +                move.w  d0,_EmulatedSR
1054 +
1055 +                move.l  $7c.w,-(sp)             ;Jump to MacOS NMI handler
1056 +                rts
1057 +
1058 + 1$              move.l  (sp)+,d0                ;Restore d0
1059 +                rts
1060 +
1061 +
1062                  END

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines