Browse Source

Plan 9 from Bell Labs 2002-12-13

David du Colombier 21 years ago
parent
commit
79b935b594
91 changed files with 2722 additions and 1577 deletions
  1. 411 408
      dist/replica/plan9.db
  2. 522 0
      dist/replica/plan9.log
  3. 2 0
      sys/include/draw.h
  4. 11 10
      sys/include/memdraw.h
  5. 7 1
      sys/man/2/print
  6. 52 6
      sys/man/8/ventiaux
  7. 6 4
      sys/src/9/alphapc/apc
  8. 6 3
      sys/src/9/alphapc/apccpu
  9. 40 4
      sys/src/9/alphapc/devarch.c
  10. 57 19
      sys/src/9/alphapc/devether.c
  11. 6 0
      sys/src/9/alphapc/etherif.h
  12. 3 2
      sys/src/9/alphapc/initcode
  13. 151 14
      sys/src/9/alphapc/main.c
  14. 2 1
      sys/src/9/alphapc/mkfile
  15. 4 5
      sys/src/9/alphapc/pci.c
  16. 1 138
      sys/src/9/alphapc/random.c
  17. 1 532
      sys/src/9/alphapc/screen.c
  18. 2 0
      sys/src/9/alphapc/screen.h
  19. 1 1
      sys/src/9/bitsy/main.c
  20. 8 8
      sys/src/9/bitsy/screen.c
  21. 3 3
      sys/src/9/boot/bootauth.c
  22. 3 3
      sys/src/9/boot/bootcache.c
  23. 1 1
      sys/src/9/boot/bootip.c
  24. 3 3
      sys/src/9/boot/embed.c
  25. 2 2
      sys/src/9/boot/local.c
  26. 1 1
      sys/src/9/boot/paq.c
  27. 37 0
      sys/src/9/boot/testboot.c
  28. 3 2
      sys/src/9/mtx/initcode
  29. 1 1
      sys/src/9/mtx/mkfile
  30. 5 3
      sys/src/9/mtx/mtx
  31. 6 3
      sys/src/9/mtx/mtxcpu
  32. 3 2
      sys/src/9/pc/devvga.c
  33. 1 1
      sys/src/9/pc/kbd.c
  34. 5 5
      sys/src/9/pc/mkfile
  35. 5 3
      sys/src/9/pc/pc
  36. 7 4
      sys/src/9/pc/pcauth
  37. 6 5
      sys/src/9/pc/pccd
  38. 6 2
      sys/src/9/pc/pccpu
  39. 8 6
      sys/src/9/pc/pcdisk
  40. 11 5
      sys/src/9/pc/screen.c
  41. 3 0
      sys/src/9/pc/screen.h
  42. 6 6
      sys/src/9/pc/vga.c
  43. 65 21
      sys/src/9/port/devdraw.c
  44. 27 13
      sys/src/9/port/devmnt.c
  45. 102 38
      sys/src/9/port/devroot.c
  46. 26 0
      sys/src/9/port/initcode.c
  47. 26 0
      sys/src/9/port/mkbootrules
  48. 17 2
      sys/src/9/port/mkdevc
  49. 13 2
      sys/src/9/port/mkdevlist
  50. 1 1
      sys/src/9/port/mkextract
  51. 8 3
      sys/src/9/port/mkroot
  52. 1 1
      sys/src/9/port/portfns.h
  53. 10 49
      sys/src/9/port/portmkfile
  54. 2 2
      sys/src/cmd/crop.c
  55. 1 2
      sys/src/cmd/exportfs/exportfs.c
  56. 20 8
      sys/src/cmd/fax/mkfile
  57. 1 1
      sys/src/cmd/iconv.c
  58. 1 1
      sys/src/cmd/jpg/multichan.c
  59. 1 1
      sys/src/cmd/jpg/onechan.c
  60. 1 1
      sys/src/cmd/jpg/writepng.c
  61. 2 2
      sys/src/cmd/postscript/p9bitpost/pslib.c
  62. 2 2
      sys/src/cmd/resample.c
  63. 25 0
      sys/src/cmd/venti/backup.example
  64. 181 0
      sys/src/cmd/venti/copy.c
  65. 1 0
      sys/src/cmd/venti/mkfile
  66. 16 7
      sys/src/cmd/venti/read.c
  67. 1 0
      sys/src/cmd/vl/l.h
  68. 49 15
      sys/src/cmd/vnc/devdraw.c
  69. 5 1
      sys/src/cmd/vnc/kbd_vwr.c
  70. 10 10
      sys/src/cmd/vnc/screen.c
  71. 38 13
      sys/src/cmd/vnc/vncs.c
  72. 22 6
      sys/src/libc/fmt/dofmt.c
  73. 1 0
      sys/src/libmemdraw/alloc.c
  74. 6 6
      sys/src/libmemdraw/arc.c
  75. 529 87
      sys/src/libmemdraw/draw.c
  76. 6 4
      sys/src/libmemdraw/ellipse.c
  77. 16 16
      sys/src/libmemdraw/fillpoly.c
  78. 32 12
      sys/src/libmemdraw/line.c
  79. 13 11
      sys/src/libmemdraw/openmemsubfont.c
  80. 2 2
      sys/src/libmemdraw/poly.c
  81. 1 1
      sys/src/libmemdraw/string.c
  82. 6 4
      sys/src/libmemlayer/draw.c
  83. 1 1
      sys/src/libmemlayer/lalloc.c
  84. 1 1
      sys/src/libmemlayer/layerop.c
  85. 1 1
      sys/src/libmemlayer/ldelete.c
  86. 2 2
      sys/src/libmemlayer/lhide.c
  87. 7 5
      sys/src/libmemlayer/line.c
  88. 1 1
      sys/src/libmemlayer/load.c
  89. 2 2
      sys/src/libmemlayer/lorigin.c
  90. 0 1
      sys/src/libmemlayer/mkfile
  91. 1 1
      sys/src/libmemlayer/unload.c

File diff suppressed because it is too large
+ 411 - 408
dist/replica/plan9.db


+ 522 - 0
dist/replica/plan9.log

@@ -16222,3 +16222,525 @@
 1039674725 1 c 386/bin/ape/dirname - 775 sys sys 1039673023 135007
 1039674725 1 c 386/bin/ape/dirname - 775 sys sys 1039673023 135007
 1039674725 2 c 386/bin/aux/lpdsend - 775 sys sys 1039673024 156055
 1039674725 2 c 386/bin/aux/lpdsend - 775 sys sys 1039673024 156055
 1039721575 0 c sys/games/lib/fortunes - 664 sys sys 1039720623 237691
 1039721575 0 c sys/games/lib/fortunes - 664 sys sys 1039720623 237691
+1039743615 0 c sys/man/8/ventiaux - 664 sys sys 1039743547 9089
+1039743615 1 c sys/src/9/port/devmnt.c - 664 sys sys 1039743586 21096
+1039743615 2 a sys/src/cmd/venti/backup.example - 775 sys sys 1039743539 490
+1039743615 3 a sys/src/cmd/venti/copy.c - 664 sys sys 1039743543 3405
+1039743615 4 c sys/src/cmd/venti/read.c - 664 sys sys 1039743542 1724
+1039744879 0 c sys/man/8/ventiaux - 664 sys sys 1039743887 9894
+1039748483 0 c sys/src/cmd/exportfs/exportfs.c - 664 sys sys 1039747665 15465
+1039750288 0 c 386/bin/venti/read - 775 sys sys 1039749306 102602
+1039750288 1 c 386/bin/scp - 775 sys sys 1039749303 159634
+1039750288 2 c 386/bin/ssh - 775 sys sys 1039749303 209458
+1039750288 3 c 386/bin/webfs - 775 sys sys 1039749307 342597
+1039750288 4 c 386/bin/auth/factotum - 775 sys sys 1039749299 300575
+1039750288 5 c 386/bin/auth/secretpem - 775 sys sys 1039749299 118326
+1039750288 6 c 386/bin/auth/secstore - 775 sys sys 1039749299 178795
+1039750288 7 c 386/bin/auth/secstored - 775 sys sys 1039749300 192673
+1039750288 8 c 386/bin/auth/secuser - 775 sys sys 1039749300 149083
+1039750288 9 c 386/bin/aux/X509gen - 775 sys sys 1039749301 126205
+1039750288 10 c 386/bin/aux/ssh_genkey - 775 sys sys 1039749301 194383
+1039750288 11 c 386/bin/aux/sshserve - 775 sys sys 1039749301 246300
+1039750288 12 c 386/bin/aux/timesync - 775 sys sys 1039749302 125513
+1039750288 13 c 386/bin/ip/httpd/httpd - 775 sys sys 1039749302 283378
+1039750288 14 c 386/bin/sshnet - 775 sys sys 1039749304 280813
+1039750288 15 c 386/bin/tlsclient - 775 sys sys 1039749304 191654
+1039750288 16 c 386/bin/tlssrv - 775 sys sys 1039749304 192019
+1039750288 17 c 386/bin/upas/fs - 775 sys sys 1039749305 325975
+1039750288 18 c 386/bin/upas/pop3 - 775 sys sys 1039749306 251371
+1039750288 19 c 386/bin/upas/smtp - 775 sys sys 1039749306 264502
+1039750288 20 c 386/lib/libmp.a - 664 sys sys 1039749307 77816
+1039750288 21 c sys/src/cmd/venti/mkfile - 664 sys sys 1039749273 1112
+1039753664 0 c 386/bin/exportfs - 775 sys sys 1039753145 145202
+1039753664 1 c 386/bin/scp - 775 sys sys 1039753145 159405
+1039753664 2 c 386/bin/ssh - 775 sys sys 1039753146 209227
+1039753664 3 c 386/bin/webfs - 775 sys sys 1039753149 342366
+1039753664 4 c 386/bin/auth/factotum - 775 sys sys 1039753142 300344
+1039753664 5 c 386/bin/auth/secretpem - 775 sys sys 1039753142 118095
+1039753664 6 c 386/bin/auth/secstore - 775 sys sys 1039753142 178566
+1039753664 7 c 386/bin/auth/secstored - 775 sys sys 1039753143 192442
+1039753664 8 c 386/bin/auth/secuser - 775 sys sys 1039753143 148854
+1039753664 9 c 386/bin/aux/X509gen - 775 sys sys 1039753143 125974
+1039753664 10 c 386/bin/aux/ssh_genkey - 775 sys sys 1039753144 194154
+1039753664 11 c 386/bin/aux/sshserve - 775 sys sys 1039753144 246069
+1039753664 12 c 386/bin/aux/timesync - 775 sys sys 1039753144 125282
+1039753664 13 c 386/bin/ip/httpd/httpd - 775 sys sys 1039753145 283147
+1039753664 14 c 386/bin/sshnet - 775 sys sys 1039753146 280584
+1039753664 15 c 386/bin/tlsclient - 775 sys sys 1039753147 191425
+1039753664 16 c 386/bin/tlssrv - 775 sys sys 1039753147 191788
+1039753664 17 c 386/bin/upas/fs - 775 sys sys 1039753148 325746
+1039753664 18 c 386/bin/upas/pop3 - 775 sys sys 1039753148 251142
+1039753664 19 c 386/bin/upas/smtp - 775 sys sys 1039753149 264273
+1039753664 20 c 386/lib/libmemdraw.a - 664 sys sys 1039753150 279612
+1039753664 21 c 386/lib/libmp.a - 664 sys sys 1039753150 76970
+1039753664 22 c sys/include/draw.h - 664 sys sys 1039752978 13954
+1039753664 23 c sys/include/memdraw.h - 664 sys sys 1039752978 5616
+1039753664 24 c sys/src/9/alphapc/apc - 664 sys sys 1039753420 621
+1039753664 25 c sys/src/9/alphapc/apccpu - 664 sys sys 1039753419 507
+1039753664 26 c sys/src/9/alphapc/devarch.c - 664 sys sys 1039753422 9760
+1039753664 27 c sys/src/9/alphapc/devether.c - 664 sys sys 1039753421 9659
+1039753664 28 c sys/src/9/alphapc/etherif.h - 664 sys sys 1039753421 1049
+1039753664 29 c sys/src/9/alphapc/initcode - 664 sys sys 1039753419 779
+1039753664 30 c sys/src/9/alphapc/main.c - 664 sys sys 1039753420 13626
+1039753664 31 c sys/src/9/alphapc/mkfile - 664 sys sys 1039753423 1985
+1039753664 32 c sys/src/9/alphapc/pci.c - 664 sys sys 1039753420 7868
+1039753664 33 c sys/src/9/alphapc/random.c - 664 sys sys 1039753421 26
+1039753664 34 c sys/src/9/alphapc/screen.c - 664 sys sys 1039753422 26
+1039753664 35 c sys/src/9/alphapc/screen.h - 664 sys sys 1039753422 3511
+1039753664 36 c sys/src/9/bitsy/main.c - 664 sys sys 1039753387 8929
+1039753664 37 c sys/src/9/bitsy/screen.c - 664 sys sys 1039753380 10145
+1039753664 38 c sys/src/9/mtx/initcode - 664 sys sys 1039753442 444
+1039753664 39 c sys/src/9/mtx/mkfile - 664 sys sys 1039753441 1475
+1039753664 40 c sys/src/9/mtx/mtx - 664 sys sys 1039753441 413
+1039753664 41 c sys/src/9/mtx/mtxcpu - 664 sys sys 1039753442 421
+1039753664 42 c sys/src/9/pc/devvga.c - 664 sys sys 1039753498 8625
+1039753664 43 c sys/src/9/pc/kbd.c - 664 sys sys 1039753498 9134
+1039753664 44 c sys/src/9/pc/mkfile - 664 sys sys 1039753495 2992
+1039753664 45 c sys/src/9/pc/pc - 664 sys sys 1039753496 1311
+1039753664 46 c sys/src/9/pc/pcauth - 664 sys sys 1039753496 600
+1039753664 47 c sys/src/9/pc/pccpu - 664 sys sys 1039753495 785
+1039753664 48 c sys/src/9/pc/pcdisk - 664 sys sys 1039753496 1369
+1039753664 49 c sys/src/9/pc/screen.c - 664 sys sys 1039753497 7266
+1039753664 50 c sys/src/9/pc/screen.h - 664 sys sys 1039753497 3742
+1039753664 51 c sys/src/9/pc/pccd - 664 sys sys 1039753495 1278
+1039753664 52 c sys/src/9/pc/vga.c - 664 sys sys 1039753497 4963
+1039753664 53 c sys/src/9/port/devdraw.c - 664 sys sys 1039753332 41987
+1039753664 54 c sys/src/9/port/devroot.c - 664 sys sys 1039753332 3593
+1039753664 55 c sys/src/9/port/mkdevc - 775 sys sys 1039753333 4054
+1039753664 56 c sys/src/9/port/mkdevlist - 775 sys sys 1039753333 700
+1039753664 57 c sys/src/9/port/mkextract - 775 sys sys 1039753334 435
+1039753664 58 c sys/src/9/port/mkroot - 775 sys sys 1039753334 235
+1039753664 59 c sys/src/9/port/portfns.h - 664 sys sys 1039753334 10472
+1039753664 60 c sys/src/9/port/portmkfile - 664 sys sys 1039753335 2372
+1039753664 61 a sys/src/9/port/initcode.c - 664 sys sys 1039753332 446
+1039753664 62 c sys/src/cmd/crop.c - 664 sys sys 1039753034 4136
+1039753664 63 c sys/src/cmd/fax/mkfile - 664 sys sys 1039753042 535
+1039753664 64 c sys/src/cmd/iconv.c - 664 sys sys 1039753035 1801
+1039753664 65 c sys/src/cmd/postscript/p9bitpost/pslib.c - 664 sys sys 1039753066 23150
+1039753664 66 c sys/src/cmd/vnc/devdraw.c - 664 sys sys 1039753056 42068
+1039753664 67 c sys/src/cmd/vnc/screen.c - 664 sys sys 1039753059 7424
+1039753664 68 c sys/src/cmd/vnc/vncs.c - 664 sys sys 1039753062 20594
+1039753664 69 c sys/src/cmd/jpg/multichan.c - 664 sys sys 1039753047 825
+1039753664 70 c sys/src/cmd/jpg/onechan.c - 664 sys sys 1039753044 3732
+1039753664 71 c sys/src/cmd/jpg/writepng.c - 664 sys sys 1039753051 4261
+1039753664 72 c sys/src/cmd/resample.c - 664 sys sys 1039753039 6268
+1039753664 73 c sys/src/cmd/vl/l.h - 664 sys sys 1039753053 5434
+1039753664 74 c sys/src/libmemdraw/alloc.c - 664 sys sys 1039752932 3152
+1039753664 75 c sys/src/libmemdraw/arc.c - 664 sys sys 1039752932 2608
+1039753664 76 c sys/src/libmemdraw/draw.c - 664 sys sys 1039752933 55250
+1039753664 77 c sys/src/libmemdraw/ellipse.c - 664 sys sys 1039752933 4866
+1039753664 78 c sys/src/libmemdraw/fillpoly.c - 664 sys sys 1039752933 9841
+1039753664 79 c sys/src/libmemdraw/line.c - 664 sys sys 1039752934 11041
+1039753664 80 c sys/src/libmemdraw/openmemsubfont.c - 664 sys sys 1039752934 900
+1039753664 81 c sys/src/libmemdraw/poly.c - 664 sys sys 1039752935 484
+1039753664 82 c sys/src/libmemdraw/string.c - 664 sys sys 1039752935 1054
+1039753664 83 c sys/src/libmemlayer/draw.c - 664 sys sys 1039752978 3947
+1039753664 84 c sys/src/libmemlayer/lalloc.c - 664 sys sys 1039752979 1760
+1039753664 85 c sys/src/libmemlayer/layerop.c - 664 sys sys 1039752979 2641
+1039753664 86 c sys/src/libmemlayer/ldelete.c - 664 sys sys 1039752979 1183
+1039753664 87 c sys/src/libmemlayer/lhide.c - 664 sys sys 1039752980 1693
+1039753664 88 c sys/src/libmemlayer/line.c - 664 sys sys 1039752980 2587
+1039753664 89 c sys/src/libmemlayer/load.c - 664 sys sys 1039752980 1032
+1039753664 90 c sys/src/libmemlayer/lorigin.c - 664 sys sys 1039752981 2507
+1039753664 91 c sys/src/libmemlayer/mkfile - 664 sys sys 1039752977 365
+1039753664 92 c sys/src/libmemlayer/unload.c - 664 sys sys 1039752981 1007
+1039753808 0 c sys/src/libc/fmt/dofmt.c - 664 sys sys 1039753802 8626
+1039754031 0 a sys/src/9/port/mkbootrules - 775 sys sys 1039754026 344
+1039758686 0 c 386/9pc - 775 sys sys 1039758620 1783164
+1039758686 1 c 386/9pccpu - 775 sys sys 1039758622 1429682
+1039758686 2 c 386/9pcdisk - 775 sys sys 1039758625 1987069
+1039758686 3 c 386/bin/8a - 775 sys sys 1039758526 113387
+1039758686 4 c 386/bin/8c - 775 sys sys 1039758527 298665
+1039758686 5 c 386/bin/8l - 775 sys sys 1039758527 107971
+1039758686 6 c 386/bin/9660srv - 775 sys sys 1039758527 105203
+1039758686 7 c 386/bin/aan - 775 sys sys 1039758528 127563
+1039758686 8 c 386/bin/acid - 775 sys sys 1039758528 377948
+1039758686 9 c 386/bin/acme - 775 sys sys 1039758529 413667
+1039758686 10 c 386/bin/ar - 775 sys sys 1039758530 113119
+1039758686 11 c 386/bin/archfs - 775 sys sys 1039758530 139484
+1039758686 12 c 386/bin/ascii - 775 sys sys 1039758530 63264
+1039758686 13 c 386/bin/astro - 775 sys sys 1039758530 139263
+1039758686 14 c 386/bin/basename - 775 sys sys 1039758547 38375
+1039758686 15 c 386/bin/bc - 775 sys sys 1039758548 80389
+1039758686 16 c 386/bin/bind - 775 sys sys 1039758548 58302
+1039758686 17 c 386/bin/bitsy/bitsyload - 775 sys sys 1039758548 62104
+1039758686 18 c 386/bin/bitsy/keyboard - 775 sys sys 1039758549 298691
+1039758686 19 c 386/bin/bitsy/params - 775 sys sys 1039758549 57274
+1039758686 20 c 386/bin/bitsy/pencal - 775 sys sys 1039758549 114495
+1039758686 21 c 386/bin/bitsy/prompter - 775 sys sys 1039758549 280856
+1039758686 22 c 386/bin/bunzip2 - 775 sys sys 1039758550 96083
+1039758686 23 c 386/bin/bzip2 - 775 sys sys 1039758550 112667
+1039758686 24 c 386/bin/cal - 775 sys sys 1039758550 66676
+1039758686 25 c 386/bin/calendar - 775 sys sys 1039758550 78193
+1039758686 26 c 386/bin/cat - 775 sys sys 1039758550 37944
+1039758686 27 c 386/bin/cdfs - 775 sys sys 1039758551 159924
+1039758686 28 c 386/bin/cfs - 775 sys sys 1039758551 129125
+1039758686 29 c 386/bin/chgrp - 775 sys sys 1039758551 58493
+1039758686 30 c 386/bin/chmod - 775 sys sys 1039758551 61736
+1039758686 31 c 386/bin/cleanname - 775 sys sys 1039758551 56650
+1039758686 32 c 386/bin/clock - 775 sys sys 1039758552 152556
+1039758686 33 c 386/bin/cmp - 775 sys sys 1039758552 41134
+1039758686 34 c 386/bin/colors - 775 sys sys 1039758552 145870
+1039758686 35 c 386/bin/comm - 775 sys sys 1039758552 60001
+1039758686 36 c 386/bin/con - 775 sys sys 1039758552 76698
+1039758686 37 c 386/bin/cp - 775 sys sys 1039758553 62687
+1039758686 38 c 386/bin/cpp - 775 sys sys 1039758553 148353
+1039758686 39 c 386/bin/cpu - 775 sys sys 1039758553 137158
+1039758686 40 c 386/bin/crop - 775 sys sys 1039758553 115496
+1039758686 41 c 386/bin/date - 775 sys sys 1039758553 43976
+1039758686 42 c 386/bin/db - 775 sys sys 1039758554 323623
+1039758686 43 c 386/bin/dc - 775 sys sys 1039758554 97868
+1039758686 44 c 386/bin/dd - 775 sys sys 1039758554 46046
+1039758686 45 c 386/bin/deroff - 775 sys sys 1039758555 73199
+1039758686 46 c 386/bin/dict - 775 sys sys 1039758555 168316
+1039758686 47 c 386/bin/diff - 775 sys sys 1039758555 82259
+1039758686 48 c 386/bin/dossrv - 775 sys sys 1039758558 139838
+1039758686 49 c 386/bin/du - 775 sys sys 1039758558 63064
+1039758686 50 c 386/bin/echo - 775 sys sys 1039758558 55830
+1039758686 51 c 386/bin/ed - 775 sys sys 1039758558 92160
+1039758686 52 c 386/bin/exportfs - 775 sys sys 1039758559 145630
+1039758686 53 c 386/bin/faces - 775 sys sys 1039758559 187144
+1039758686 54 c 386/bin/factor - 775 sys sys 1039758559 60135
+1039758686 55 c 386/bin/fs/32vfs - 775 sys sys 1039758560 96155
+1039758686 56 c 386/bin/fs/cpiofs - 775 sys sys 1039758560 94985
+1039758686 57 c 386/bin/fs/tapfs - 775 sys sys 1039758561 97453
+1039758686 58 c 386/bin/fs/tarfs - 775 sys sys 1039758561 95839
+1039758686 59 c 386/bin/fs/tpfs - 775 sys sys 1039758561 94691
+1039758686 60 c 386/bin/fs/v10fs - 775 sys sys 1039758561 96202
+1039758686 61 c 386/bin/fs/v6fs - 775 sys sys 1039758562 96121
+1039758686 62 c 386/bin/getmap - 775 sys sys 1039758562 63678
+1039758686 63 c 386/bin/gunzip - 775 sys sys 1039758563 79918
+1039758686 64 c 386/bin/gzip - 775 sys sys 1039758563 84015
+1039758686 65 c 386/bin/hget - 775 sys sys 1039758563 101403
+1039758686 66 c 386/bin/history - 775 sys sys 1039758564 71183
+1039758686 67 c 386/bin/htmlfmt - 775 sys sys 1039758564 158912
+1039758686 68 c 386/bin/iconv - 775 sys sys 1039758564 112738
+1039758686 69 c 386/bin/idiff - 775 sys sys 1039758565 75492
+1039758686 70 c 386/bin/lnfs - 775 sys sys 1039758574 100756
+1039758686 71 c 386/bin/nntpfs - 775 sys sys 1039758580 159773
+1039758686 72 c 386/bin/pipefile - 775 sys sys 1039758581 39893
+1039758686 73 c 386/bin/png - 775 sys sys 1039758582 157728
+1039758686 74 c 386/bin/replica/applychanges - 775 sys sys 1039758585 99044
+1039758686 75 c 386/bin/replica/applylog - 775 sys sys 1039758585 98429
+1039758686 76 c 386/bin/replica/compactdb - 775 sys sys 1039758586 77913
+1039758686 77 c 386/bin/replica/updatedb - 775 sys sys 1039758586 95939
+1039758686 78 c 386/bin/resample - 775 sys sys 1039758586 120283
+1039758686 79 c 386/bin/rtstats - 775 sys sys 1039758587 174824
+1039758686 80 c 386/bin/sha1sum - 775 sys sys 1039758589 59581
+1039758686 81 c 386/bin/snap - 775 sys sys 1039758590 288721
+1039758686 82 c 386/bin/snapfs - 775 sys sys 1039758591 357433
+1039758686 83 c 386/bin/srvold9p - 775 sys sys 1039758592 130502
+1039758686 84 c 386/bin/topng - 775 sys sys 1039758597 137880
+1039758686 85 c 386/bin/troff2html - 775 sys sys 1039758598 81032
+1039758686 86 c 386/bin/unzip - 775 sys sys 1039758599 90042
+1039758686 87 c 386/bin/usb/usbaudio - 775 sys sys 1039758606 173005
+1039758686 88 c 386/bin/usb/usbd - 775 sys sys 1039758606 121266
+1039758686 89 c 386/bin/usb/usbmouse - 775 sys sys 1039758606 136659
+1039758686 90 c 386/bin/venti/buildindex - 775 sys sys 1039758608 178668
+1039758686 91 c 386/bin/venti/checkarenas - 775 sys sys 1039758608 181667
+1039758686 92 c 386/bin/venti/checkindex - 775 sys sys 1039758608 179486
+1039758686 93 c 386/bin/venti/clumpstats - 775 sys sys 1039758609 168683
+1039758686 94 a 386/bin/venti/copy - 775 sys sys 1039758609 106664
+1039758686 95 c 386/bin/venti/findscore - 775 sys sys 1039758609 153272
+1039758686 96 c 386/bin/venti/fmtarenas - 775 sys sys 1039758609 154075
+1039758686 97 c 386/bin/venti/fmtindex - 775 sys sys 1039758610 168346
+1039758686 98 c 386/bin/venti/fmtisect - 775 sys sys 1039758610 168930
+1039758686 99 c 386/bin/venti/rdarena - 775 sys sys 1039758610 153014
+1039758686 100 c 386/bin/venti/read - 775 sys sys 1039758611 103030
+1039758686 101 c 386/bin/venti/sync - 775 sys sys 1039758611 102180
+1039758686 102 c 386/bin/venti/syncindex - 775 sys sys 1039758611 193823
+1039758686 103 c 386/bin/venti/venti - 775 sys sys 1039758612 248414
+1039758686 104 c 386/bin/venti/verifyarena - 775 sys sys 1039758612 127738
+1039758686 105 c 386/bin/venti/wrarena - 775 sys sys 1039758612 181345
+1039758686 106 c 386/bin/venti/write - 775 sys sys 1039758613 102982
+1039758686 107 c 386/bin/vncs - 775 sys sys 1039758613 440826
+1039758686 108 c 386/bin/vncv - 775 sys sys 1039758614 174057
+1039758686 109 c 386/bin/webcookies - 775 sys sys 1039758615 159686
+1039758686 110 c 386/bin/wikifs - 775 sys sys 1039758616 194294
+1039758686 111 c 386/bin/zip - 775 sys sys 1039758617 89314
+1039758686 112 c 386/bin/file - 775 sys sys 1039758559 117145
+1039758686 113 c 386/bin/fmt - 775 sys sys 1039758560 63811
+1039758686 114 c 386/bin/fortune - 775 sys sys 1039758560 66329
+1039758686 115 c 386/bin/freq - 775 sys sys 1039758560 60443
+1039758686 116 c 386/bin/ftpfs - 775 sys sys 1039758562 148301
+1039758686 117 c 386/bin/gif - 775 sys sys 1039758562 155652
+1039758686 118 c 386/bin/graph - 775 sys sys 1039758563 127337
+1039758686 119 c 386/bin/grep - 775 sys sys 1039758563 77890
+1039758686 120 c 386/bin/hayes - 775 sys sys 1039758563 63552
+1039758686 121 c 386/bin/hoc - 775 sys sys 1039758564 98955
+1039758686 122 c 386/bin/html2ms - 775 sys sys 1039758564 64730
+1039758686 123 c 386/bin/import - 775 sys sys 1039758565 87315
+1039758686 124 c 386/bin/iostats - 775 sys sys 1039758565 98800
+1039758686 125 c 386/bin/join - 775 sys sys 1039758572 114412
+1039758686 126 c 386/bin/jpg - 775 sys sys 1039758573 172380
+1039758686 127 c 386/bin/kprof - 775 sys sys 1039758573 101896
+1039758686 128 c 386/bin/ktrace - 775 sys sys 1039758573 115126
+1039758686 129 c 386/bin/lens - 775 sys sys 1039758573 122362
+1039758686 130 c 386/bin/lex - 775 sys sys 1039758573 97530
+1039758686 131 c 386/bin/look - 775 sys sys 1039758574 64460
+1039758686 132 c 386/bin/ls - 775 sys sys 1039758574 78970
+1039758686 133 c 386/bin/mc - 775 sys sys 1039758574 128609
+1039758686 134 c 386/bin/md5sum - 775 sys sys 1039758574 59713
+1039758686 135 c 386/bin/mk - 775 sys sys 1039758575 141369
+1039758686 136 c 386/bin/mkdir - 775 sys sys 1039758575 57836
+1039758686 137 c 386/bin/mount - 775 sys sys 1039758576 71032
+1039758686 138 c 386/bin/ms2html - 775 sys sys 1039758576 100101
+1039758686 139 c 386/bin/mv - 775 sys sys 1039758576 64993
+1039758686 140 c 386/bin/netkey - 775 sys sys 1039758579 70753
+1039758686 141 c 386/bin/netstat - 775 sys sys 1039758579 81376
+1039758686 142 c 386/bin/news - 775 sys sys 1039758579 70506
+1039758686 143 c 386/bin/nm - 775 sys sys 1039758580 123224
+1039758686 144 c 386/bin/ns - 775 sys sys 1039758580 63830
+1039758686 145 c 386/bin/p - 775 sys sys 1039758580 63746
+1039758686 146 c 386/bin/page - 775 sys sys 1039758581 214018
+1039758686 147 c 386/bin/passwd - 775 sys sys 1039758581 81058
+1039758686 148 c 386/bin/pcc - 775 sys sys 1039758581 66189
+1039758686 149 c 386/bin/plot - 775 sys sys 1039758582 216945
+1039758686 150 c 386/bin/plumb - 775 sys sys 1039758582 65473
+1039758686 151 c 386/bin/plumber - 775 sys sys 1039758582 169206
+1039758686 152 c 386/bin/ppm - 775 sys sys 1039758583 146744
+1039758686 153 c 386/bin/pr - 775 sys sys 1039758583 76437
+1039758686 154 c 386/bin/primes - 775 sys sys 1039758583 39290
+1039758686 155 c 386/bin/prof - 775 sys sys 1039758583 106372
+1039758686 156 c 386/bin/proof - 775 sys sys 1039758584 173099
+1039758686 157 c 386/bin/ps - 775 sys sys 1039758584 64633
+1039758686 158 c 386/bin/pwd - 775 sys sys 1039758584 37188
+1039758686 159 c 386/bin/ramfs - 775 sys sys 1039758584 89906
+1039758686 160 c 386/bin/rc - 775 sys sys 1039758584 139862
+1039758686 161 c 386/bin/rdbfs - 775 sys sys 1039758585 166622
+1039758686 162 c 386/bin/read - 775 sys sys 1039758585 56544
+1039758686 163 c 386/bin/rio - 775 sys sys 1039758587 300600
+1039758686 164 c 386/bin/rm - 775 sys sys 1039758587 60033
+1039758686 165 c 386/bin/rx - 775 sys sys 1039758587 78434
+1039758686 166 c 386/bin/sam - 775 sys sys 1039758588 156892
+1039758686 167 c 386/bin/scat - 775 sys sys 1039758588 277448
+1039758686 168 c 386/bin/scp - 775 sys sys 1039758589 159535
+1039758686 169 c 386/bin/scuzz - 775 sys sys 1039758589 110998
+1039758686 170 c 386/bin/sed - 775 sys sys 1039758589 88430
+1039758686 171 c 386/bin/seq - 775 sys sys 1039758589 38817
+1039758686 172 c 386/bin/size - 775 sys sys 1039758589 76292
+1039758686 173 c 386/bin/snoopy - 775 sys sys 1039758591 152394
+1039758686 174 c 386/bin/sort - 775 sys sys 1039758591 81296
+1039758686 175 c 386/bin/split - 775 sys sys 1039758591 74227
+1039758686 176 c 386/bin/srv - 775 sys sys 1039758591 80150
+1039758686 177 c 386/bin/srvfs - 775 sys sys 1039758592 39914
+1039758686 178 c 386/bin/ssh - 775 sys sys 1039758592 209655
+1039758686 179 c 386/bin/stats - 775 sys sys 1039758593 184849
+1039758686 180 c 386/bin/strings - 775 sys sys 1039758593 60879
+1039758686 181 c 386/bin/strip - 775 sys sys 1039758593 60826
+1039758686 182 c 386/bin/sum - 775 sys sys 1039758593 40355
+1039758686 183 c 386/bin/swap - 775 sys sys 1039758594 60844
+1039758686 184 c 386/bin/vtdump - 775 sys sys 1039758615 163138
+1039758686 185 c 386/bin/webfs - 775 sys sys 1039758616 342496
+1039758686 186 c 386/bin/winwatch - 775 sys sys 1039758616 139473
+1039758686 187 c 386/bin/ape/cc - 775 sys sys 1039758529 68927
+1039758686 188 c 386/bin/ape/stty - 775 sys sys 1039758529 41577
+1039758686 189 c 386/bin/ape/tar - 775 sys sys 1039758529 60413
+1039758686 190 c 386/bin/auth/aescbc - 775 sys sys 1039758531 120944
+1039758686 191 c 386/bin/auth/authsrv - 775 sys sys 1039758531 162132
+1039758686 192 c 386/bin/auth/changeuser - 775 sys sys 1039758531 96022
+1039758686 193 c 386/bin/auth/convkeys - 775 sys sys 1039758531 84013
+1039758686 194 c 386/bin/auth/convkeys2 - 775 sys sys 1039758532 84033
+1039758686 195 c 386/bin/auth/cron - 775 sys sys 1039758532 139996
+1039758686 196 c 386/bin/auth/debug - 775 sys sys 1039758532 100413
+1039758686 197 c 386/bin/auth/factotum - 775 sys sys 1039758533 300772
+1039758686 198 c 386/bin/auth/fgui - 775 sys sys 1039758533 210904
+1039758686 199 c 386/bin/auth/guard.srv - 775 sys sys 1039758533 139814
+1039758686 200 c 386/bin/auth/iam - 775 sys sys 1039758534 51077
+1039758686 201 c 386/bin/auth/keyfs - 775 sys sys 1039758534 114307
+1039758686 202 c 386/bin/auth/login - 775 sys sys 1039758534 99385
+1039758686 203 c 386/bin/auth/printnetkey - 775 sys sys 1039758534 40969
+1039758686 204 c 386/bin/auth/secretpem - 775 sys sys 1039758534 118523
+1039758686 205 c 386/bin/auth/secstore - 775 sys sys 1039758535 178992
+1039758686 206 c 386/bin/auth/secstored - 775 sys sys 1039758535 192870
+1039758686 207 c 386/bin/auth/secuser - 775 sys sys 1039758535 149280
+1039758686 208 c 386/bin/auth/uniq - 775 sys sys 1039758536 61773
+1039758686 209 c 386/bin/auth/warning - 775 sys sys 1039758536 97723
+1039758686 210 c 386/bin/auth/wrkey - 775 sys sys 1039758536 71296
+1039758686 211 c 386/bin/aux/9pcon - 775 sys sys 1039758536 96151
+1039758686 212 c 386/bin/aux/LOCK - 775 sys sys 1039758536 58689
+1039758686 213 c 386/bin/aux/X509gen - 775 sys sys 1039758537 126402
+1039758686 214 c 386/bin/aux/accupoint - 775 sys sys 1039758537 41111
+1039758686 215 c 386/bin/aux/acidleak - 775 sys sys 1039758537 67904
+1039758686 216 c 386/bin/aux/apm - 775 sys sys 1039758537 171807
+1039758686 217 c 386/bin/aux/astarld - 775 sys sys 1039758537 63522
+1039758686 218 c 386/bin/aux/cddb - 775 sys sys 1039758537 70432
+1039758686 219 c 386/bin/aux/clog - 775 sys sys 1039758538 65408
+1039758686 220 c 386/bin/aux/consolefs - 775 sys sys 1039758538 152994
+1039758686 221 c 386/bin/aux/data2s - 775 sys sys 1039758538 59178
+1039758686 222 c 386/bin/aux/depend - 775 sys sys 1039758538 145132
+1039758686 223 c 386/bin/aux/disksim - 775 sys sys 1039758539 142703
+1039758686 224 c 386/bin/aux/faxreceive - 775 sys sys 1039758539 83418
+1039758686 225 c 386/bin/aux/faxsend - 775 sys sys 1039758539 88816
+1039758686 226 c 386/bin/aux/flashfs - 775 sys sys 1039758539 158578
+1039758686 227 c 386/bin/aux/g3p9bit - 775 sys sys 1039758539 65837
+1039758686 228 c 386/bin/aux/getflags - 775 sys sys 1039758540 44343
+1039758686 229 c 386/bin/aux/lines - 775 sys sys 1039758540 59152
+1039758686 230 c 386/bin/aux/listen - 775 sys sys 1039758540 104208
+1039758686 231 c 386/bin/aux/listen1 - 775 sys sys 1039758540 91094
+1039758686 232 c 386/bin/aux/lpsend - 775 sys sys 1039758540 53107
+1039758686 233 c 386/bin/aux/mapd - 775 sys sys 1039758541 190944
+1039758686 234 c 386/bin/aux/mkflashfs - 775 sys sys 1039758541 66240
+1039758686 235 c 386/bin/aux/mklatinkbd - 775 sys sys 1039758541 62863
+1039758686 236 c 386/bin/aux/mnihongo - 775 sys sys 1039758541 134897
+1039758686 237 c 386/bin/aux/mouse - 775 sys sys 1039758541 44473
+1039758686 238 c 386/bin/aux/ms2 - 775 sys sys 1039758542 84047
+1039758686 239 c 386/bin/aux/mswordstrings - 775 sys sys 1039758542 64268
+1039758686 240 c 386/bin/aux/na - 775 sys sys 1039758542 152747
+1039758686 241 c 386/bin/aux/nfsserver - 775 sys sys 1039758542 171424
+1039758686 242 c 386/bin/aux/olefs - 775 sys sys 1039758543 142400
+1039758686 243 c 386/bin/aux/p9bitpost - 775 sys sys 1039758543 127979
+1039758686 244 c 386/bin/aux/pcmcia - 775 sys sys 1039758543 46790
+1039758686 245 c 386/bin/aux/pcnfsd - 775 sys sys 1039758543 127219
+1039758686 246 c 386/bin/aux/portmapper - 775 sys sys 1039758544 126116
+1039758686 247 c 386/bin/aux/rdwr - 775 sys sys 1039758544 38800
+1039758686 248 c 386/bin/aux/reboot - 775 sys sys 1039758544 59049
+1039758686 249 c 386/bin/aux/samterm - 775 sys sys 1039758544 242240
+1039758686 250 c 386/bin/aux/searchfs - 775 sys sys 1039758545 90974
+1039758686 251 c 386/bin/aux/sprog - 775 sys sys 1039758545 77768
+1039758686 252 c 386/bin/aux/ssh_genkey - 775 sys sys 1039758545 194580
+1039758686 253 c 386/bin/aux/sshserve - 775 sys sys 1039758546 246497
+1039758686 254 c 386/bin/aux/stub - 775 sys sys 1039758546 133120
+1039758686 255 c 386/bin/aux/text2post - 775 sys sys 1039758546 77253
+1039758686 256 c 386/bin/aux/timesync - 775 sys sys 1039758546 125710
+1039758686 257 c 386/bin/aux/tr2post - 775 sys sys 1039758547 175495
+1039758686 258 c 386/bin/aux/trampoline - 775 sys sys 1039758547 81154
+1039758686 259 c 386/bin/aux/typepasswd - 775 sys sys 1039758547 68151
+1039758686 260 c 386/bin/aux/vga - 775 sys sys 1039758547 299452
+1039758686 261 c 386/bin/disk/dump9660 - 775 sys sys 1039758555 151486
+1039758686 262 c 386/bin/disk/exsort - 775 sys sys 1039758556 58789
+1039758686 263 c 386/bin/disk/fdisk - 775 sys sys 1039758556 106823
+1039758686 264 c 386/bin/disk/format - 775 sys sys 1039758556 91866
+1039758686 265 c 386/bin/disk/kfs - 775 sys sys 1039758556 247140
+1039758686 266 c 386/bin/disk/kfscmd - 775 sys sys 1039758557 38719
+1039758686 267 c 386/bin/disk/mbr - 775 sys sys 1039758557 72334
+1039758686 268 c 386/bin/disk/mkext - 775 sys sys 1039758557 77815
+1039758686 269 c 386/bin/disk/mkfs - 775 sys sys 1039758557 87444
+1039758686 270 c 386/bin/disk/prep - 775 sys sys 1039758557 98783
+1039758686 271 c 386/bin/execnet - 775 sys sys 1039758558 168262
+1039758686 272 c 386/bin/ip/dhcpclient - 775 sys sys 1039758565 91652
+1039758686 273 c 386/bin/ip/dhcpd - 775 sys sys 1039758566 144971
+1039758686 274 c 386/bin/ip/dhcpleases - 775 sys sys 1039758566 84655
+1039758686 275 c 386/bin/ip/ftpd - 775 sys sys 1039758566 166832
+1039758686 276 c 386/bin/ip/gping - 775 sys sys 1039758567 178125
+1039758686 277 c 386/bin/ip/hogports - 775 sys sys 1039758567 43296
+1039758686 278 c 386/bin/ip/httpd/httpd - 775 sys sys 1039758567 283575
+1039758686 279 c 386/bin/ip/httpd/imagemap - 775 sys sys 1039758568 113595
+1039758686 280 c 386/bin/ip/httpd/man2html - 775 sys sys 1039758568 121860
+1039758686 281 c 386/bin/ip/httpd/save - 775 sys sys 1039758568 130924
+1039758686 282 c 386/bin/ip/httpd/wikipost - 775 sys sys 1039758568 111282
+1039758686 283 c 386/bin/ip/imap4d - 775 sys sys 1039758569 232588
+1039758686 284 c 386/bin/ip/ipconfig - 775 sys sys 1039758569 103748
+1039758686 285 c 386/bin/ip/ping - 775 sys sys 1039758569 74005
+1039758686 286 c 386/bin/ip/ppp - 775 sys sys 1039758570 211448
+1039758686 287 c 386/bin/ip/pppoe - 775 sys sys 1039758570 75475
+1039758686 288 c 386/bin/ip/pptp - 775 sys sys 1039758570 122528
+1039758686 289 c 386/bin/ip/pptpd - 775 sys sys 1039758570 123584
+1039758686 290 c 386/bin/ip/rarpd - 775 sys sys 1039758571 107218
+1039758686 291 c 386/bin/ip/rexexec - 775 sys sys 1039758571 86656
+1039758686 292 c 386/bin/ip/rip - 775 sys sys 1039758571 89757
+1039758686 293 c 386/bin/ip/rlogind - 775 sys sys 1039758571 66384
+1039758686 294 c 386/bin/ip/telnetd - 775 sys sys 1039758571 120147
+1039758686 295 c 386/bin/ip/tftpd - 775 sys sys 1039758572 102536
+1039758686 296 c 386/bin/ip/traceroute - 775 sys sys 1039758572 70850
+1039758686 297 c 386/bin/ip/udpecho - 775 sys sys 1039758572 43540
+1039758686 298 c 386/bin/mkpaqfs - 775 sys sys 1039758575 93491
+1039758686 299 c 386/bin/mkstate - 775 sys sys 1039758575 62173
+1039758686 300 c 386/bin/mntgen - 775 sys sys 1039758575 133926
+1039758686 301 c 386/bin/mtime - 775 sys sys 1039758576 57875
+1039758686 302 c 386/bin/ndb/cs - 775 sys sys 1039758576 143184
+1039758686 303 c 386/bin/ndb/csquery - 775 sys sys 1039758577 60136
+1039758686 304 c 386/bin/ndb/dns - 775 sys sys 1039758577 210800
+1039758686 305 c 386/bin/ndb/dnsdebug - 775 sys sys 1039758577 185793
+1039758686 306 c 386/bin/ndb/dnsquery - 775 sys sys 1039758578 62442
+1039758686 307 c 386/bin/ndb/dnstcp - 775 sys sys 1039758578 184617
+1039758686 308 c 386/bin/ndb/ipquery - 775 sys sys 1039758578 91675
+1039758686 309 c 386/bin/ndb/mkdb - 775 sys sys 1039758578 62632
+1039758686 310 c 386/bin/ndb/mkhash - 775 sys sys 1039758578 82288
+1039758686 311 c 386/bin/ndb/mkhosts - 775 sys sys 1039758579 83235
+1039758686 312 c 386/bin/ndb/query - 775 sys sys 1039758579 81033
+1039758686 313 c 386/bin/paqfs - 775 sys sys 1039758581 108073
+1039758686 314 c 386/bin/sshnet - 775 sys sys 1039758593 281010
+1039758686 315 c 386/bin/syscall - 775 sys sys 1039758594 72631
+1039758686 316 c 386/bin/tail - 775 sys sys 1039758594 64882
+1039758686 317 c 386/bin/tar - 775 sys sys 1039758594 81322
+1039758686 318 c 386/bin/tbl - 775 sys sys 1039758594 111800
+1039758686 319 c 386/bin/tcs - 775 sys sys 1039758595 278428
+1039758686 320 c 386/bin/tee - 775 sys sys 1039758595 38926
+1039758686 321 c 386/bin/telco - 775 sys sys 1039758595 105055
+1039758686 322 c 386/bin/telnet - 775 sys sys 1039758595 80800
+1039758686 323 c 386/bin/test - 775 sys sys 1039758595 63910
+1039758686 324 c 386/bin/time - 775 sys sys 1039758596 59810
+1039758686 325 c 386/bin/tlsclient - 775 sys sys 1039758596 191851
+1039758686 326 c 386/bin/tlssrv - 775 sys sys 1039758596 192216
+1039758686 327 c 386/bin/togif - 775 sys sys 1039758597 188561
+1039758686 328 c 386/bin/toppm - 775 sys sys 1039758597 163998
+1039758686 329 c 386/bin/touch - 775 sys sys 1039758597 63209
+1039758686 330 c 386/bin/tprof - 775 sys sys 1039758598 273463
+1039758686 331 c 386/bin/tr - 775 sys sys 1039758598 60540
+1039758686 332 c 386/bin/tweak - 775 sys sys 1039758598 188803
+1039758686 333 c 386/bin/unicode - 775 sys sys 1039758599 61093
+1039758686 334 c 386/bin/uniq - 775 sys sys 1039758599 60560
+1039758686 335 c 386/bin/units - 775 sys sys 1039758599 73879
+1039758686 336 c 386/bin/unmount - 775 sys sys 1039758599 37108
+1039758686 337 c 386/bin/upas/aliasmail - 775 sys sys 1039758599 100876
+1039758686 338 c 386/bin/upas/deliver - 775 sys sys 1039758599 68805
+1039758686 339 c 386/bin/upas/filter - 775 sys sys 1039758600 145556
+1039758686 340 c 386/bin/upas/fs - 775 sys sys 1039758600 326172
+1039758686 341 c 386/bin/upas/list - 775 sys sys 1039758601 81422
+1039758686 342 c 386/bin/upas/marshal - 775 sys sys 1039758601 126720
+1039758686 343 c 386/bin/upas/ml - 775 sys sys 1039758601 118090
+1039758686 344 c 386/bin/upas/mlmgr - 775 sys sys 1039758601 100861
+1039758686 345 c 386/bin/upas/mlowner - 775 sys sys 1039758602 92131
+1039758686 346 c 386/bin/upas/nedmail - 775 sys sys 1039758602 147378
+1039758686 347 c 386/bin/upas/pop3 - 775 sys sys 1039758602 251568
+1039758686 348 c 386/bin/upas/qer - 775 sys sys 1039758603 98517
+1039758686 349 c 386/bin/upas/ratfs - 775 sys sys 1039758603 112389
+1039758686 350 c 386/bin/upas/runq - 775 sys sys 1039758603 111302
+1039758686 351 c 386/bin/upas/scanmail - 775 sys sys 1039758603 126508
+1039758686 352 c 386/bin/upas/send - 775 sys sys 1039758604 188619
+1039758686 353 c 386/bin/upas/smtp - 775 sys sys 1039758604 264699
+1039758686 354 c 386/bin/upas/smtpd - 775 sys sys 1039758605 199198
+1039758686 355 c 386/bin/upas/testscan - 775 sys sys 1039758605 82381
+1039758686 356 c 386/bin/upas/token - 775 sys sys 1039758605 76178
+1039758686 357 c 386/bin/upas/vf - 775 sys sys 1039758605 90529
+1039758686 358 c 386/bin/vac - 775 sys sys 1039758607 173522
+1039758686 359 c 386/bin/vacfs - 775 sys sys 1039758607 179723
+1039758686 360 c 386/bin/vt - 775 sys sys 1039758614 169349
+1039758686 361 c 386/bin/wc - 775 sys sys 1039758615 42416
+1039758686 362 c 386/bin/xd - 775 sys sys 1039758616 62802
+1039758686 363 c 386/bin/xmr - 775 sys sys 1039758616 40652
+1039758686 364 c 386/bin/xms - 775 sys sys 1039758617 41233
+1039758686 365 c 386/bin/yacc - 775 sys sys 1039758617 100850
+1039758686 366 c 386/lib/libc.a - 664 sys sys 1039758626 496612
+1039758686 367 c 386/lib/libcontrol.a - 664 sys sys 1039758627 243294
+1039758686 368 c 386/lib/libdraw.a - 664 sys sys 1039758627 360966
+1039758686 369 c 386/lib/libframe.a - 664 sys sys 1039758628 65832
+1039758686 370 c 386/lib/libgeometry.a - 664 sys sys 1039758628 50806
+1039758686 371 c 386/lib/libhtml.a - 664 sys sys 1039758628 220944
+1039758686 372 c 386/lib/libmemdraw.a - 664 sys sys 1039758629 292324
+1039758686 373 c 386/lib/libmemlayer.a - 664 sys sys 1039758629 47116
+1039758686 374 c 386/lib/libplumb.a - 664 sys sys 1039758629 19000
+1039758686 375 c 386/lib/libscribble.a - 664 sys sys 1039758629 108138
+1039761098 0 c sys/man/2/print - 664 sys sys 1039759892 8890
+1039762899 0 c 386/init - 775 sys sys 1039762724 97616
+1039763807 0 c 386/9pcdisk - 775 sys sys 1039763781 1966876
+1039763807 1 c 386/9pcdisk.gz - 664 sys sys 1039763783 695837
+1039763807 2 c sys/src/9/boot/bootauth.c - 664 sys sys 1039763726 1097
+1039763807 3 c sys/src/9/boot/bootcache.c - 664 sys sys 1039763729 1518
+1039763807 4 c sys/src/9/boot/bootip.c - 664 sys sys 1039763724 3383
+1039763807 5 c sys/src/9/boot/embed.c - 664 sys sys 1039763720 1191
+1039763807 6 c sys/src/9/boot/local.c - 664 sys sys 1039763718 2041
+1039763807 7 c sys/src/9/boot/paq.c - 664 sys sys 1039763722 1099
+1039763807 8 a sys/src/9/boot/testboot.c - 664 sys sys 1039763734 496
+1039764701 0 a 386/_9pcdisk.gz - 664 sys sys 1039764191 695837
+1039764701 1 c sys/src/9/pc/pcdisk - 664 sys sys 1039764711 1369
+1039764868 0 c 386/9pc - 775 sys sys 1039764767 1783420
+1039764868 1 c 386/9pc.gz - 664 sys sys 1039764768 614091
+1039764868 2 c 386/9pccpu - 775 sys sys 1039764770 1429714
+1039764868 3 c 386/9pccpu.gz - 664 sys sys 1039764771 498997
+1039764868 4 c 386/9pcdisk - 775 sys sys 1039764751 1987341
+1039764868 5 c 386/9pcdisk.gz - 664 sys sys 1039764747 703133
+1039766123 0 c 386/9pcdisk - 775 sys sys 1039766107 1987341
+1039766123 1 c 386/9pcdisk.gz - 664 sys sys 1039766104 703132
+1039768304 0 c sys/src/cmd/vnc/kbd_vwr.c - 664 sys sys 1039767358 2361

+ 2 - 0
sys/include/draw.h

@@ -102,6 +102,8 @@ enum
 	DoverS	= DinS|DoutS|SoutD,
 	DoverS	= DinS|DoutS|SoutD,
 	DatopS	= DinS|SoutD,
 	DatopS	= DinS|SoutD,
 	DxorS	= DoutS|SoutD,	/* == SxorD */
 	DxorS	= DoutS|SoutD,	/* == SxorD */
+
+	Ncomp = 12,
 };
 };
 
 
 /*
 /*

+ 11 - 10
sys/include/memdraw.h

@@ -100,6 +100,7 @@ struct	Memdrawparam
 	Rectangle sr;
 	Rectangle sr;
 	Memimage *mask;
 	Memimage *mask;
 	Rectangle mr;
 	Rectangle mr;
+	int op;
 
 
 	ulong state;
 	ulong state;
 	ulong mval;	/* if Simplemask, the mask pixel in mask format */
 	ulong mval;	/* if Simplemask, the mask pixel in mask format */
@@ -131,18 +132,18 @@ extern int		memsetchan(Memimage*, ulong);
 /*
 /*
  * Graphics
  * Graphics
  */
  */
-extern void	memdraw(Memimage*, Rectangle, Memimage*, Point, Memimage*, Point);
-extern void	memline(Memimage*, Point, Point, int, int, int, Memimage*, Point);
-extern void	mempoly(Memimage*, Point*, int, int, int, int, Memimage*, Point);
-extern void	memfillpoly(Memimage*, Point*, int, int, Memimage*, Point);
-extern void	_memfillpolysc(Memimage*, Point*, int, int, Memimage*, Point, int, int, int);
-extern void	memimagedraw(Memimage*, Rectangle, Memimage*, Point, Memimage*, Point);
+extern void	memdraw(Memimage*, Rectangle, Memimage*, Point, Memimage*, Point, int);
+extern void	memline(Memimage*, Point, Point, int, int, int, Memimage*, Point, int);
+extern void	mempoly(Memimage*, Point*, int, int, int, int, Memimage*, Point, int);
+extern void	memfillpoly(Memimage*, Point*, int, int, Memimage*, Point, int);
+extern void	_memfillpolysc(Memimage*, Point*, int, int, Memimage*, Point, int, int, int, int);
+extern void	memimagedraw(Memimage*, Rectangle, Memimage*, Point, Memimage*, Point, int);
 extern int	hwdraw(Memdrawparam*);
 extern int	hwdraw(Memdrawparam*);
-extern void	memimageline(Memimage*, Point, Point, int, int, int, Memimage*, Point);
-extern void	_memimageline(Memimage*, Point, Point, int, int, int, Memimage*, Point, Rectangle);
+extern void	memimageline(Memimage*, Point, Point, int, int, int, Memimage*, Point, int);
+extern void	_memimageline(Memimage*, Point, Point, int, int, int, Memimage*, Point, Rectangle, int);
 extern Point	memimagestring(Memimage*, Point, Memimage*, Point, Memsubfont*, char*);
 extern Point	memimagestring(Memimage*, Point, Memimage*, Point, Memsubfont*, char*);
-extern void	memellipse(Memimage*, Point, int, int, int, Memimage*, Point);
-extern void	memarc(Memimage*, Point, int, int, int, Memimage*, Point, int, int);
+extern void	memellipse(Memimage*, Point, int, int, int, Memimage*, Point, int);
+extern void	memarc(Memimage*, Point, int, int, int, Memimage*, Point, int, int, int);
 extern Rectangle	memlinebbox(Point, Point, int, int, int);
 extern Rectangle	memlinebbox(Point, Point, int, int, int);
 extern int	memlineendsize(int);
 extern int	memlineendsize(int);
 extern void	_memmkcmap(void);
 extern void	_memmkcmap(void);

+ 7 - 1
sys/man/2/print

@@ -328,7 +328,7 @@ conversions, trailing zeros are not removed.
 .PP
 .PP
 The
 The
 .B s
 .B s
-verb copies a string
+verb copies a nul-terminated string
 (pointer to
 (pointer to
 .BR char )
 .BR char )
 to the output.
 to the output.
@@ -342,6 +342,12 @@ These
 characters are justified within a field of
 characters are justified within a field of
 .I width
 .I width
 characters as described above.
 characters as described above.
+If a
+.I precision
+is given, it is safe for the string not to be nul-terminated
+as long as it is at least
+.I precision
+characters (not bytes!) long.
 The
 The
 .B S
 .B S
 verb is similar, but it interprets its pointer as an array
 verb is similar, but it interprets its pointer as an array

+ 52 - 6
sys/man/8/ventiaux

@@ -3,6 +3,7 @@
 buildindex,
 buildindex,
 checkarenas,
 checkarenas,
 checkindex,
 checkindex,
+copy,
 fmtarenas,
 fmtarenas,
 fmtindex,
 fmtindex,
 fmtisect,
 fmtisect,
@@ -40,6 +41,17 @@ write \- Venti maintenance and debugging commands
 .I venti.config
 .I venti.config
 .I tmp
 .I tmp
 .PP
 .PP
+.B venti/copy
+[
+.B -f
+]
+.I src
+.I dst
+.I score
+[
+.I type
+]
+.PP
 .B venti/fmtarenas
 .B venti/fmtarenas
 [
 [
 .B -Z
 .B -Z
@@ -83,11 +95,10 @@ write \- Venti maintenance and debugging commands
 .B -h
 .B -h
 .I host
 .I host
 ]
 ]
+.I score
 [
 [
-.B -t
 .I type
 .I type
 ]
 ]
-.I score
 .PP
 .PP
 .B venti/wrarena
 .B venti/wrarena
 [
 [
@@ -391,9 +402,7 @@ of which arenas have been processed.)
 .I Read
 .I Read
 and
 and
 .I write
 .I write
-interact with a running
-Venti
-server rather than access the data directly.
+read and write blocks from a running Venti server.
 They are intended to ease debugging of the server.
 They are intended to ease debugging of the server.
 The default
 The default
 .I host
 .I host
@@ -403,7 +412,20 @@ followed by the network metaname
 .BR $venti .
 .BR $venti .
 The
 The
 .I type
 .I type
-sets the block type to read or write; it is a decimal number.
+is the decimal type of block to be read or written.
+If no 
+.I type
+is specified for
+.I read ,
+all types are tried, and a command-line is printed to
+show the type that eventually worked.
+If no
+.I type
+is specified for
+.I write ,
+.B VtDataType
+(13)
+is used.
 .I Read
 .I Read
 reads the block named by
 reads the block named by
 .I score
 .I score
@@ -413,6 +435,30 @@ from the Venti server and writes it to standard output.
 reads a block from standard input and attempts to write
 reads a block from standard input and attempts to write
 it to the Venti server.
 it to the Venti server.
 If successful, it prints the score of the block on the server.
 If successful, it prints the score of the block on the server.
+.PP
+.I Copy
+walks the entire tree of blocks rooted at
+.I score ,
+copying all the blocks visited during the walk from
+the Venti server at network address
+.I src
+to the Venti server at network address
+.I dst .
+If
+.I type
+(a decimal block type for
+.IR score )
+is omitted, all types will be tried in sequence
+until one is found that works.
+The
+.B -f
+flag runs the copy in ``fast'' mode: if a block is already on
+.IR dst ,
+the walk does not descend below it, on the assumption that all its
+children are also already on
+.IR dst .
+Without this flag, the copy often transfers many times more
+data than necessary.
 .SH SOURCE
 .SH SOURCE
 .B /sys/src/cmd/venti
 .B /sys/src/cmd/venti
 .SH "SEE ALSO"
 .SH "SEE ALSO"

+ 6 - 4
sys/src/9/alphapc/apc

@@ -35,10 +35,6 @@ link
 misc
 misc
 	arch164
 	arch164
 
 
-	ipconfig.root
-	kfs.root
-	factotum.root
-
 	sdata		pci sdscsi
 	sdata		pci sdscsi
 	sd53c8xx	pci sdscsi
 	sd53c8xx	pci sdscsi
 
 
@@ -62,3 +58,9 @@ port
 
 
 boot
 boot
 	il
 	il
+
+bootdir
+	bootapc.out boot
+	/alpha/bin/disk/kfs
+	factotum.hack factotum
+	ipconfig.hack ipconfig

+ 6 - 3
sys/src/9/alphapc/apccpu

@@ -31,9 +31,6 @@ link
 misc
 misc
 	arch164
 	arch164
 
 
-	ipconfig.root
-	factotum.root
-
 	sdata		pci sdscsi
 	sdata		pci sdscsi
 	sd53c8xx	pci sdscsi
 	sd53c8xx	pci sdscsi
 
 
@@ -54,3 +51,9 @@ port
 
 
 boot cpu
 boot cpu
 	il
 	il
+
+bootdir
+	bootapccpu.out boot
+	ipconfig.hack ipconfig
+	factotum.hack factotum
+

+ 40 - 4
sys/src/9/alphapc/devarch.c

@@ -401,13 +401,49 @@ PCArch archgeneric = {
 
 
 static char	*sysnames[] =
 static char	*sysnames[] =
 {
 {
-// [26]		"EB164",
-[26]		"AlphaPC 164",
+[1]		"Alpha Demo. Unit",
+[2]		"DEC 4000; Cobra",
+[3]		"DEC 7000; Ruby",
+[4]		"DEC 3000/500; Flamingo family (TC)",
+[6]		"DEC 2000/300; Jensen (EISA/ISA)",
+[7]		"DEC 3000/300; Pelican (TC)",
+[8]		"Avalon A12; Avalon Multicomputer",
+[9]		"DEC 2100/A500; Sable",
+[10]		"DEC APXVME/64; AXPvme (VME?)",
+[11]		"DEC AXPPCI/33; NoName (PCI/ISA)",
+[12]		"DEC 21000; TurboLaser (PCI/EISA)",
+[13]		"DEC 2100/A50; Avanti (PCI/ISA)",
+[14]		"DEC MUSTANG; Mustang",
+[15]		"DEC KN20AA; kn20aa (PCI/EISA)",
+[17]		"DEC 1000; Mikasa (PCI/ISA?)",
+[19]		"EB66; EB66 (PCI/ISA?)",		// DEC?
+[20]		"EB64P; EB64+ (PCI/ISA?)",		// DEC?
+[21]		"Alphabook1; Alphabook",
+[22]		"DEC 4100; Rawhide (PCI/EISA)",
+[23]		"DEC EV45/PBP; Lego",
+[24]		"DEC 2100A/A500; Lynx",
+[26]		"DEC AlphaPC 164",	// only supported one: "EB164 (PCI/ISA)"
+[27]		"DEC 1000A; Noritake",
+[28]		"DEC AlphaVME/224; Cortex",
+[30]		"DEC 550; Miata (PCI/ISA)",
+[32]		"DEC EV56/PBP; Takara",
+[33]		"DEC AlphaVME/320; Yukon (VME?)",
+[34]		"DEC 6600; MonetGoldrush",
+// 200 and up is Alpha Processor Inc. machines
+// [201]	"API UP1000; Nautilus",
 };
 };
 
 
 static char	*cpunames[] =
 static char	*cpunames[] =
 {
 {
-[7]		"21164A",
+[1]		"EV3",
+[2]		"EV4: 21064",
+[3]		"Simulation",
+[4]		"LCA4: 2106[68]",
+[5]		"EV5: 21164",
+[6]		"EV45: 21064A",
+[7]		"21164A",		/* only supported one: EV56 */
+[8]		"EV6: 21264",
+[9]		"PCA256: 21164PC",
 };
 };
 
 
 void
 void
@@ -430,7 +466,7 @@ cpuidprint(void)
 		s = "<unknown>";
 		s = "<unknown>";
 		if (hwrpb->systype < nelem(sysnames))
 		if (hwrpb->systype < nelem(sysnames))
 			s = sysnames[hwrpb->systype];
 			s = sysnames[hwrpb->systype];
-		print("DEC %s (%llux, %llux, %llux)\n", s, hwrpb->systype, hwrpb->sysvar, hwrpb->sysrev);
+		print("%s (%llux, %llux, %llux)\n", s, hwrpb->systype, hwrpb->sysvar, hwrpb->sysrev);
 	}
 	}
 
 
 	for (i = 0; i < hwrpb->ncpu; i++) {
 	for (i = 0; i < hwrpb->ncpu; i++) {

+ 57 - 19
sys/src/9/alphapc/devether.c

@@ -10,7 +10,7 @@
 
 
 #include "etherif.h"
 #include "etherif.h"
 
 
-static Ether *etherxx[MaxEther];
+static volatile Ether *etherxx[MaxEther];
 
 
 Chan*
 Chan*
 etherattach(char* spec)
 etherattach(char* spec)
@@ -176,7 +176,8 @@ etheriq(Ether* ether, Block* bp, int fromwire)
 				else if(xbp = iallocb(len)){
 				else if(xbp = iallocb(len)){
 					memmove(xbp->wp, pkt, len);
 					memmove(xbp->wp, pkt, len);
 					xbp->wp += len;
 					xbp->wp += len;
-					qpass(f->in, xbp);
+					if(qpass(f->in, xbp) < 0)
+						ether->soverflows++;
 				}
 				}
 				else
 				else
 					ether->soverflows++;
 					ether->soverflows++;
@@ -239,21 +240,26 @@ etherwrite(Chan* chan, void* buf, long n, vlong)
 {
 {
 	Ether *ether;
 	Ether *ether;
 	Block *bp;
 	Block *bp;
+	int nn;
 
 
 	ether = etherxx[chan->dev];
 	ether = etherxx[chan->dev];
-	if(NETTYPE(chan->qid.path) != Ndataqid){
-
+	if(NETTYPE(chan->qid.path) != Ndataqid) {
+		nn = netifwrite(ether, chan, buf, n);
+		if(nn >= 0)
+			return nn;
 		if(n == sizeof("nonblocking")-1 && strncmp((char*)buf, "nonblocking", n) == 0){
 		if(n == sizeof("nonblocking")-1 && strncmp((char*)buf, "nonblocking", n) == 0){
 			qnoblock(ether->oq, 1);
 			qnoblock(ether->oq, 1);
 			return n;
 			return n;
 		}
 		}
+		if(ether->ctl!=nil)
+			return ether->ctl(ether,buf,n);
 
 
-		return netifwrite(ether, chan, buf, n);
+		error(Ebadctl);
 	}
 	}
 
 
-	if(n > ETHERMAXTU)
+	if(n > ether->maxmtu)
 		error(Etoobig);
 		error(Etoobig);
-	if(n < ETHERMINTU)
+	if(n < ether->minmtu)
 		error(Etoosmall);
 		error(Etoosmall);
 
 
 	bp = allocb(n);
 	bp = allocb(n);
@@ -276,18 +282,23 @@ etherbwrite(Chan* chan, Block* bp, ulong)
 	long n;
 	long n;
 
 
 	n = BLEN(bp);
 	n = BLEN(bp);
-	ether = etherxx[chan->dev];
 	if(NETTYPE(chan->qid.path) != Ndataqid){
 	if(NETTYPE(chan->qid.path) != Ndataqid){
-		n = netifwrite(ether, chan, bp->rp, n);
+		if(waserror()) {
+			freeb(bp);
+			nexterror();
+		}
+		n = etherwrite(chan, bp->rp, n, 0);
+		poperror();
 		freeb(bp);
 		freeb(bp);
 		return n;
 		return n;
 	}
 	}
+	ether = etherxx[chan->dev];
 
 
-	if(n > ETHERMAXTU){
+	if(n > ether->maxmtu){
 		freeb(bp);
 		freeb(bp);
-		error(Ebadarg);
+		error(Etoobig);
 	}
 	}
-	if(n < ETHERMINTU){
+	if(n < ether->minmtu){
 		freeb(bp);
 		freeb(bp);
 		error(Etoosmall);
 		error(Etoosmall);
 	}
 	}
@@ -320,7 +331,7 @@ parseether(uchar *to, char *from)
 	int i;
 	int i;
 
 
 	p = from;
 	p = from;
-	for(i = 0; i < 6; i++){
+	for(i = 0; i < Eaddrlen; i++){
 		if(*p == 0)
 		if(*p == 0)
 			return -1;
 			return -1;
 		nip[0] = *p++;
 		nip[0] = *p++;
@@ -340,7 +351,7 @@ etherreset(void)
 {
 {
 	Ether *ether;
 	Ether *ether;
 	int i, n, ctlrno;
 	int i, n, ctlrno;
-	char name[32], buf[128];
+	char name[32], buf[256];
 
 
 	for(ether = 0, ctlrno = 0; ctlrno < MaxEther; ctlrno++){
 	for(ether = 0, ctlrno = 0; ctlrno < MaxEther; ctlrno++){
 		if(ether == 0)
 		if(ether == 0)
@@ -359,9 +370,9 @@ etherreset(void)
 			for(i = 0; i < ether->nopt; i++){
 			for(i = 0; i < ether->nopt; i++){
 				if(strncmp(ether->opt[i], "ea=", 3))
 				if(strncmp(ether->opt[i], "ea=", 3))
 					continue;
 					continue;
-				if(parseether(ether->ea, &ether->opt[i][3]) == -1)
+				if(parseether(ether->ea, &ether->opt[i][3]))
 					memset(ether->ea, 0, Eaddrlen);
 					memset(ether->ea, 0, Eaddrlen);
-			}	
+			}
 			if(cards[n].reset(ether))
 			if(cards[n].reset(ether))
 				break;
 				break;
 
 
@@ -373,10 +384,17 @@ etherreset(void)
 			if(ether->irq == 2 && BUSTYPE(ether->tbdf) != BusPCI)
 			if(ether->irq == 2 && BUSTYPE(ether->tbdf) != BusPCI)
 				ether->irq = 9;
 				ether->irq = 9;
 			snprint(name, sizeof(name), "ether%d", ctlrno);
 			snprint(name, sizeof(name), "ether%d", ctlrno);
-			intrenable(ether->irq, ether->interrupt, ether, ether->tbdf, name);
+			/*
+			 * If ether->irq is 0, it is a hack to indicate no
+			 * interrupt used by ethersink.
+			 */
+			if(ether->irq > 0)
+				intrenable(ether->irq, ether->interrupt,
+					ether, ether->tbdf, name);
 
 
-			i = sprint(buf, "#l%d: %s: %dMbps port 0x%luX irq %lud",
-				ctlrno, ether->type, ether->mbps, ether->port, ether->irq);
+			i = sprint(buf, "#l%d (%s): %s: %dMbps port 0x%luX irq %lud",
+				ctlrno, name, ether->type, ether->mbps,
+				ether->port, ether->irq);
 			if(ether->mem)
 			if(ether->mem)
 				i += sprint(buf+i, " addr 0x%luX", PADDR(ether->mem));
 				i += sprint(buf+i, " addr 0x%luX", PADDR(ether->mem));
 			if(ether->size)
 			if(ether->size)
@@ -412,6 +430,26 @@ etherreset(void)
 		free(ether);
 		free(ether);
 }
 }
 
 
+/* imported from ../pc; not ready for use yet */
+static void
+ethershutdown(void)
+{
+	Ether *ether;
+	int i;
+
+	for(i = 0; i < MaxEther; i++){
+		ether = etherxx[i];
+		if(ether == nil)
+			continue;
+		if(ether->shutdown == nil) {
+			print("#l%d: no shutdown fuction\n", i);
+			continue;
+		}
+		(*ether->shutdown)(ether);
+	}
+}
+
+
 #define POLY 0xedb88320
 #define POLY 0xedb88320
 
 
 /* really slow 32 bit crc for ethers */
 /* really slow 32 bit crc for ethers */

+ 6 - 0
sys/src/9/alphapc/etherif.h

@@ -15,10 +15,15 @@ struct Ether {
 	uchar	ea[Eaddrlen];
 	uchar	ea[Eaddrlen];
 
 
 	void	(*attach)(Ether*);	/* filled in by reset routine */
 	void	(*attach)(Ether*);	/* filled in by reset routine */
+	void	(*detach)(Ether*);	/* NEW, from ../pc */
 	void	(*transmit)(Ether*);
 	void	(*transmit)(Ether*);
 	void	(*interrupt)(Ureg*, void*);
 	void	(*interrupt)(Ureg*, void*);
 	long	(*ifstat)(Ether*, void*, long, ulong);
 	long	(*ifstat)(Ether*, void*, long, ulong);
 	long 	(*ctl)(Ether*, void*, long); /* custom ctl messages */
 	long 	(*ctl)(Ether*, void*, long); /* custom ctl messages */
+/* START NEW, from ../pc */
+	void	(*power)(Ether*, int);	/* power on/off */
+	void	(*shutdown)(Ether*);	/* shutdown hardware before reboot */
+/* END NEW */
 	void	*ctlr;
 	void	*ctlr;
 
 
 	Queue*	oq;
 	Queue*	oq;
@@ -29,6 +34,7 @@ struct Ether {
 extern Block* etheriq(Ether*, Block*, int);
 extern Block* etheriq(Ether*, Block*, int);
 extern void addethercard(char*, int(*)(Ether*));
 extern void addethercard(char*, int(*)(Ether*));
 extern ulong ethercrc(uchar*, int);
 extern ulong ethercrc(uchar*, int);
+extern int parseether(uchar*, char*);
 
 
 #define NEXT(x, l)	(((x)+1)%(l))
 #define NEXT(x, l)	(((x)+1)%(l))
 #define PREV(x, l)	(((x) == 0) ? (l)-1: (x)-1)
 #define PREV(x, l)	(((x) == 0) ? (l)-1: (x)-1)

+ 3 - 2
sys/src/9/alphapc/initcode

@@ -41,6 +41,7 @@ TEXT	exec(SB), $0
 	RET
 	RET
 
 
 DATA	boot+0(SB)/5,$"/boot"
 DATA	boot+0(SB)/5,$"/boot"
-DATA	bootv+0(SB)/4,$boot+1(SB)
-GLOBL	boot+0(SB),$6
+DATA	boot+5(SB)/5,$"/boot"
+DATA	bootv+0(SB)/4,$boot+6(SB)
+GLOBL	boot+0(SB),$11
 GLOBL	bootv+0(SB),$8
 GLOBL	bootv+0(SB),$8

+ 151 - 14
sys/src/9/alphapc/main.c

@@ -32,6 +32,7 @@ options(void)
 	cp = bootargs;
 	cp = bootargs;
 	strncpy(cp, bootconf->bootargs, BOOTARGSLEN);
 	strncpy(cp, bootconf->bootargs, BOOTARGSLEN);
 	cp[BOOTARGSLEN-1] = 0;
 	cp[BOOTARGSLEN-1] = 0;
+	/* can't print in this routine, see below in main() */
 
 
 	/*
 	/*
 	 * Strip out '\r', change '\t' -> ' '.
 	 * Strip out '\r', change '\t' -> ' '.
@@ -60,6 +61,18 @@ options(void)
 	}
 	}
 }
 }
 
 
+/* debugging only */
+static void
+dumpopts(void)
+{
+	int i;
+
+	print("dumpopts: found /alpha/conf options at 0x%lux\n",
+		bootconf->bootargs);
+	for(i = 0; i < nconf; i++)
+		print("dumpopts: read %s=%s\n", confname[i], confval[i]);
+}
+
 void
 void
 main(void)
 main(void)
 {
 {
@@ -80,6 +93,8 @@ main(void)
 	trapinit();
 	trapinit();
 	screeninit();
 	screeninit();
 	printinit();
 	printinit();
+	/* it's now safe to print */
+	/* dumpopts();			/* DEBUG */
 	kbdinit();
 	kbdinit();
 	i8250console();
 	i8250console();
 	quotefmtinstall();
 	quotefmtinstall();
@@ -102,6 +117,26 @@ initfp.fpstatus = 0x68028000;
 	schedinit();
 	schedinit();
 }
 }
 
 
+/* cpu->state bits */
+enum {
+	Cpubootinprog	= 1,	/* boot in progress */
+	Cpucanrestart	= 2,	/* restart possible */
+	Cpuavail	= 4,	/* processor available */
+	Cpuexists 	= 8,	/* processor present */
+	Cpuuserhalted	= 0x10,	/* user halted */
+	Cpuctxtokay	= 0x20,	/* context valid */
+	Cpupalokay	= 0x40,	/* PALcode valid */
+	Cpupalmemokay	= 0x80,	/* PALcode memory valid */
+	Cpupalloaded	= 0x100, /* PALcode loaded */
+	Cpuhaltmask	= 0xff0000, /* halt request mask */
+	Cpuhaltdflt	= 0,
+	Cpuhaltsaveexit = 0x10000,
+	Cpuhaltcoldboot = 0x20000,
+	Cpuhaltwarmboot = 0x30000,
+	Cpuhaltstayhalted = 0x40000,
+	Cpumustbezero = 0xffffffffff000000,	/* 24:63 -- must be zero */
+};
+
 /*
 /*
  *  initialize a processor's mach structure.  each processor does this
  *  initialize a processor's mach structure.  each processor does this
  *  for itself.
  *  for itself.
@@ -121,15 +156,16 @@ machinit(void)
 	active.machs = 1;
 	active.machs = 1;
 
 
 	cpu = (Hwcpu*) ((ulong)hwrpb + hwrpb->cpuoff + n*hwrpb->cpulen);
 	cpu = (Hwcpu*) ((ulong)hwrpb + hwrpb->cpuoff + n*hwrpb->cpulen);
-	cpu->state &= ~1;			/* boot in progress - not */
-/*	cpu->state |= (4<<16);		/* stay halted */
+	cpu->state &= ~Cpubootinprog;
+	if (0)
+		cpu->state |= Cpuhaltstayhalted;
 }
 }
 
 
 void
 void
 init0(void)
 init0(void)
 {
 {
 	int i;
 	int i;
-	char tstr[32];
+	char buf[2*KNAMELEN];
 
 
 	up->nerrlab = 0;
 	up->nerrlab = 0;
 
 
@@ -147,9 +183,9 @@ init0(void)
 	chandevinit();
 	chandevinit();
 
 
 	if(!waserror()){
 	if(!waserror()){
+		snprint(buf, sizeof(buf), "alpha %s alphapc", conffile);
+		ksetenv("terminal", buf, 0);
 		ksetenv("cputype", "alpha", 0);
 		ksetenv("cputype", "alpha", 0);
-		sprint(tstr, "alpha %s alphapc", conffile);
-		ksetenv("terminal", tstr, 0);
 		if(cpuserver)
 		if(cpuserver)
 			ksetenv("service", "cpu", 0);
 			ksetenv("service", "cpu", 0);
 		else
 		else
@@ -254,15 +290,104 @@ procsave(Proc *p)
 	mmupark();
 	mmupark();
 }
 }
 
 
-/* still to do */
 void
 void
-reboot(void*, void*, ulong)
+setupboot(int halt)
 {
 {
+	int n = 0;		// cpu id of primary cpu, not just m->machno
+	Hwcpu *cpu = (Hwcpu*)((ulong)hwrpb + hwrpb->cpuoff + n*hwrpb->cpulen);
+
+	cpu->state &= ~(Cpucanrestart | Cpuhaltmask);
+	cpu->state |= (halt? Cpuhaltstayhalted: Cpuhaltwarmboot);
+}
+
+/* from ../pc */
+static void
+shutdown(int ispanic)
+{
+	int ms, once;
+
+	lock(&active);
+	if(ispanic)
+		active.ispanic = ispanic;
+	else if(m->machno == 0 && (active.machs & (1<<m->machno)) == 0)
+		active.ispanic = 0;
+	once = active.machs & (1<<m->machno);
+	active.machs &= ~(1<<m->machno);
+	active.exiting = 1;
+	unlock(&active);
+
+	if(once)
+		print("cpu%d: exiting\n", m->machno);
+	spllo();
+	for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
+		delay(TK2MS(2));
+		if(active.machs == 0 && consactive() == 0)
+			break;
+	}
+
+	if(active.ispanic && m->machno == 0) {
+		if(cpuserver)
+			delay(10000);
+		else
+			for (;;)
+				continue;
+	} else
+		delay(1000);
+}
+
+/* from ../pc: */
+void
+reboot(void *entry, void *code, ulong size)
+{
+	// writeconf();		// pass kernel environment to next kernel
+	shutdown(0);
+
+	/*
+	 * should be the only processor running now
+	 */
+	print("shutting down...\n");
+	delay(200);
+
+	splhi();
+
+	/* turn off buffered serial console */
+	serialoq = nil;
+
+	/* shutdown devices */
+	chandevshutdown();
+
+#ifdef FUTURE
+{
+	ulong *pdb;
+	/*
+	 * Modify the machine page table to directly map the low 4MB of memory
+	 * This allows the reboot code to turn off the page mapping
+	 */
+	pdb = m->pdb;
+	pdb[PDX(0)] = pdb[PDX(KZERO)];
+	mmuflushtlb(PADDR(pdb));
+}
+	/* setup reboot trampoline function */
+{
+	void (*f)(ulong, ulong, ulong) = (void*)REBOOTADDR;
+
+	memmove(f, rebootcode, sizeof(rebootcode));
+#else
+	USED(entry, code, size);
+#endif
+
+	print("rebooting...\n");
+#ifdef FUTURE
+	/* off we go - never to return */
+	(*f)(PADDR(entry), PADDR(code), size);
+}
+#endif
+	setupboot(0);		// reboot, don't halt
 	exit(0);
 	exit(0);
 }
 }
 
 
 void
 void
-exit(int)
+exit(int ispanic)
 {
 {
 	canlock(&active);
 	canlock(&active);
 	active.machs &= ~(1<<m->machno);
 	active.machs &= ~(1<<m->machno);
@@ -277,9 +402,21 @@ exit(int)
 
 
 	splhi();
 	splhi();
 	delay(1000);	/* give serial fifo time to finish flushing */
 	delay(1000);	/* give serial fifo time to finish flushing */
+	if (getconf("*debug") != nil) {
+		USED(ispanic);
+		delay(60*1000);		/* give us time to read the screen */
+	}
 	if(arch->coredetach)
 	if(arch->coredetach)
 		arch->coredetach();
 		arch->coredetach();
-	firmware();
+	setupboot(1);			// set up to halt
+	for (; ; )
+		firmware();
+
+	// on PC is just:
+	if (0) {
+		shutdown(ispanic);
+		// arch->reset();
+	}
 }
 }
 
 
 void
 void
@@ -414,7 +551,7 @@ void
 memholes(void)
 memholes(void)
 {
 {
 	Bank *b, *eb;
 	Bank *b, *eb;
-	
+
 	b = bootconf->bank;
 	b = bootconf->bank;
 	eb = b+bootconf->nbank;
 	eb = b+bootconf->nbank;
 	while(b < eb) {
 	while(b < eb) {
@@ -453,10 +590,10 @@ getconf(char *name)
 {
 {
 	int n;
 	int n;
 
 
-	for(n = 0; n < nconf; n++){
-		if(cistrcmp(confname[n], name) == 0)
+	for(n = 0; n < nconf; n++)
+		if(cistrcmp(confname[n], name) == 0) {
 			return confval[n];
 			return confval[n];
-	}
+		}
 	return 0;
 	return 0;
 }
 }
 
 
@@ -501,7 +638,7 @@ cistrcmp(char *a, char *b)
 	for(;;){
 	for(;;){
 		ac = *a++;
 		ac = *a++;
 		bc = *b++;
 		bc = *b++;
-	
+
 		if(ac >= 'A' && ac <= 'Z')
 		if(ac >= 'A' && ac <= 'Z')
 			ac = 'a' + (ac - 'A');
 			ac = 'a' + (ac - 'A');
 		if(bc >= 'A' && bc <= 'Z')
 		if(bc >= 'A' && bc <= 'Z')

+ 2 - 1
sys/src/9/alphapc/mkfile

@@ -52,7 +52,6 @@ OBJ=\
 	trap.$O\
 	trap.$O\
 	$DEVS\
 	$DEVS\
 	$PORT\
 	$PORT\
-	boot$CONF.root.$O\
 
 
 LIB=\
 LIB=\
 	/$objtype/lib/libmemlayer.a\
 	/$objtype/lib/libmemlayer.a\
@@ -77,6 +76,7 @@ install:V: $p$CONF
 
 
 <../boot/bootmkfile
 <../boot/bootmkfile
 <../port/portmkfile
 <../port/portmkfile
+<|../port/mkbootrules $CONF
 
 
 init.h:	initcode /sys/src/libc/9syscall/sys.h
 init.h:	initcode /sys/src/libc/9syscall/sys.h
 	$AS initcode
 	$AS initcode
@@ -96,6 +96,7 @@ sd53c8xx.i:	../pc/sd53c8xx.n
 devfloppy.$O:	../pc/devfloppy.c
 devfloppy.$O:	../pc/devfloppy.c
 ether2114x.$O:	../pc/ether2114x.c
 ether2114x.$O:	../pc/ether2114x.c
 mouse.$O:	../pc/mouse.c
 mouse.$O:	../pc/mouse.c
+screen.$O:	../pc/screen.c
 sdata.$O:	../pc/sdata.c
 sdata.$O:	../pc/sdata.c
 sdscsi.$O:	../pc/sdscsi.c
 sdscsi.$O:	../pc/sdscsi.c
 uarti8250.$O:	../pc/uarti8250.c
 uarti8250.$O:	../pc/uarti8250.c

+ 4 - 5
sys/src/9/alphapc/pci.c

@@ -197,15 +197,14 @@ pciscan(int bno, Pcidev** list)
 static void
 static void
 pcicfginit(void)
 pcicfginit(void)
 {
 {
-/*	char *p; */
+	char *p;
 
 
 	lock(&pcicfginitlock);
 	lock(&pcicfginitlock);
 	if(pcicfgmode == -1){
 	if(pcicfgmode == -1){
 		pcicfgmode = 0;
 		pcicfgmode = 0;
-/*		if(p = getconf("*pcimaxdno"))
-			pcimaxdno = strtoul(p, 0, 0); */
-pcimaxdno = 15 /* was 20; what is correct value??? */;
-
+		pcimaxdno = 15;		/* was 20; what is correct value??? */
+		if(p = getconf("*pcimaxdno"))
+			pcimaxdno = strtoul(p, 0, 0);
 		pciscan(0, &pciroot);
 		pciscan(0, &pciroot);
 	}
 	}
 	unlock(&pcicfginitlock);
 	unlock(&pcicfginitlock);

+ 1 - 138
sys/src/9/alphapc/random.c

@@ -1,138 +1 @@
-#include	"u.h"
-#include	"../port/lib.h"
-#include	"mem.h"
-#include	"dat.h"
-#include	"fns.h"
-#include	"../port/error.h"
-
-
-struct Rb
-{
-	QLock;
-	Rendez	producer;
-	Rendez	consumer;
-	ulong	randomcount;
-	uchar	buf[1024];
-	uchar	*ep;
-	uchar	*rp;
-	uchar	*wp;
-	uchar	next;
-	uchar	wakeme;
-	ushort	bits;
-	ulong	randn;
-} rb;
-
-static int
-rbnotfull(void*)
-{
-	int i;
-
-	i = rb.rp - rb.wp;
-	return i != 1 && i != (1 - sizeof(rb.buf));
-}
-
-static int
-rbnotempty(void*)
-{
-	return rb.wp != rb.rp;
-}
-
-void
-genrandom(void*)
-{
-	up->basepri = PriNormal;
-	up->priority = up->basepri;
-
-	for(;;){
-		for(;;)
-			if(++rb.randomcount > 100000)
-				break;
-		if(anyhigher())
-			sched();
-		if(!rbnotfull(0))
-			sleep(&rb.producer, rbnotfull, 0);
-	}
-}
-
-/*
- *  produce random bits in a circular buffer
- */
-static void
-randomclock(void)
-{
-	if(rb.randomcount == 0 || !rbnotfull(0))
-		return;
-
-	rb.bits = (rb.bits<<2) ^ rb.randomcount;
-	rb.randomcount = 0;
-
-	rb.next++;
-	if(rb.next != 8/2)
-		return;
-	rb.next = 0;
-
-	*rb.wp ^= rb.bits;
-	if(rb.wp+1 == rb.ep)
-		rb.wp = rb.buf;
-	else
-		rb.wp = rb.wp+1;
-
-	if(rb.wakeme)
-		wakeup(&rb.consumer);
-}
-
-void
-randominit(void)
-{
-	addclock0link(randomclock, 1000/HZ);
-	rb.ep = rb.buf + sizeof(rb.buf);
-	rb.rp = rb.wp = rb.buf;
-	kproc("genrandom", genrandom, 0);
-}
-
-/*
- *  consume random bytes from a circular buffer
- */
-ulong
-randomread(void *xp, ulong n)
-{
-	uchar *e, *p;
-	ulong x;
-
-	p = xp;
-
-	if(waserror()){
-		qunlock(&rb);
-		nexterror();
-	}
-
-	qlock(&rb);
-	for(e = p + n; p < e; ){
-		if(rb.wp == rb.rp){
-			rb.wakeme = 1;
-			wakeup(&rb.producer);
-			sleep(&rb.consumer, rbnotempty, 0);
-			rb.wakeme = 0;
-			continue;
-		}
-
-		/*
-		 *  beating clocks will be precictable if
-		 *  they are synchronized.  Use a cheap pseudo
-		 *  random number generator to obscure any cycles.
-		 */
-		x = rb.randn*1103515245 ^ *rb.rp;
-		*p++ = rb.randn = x;
-
-		if(rb.rp+1 == rb.ep)
-			rb.rp = rb.buf;
-		else
-			rb.rp = rb.rp+1;
-	}
-	qunlock(&rb);
-	poperror();
-
-	wakeup(&rb.producer);
-
-	return n;
-}
+#include "../pc/random.c"

+ 1 - 532
sys/src/9/alphapc/screen.c

@@ -1,532 +1 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "ureg.h"
-#include "../port/error.h"
-
-#define	Image	IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-#define RGB2K(r,g,b)	((156763*(r)+307758*(g)+59769*(b))>>19)
-
-Point ZP = {0, 0};
-
-Rectangle physgscreenr;
-
-Memdata gscreendata;
-Memimage *gscreen;
-
-VGAscr vgascreen[1];
-
-Cursor	arrow = {
-	{ -1, -1 },
-	{ 0xFF, 0xFF, 0x80, 0x01, 0x80, 0x02, 0x80, 0x0C, 
-	  0x80, 0x10, 0x80, 0x10, 0x80, 0x08, 0x80, 0x04, 
-	  0x80, 0x02, 0x80, 0x01, 0x80, 0x02, 0x8C, 0x04, 
-	  0x92, 0x08, 0x91, 0x10, 0xA0, 0xA0, 0xC0, 0x40, 
-	},
-	{ 0x00, 0x00, 0x7F, 0xFE, 0x7F, 0xFC, 0x7F, 0xF0, 
-	  0x7F, 0xE0, 0x7F, 0xE0, 0x7F, 0xF0, 0x7F, 0xF8, 
-	  0x7F, 0xFC, 0x7F, 0xFE, 0x7F, 0xFC, 0x73, 0xF8, 
-	  0x61, 0xF0, 0x60, 0xE0, 0x40, 0x40, 0x00, 0x00, 
-	},
-};
-
-int
-screensize(int x, int y, int z, ulong chan)
-{
-	VGAscr *scr;
-
-	memimageinit();
-	scr = &vgascreen[0];
-
-	/*
-	 * BUG: need to check if any xalloc'ed memory needs to
-	 * be given back if aperture is set.
-	 */
-	if(scr->aperture == 0){
-		int width = (x*z)/BI2WD;
-
-		gscreendata.bdata = xalloc(width*BY2WD*y);
-		if(gscreendata.bdata == 0)
-			error("screensize: vga soft memory");
-		memset(gscreendata.bdata, Backgnd, width*BY2WD*y);
-		scr->useflush = 1;
-
-		scr->aperture = PADDR(arch->pcimem(0xA0000, 1<<16));
-		scr->apsize = 1<<16;
-	}
-	else
-		gscreendata.bdata = KADDR(scr->aperture);
-
-	if(gscreen)
-		freememimage(gscreen);
-
-	gscreen = allocmemimaged(Rect(0,0,x,y), chan, &gscreendata);
-	vgaimageinit(chan);
-	if(gscreen == nil)
-		return -1;
-
-/*	memset(gscreen->data->bdata, 0x15, (x*y*z+7)/8);	/* RSC BUG */
-	memfillcolor(gscreen, DRed);
-
-	scr->palettedepth = 6;	/* default */
-	scr->gscreendata = &gscreendata;
-	scr->memdefont = getmemdefont();
-	scr->gscreen = gscreen;
-
-	physgscreenr = gscreen->r;
-
-	drawcmap();
-	return 0;
-}
-
-int
-screenaperture(int size, int align)
-{
-	VGAscr *scr;
-	ulong aperture;
-
-	scr = &vgascreen[0];
-
-	if(size == 0){
-		if(scr->aperture && scr->isupamem)
-			upafree(scr->aperture, scr->apsize);
-		scr->aperture = 0;
-		scr->isupamem = 0;
-		return 0;
-	}
-	if(scr->dev && scr->dev->linear){
-		aperture = scr->dev->linear(scr, &size, &align);
-		if(aperture == 0)
-			return 1;
-	}else{
-		aperture = upamalloc(0, size, align);
-		if(aperture == 0)
-			return 1;
-
-		if(scr->aperture && scr->isupamem)
-			upafree(scr->aperture, scr->apsize);
-		scr->isupamem = 1;
-	}
-
-	scr->aperture = aperture;
-	scr->apsize = size;
-
-	return 0;
-}
-
-uchar*
-attachscreen(Rectangle* r, ulong* chan, int* d, int* width, int *softscreen)
-{
-	VGAscr *scr;
-
-	scr = &vgascreen[0];
-	if(scr->gscreen == nil || scr->gscreendata == nil)
-		return nil;
-
-	*r = scr->gscreen->r;
-	*chan = scr->gscreen->chan;
-	*d = scr->gscreen->depth;
-	*width = scr->gscreen->width;
-	*softscreen = scr->useflush;
-
-	return scr->gscreendata->bdata;
-}
-
-/*
- * It would be fair to say that this doesn't work for >8-bit screens.
- */
-void
-flushmemscreen(Rectangle r)
-{
-	VGAscr *scr;
-	uchar *sp, *disp, *sdisp, *edisp;
-	int y, len, incs, off, page;
-
-	scr = &vgascreen[0];
-	if(scr->gscreen == nil || scr->useflush == 0)
-		return;
-	if(scr->dev == nil || scr->dev->page == nil)
-		return;
-
-	if(rectclip(&r, scr->gscreen->r) == 0)
-		return;
-
-	incs = scr->gscreen->width * BY2WD;
-
-	switch(scr->gscreen->depth){
-	default:
-		len = 0;
-		panic("flushmemscreen: depth\n");
-		break;
-	case 8:
-		len = Dx(r);
-		break;
-	}
-	if(len < 1)
-		return;
-
-	off = r.min.y*scr->gscreen->width*BY2WD+(r.min.x*scr->gscreen->depth)/8;
-	page = off/scr->apsize;
-	off %= scr->apsize;
-	disp = KADDR(scr->aperture);
-	sdisp = disp+off;
-	edisp = disp+scr->apsize;
-
-	off = r.min.y*scr->gscreen->width*BY2WD+(r.min.x*scr->gscreen->depth)/8;
-
-	sp = scr->gscreendata->bdata + off;
-
-	scr->dev->page(scr, page);
-	for(y = r.min.y; y < r.max.y; y++) {
-		if(sdisp + incs < edisp) {
-			memmove(sdisp, sp, len);
-			sp += incs;
-			sdisp += incs;
-		}
-		else {
-			off = edisp - sdisp;
-			page++;
-			if(off <= len){
-				if(off > 0)
-					memmove(sdisp, sp, off);
-				scr->dev->page(scr, page);
-				if(len - off > 0)
-					memmove(disp, sp+off, len - off);
-			}
-			else {
-				memmove(sdisp, sp, len);
-				scr->dev->page(scr, page);
-			}
-			sp += incs;
-			sdisp += incs - scr->apsize;
-		}
-	}
-}
-
-void
-getcolor(ulong p, ulong* pr, ulong* pg, ulong* pb)
-{
-	VGAscr *scr;
-	ulong x;
-
-	scr = &vgascreen[0];
-	if(scr->gscreen == nil)
-		return;
-
-	switch(scr->gscreen->depth){
-	default:
-		x = 0x0F;
-		break;
-	case 8:
-		x = 0xFF;
-		break;
-	}
-	p &= x;
-
-	lock(&cursor);
-	*pr = scr->colormap[p][0];
-	*pg = scr->colormap[p][1];
-	*pb = scr->colormap[p][2];
-	unlock(&cursor);
-}
-
-int
-setpalette(ulong p, ulong r, ulong g, ulong b)
-{
-	VGAscr *scr;
-	int d;
-
-	scr = &vgascreen[0];
-	d = scr->palettedepth;
-
-	lock(&cursor);
-	scr->colormap[p][0] = r;
-	scr->colormap[p][1] = g;
-	scr->colormap[p][2] = b;
-	vgao(PaddrW, p);
-	vgao(Pdata, r>>(32-d));
-	vgao(Pdata, g>>(32-d));
-	vgao(Pdata, b>>(32-d));
-	unlock(&cursor);
-
-	return ~0;
-}
-
-/*
- * On some video cards (e.g. Mach64), the palette is used as the 
- * DAC registers for >8-bit modes.  We don't want to set them when the user
- * is trying to set a colormap and the card is in one of these modes.
- */
-int
-setcolor(ulong p, ulong r, ulong g, ulong b)
-{
-	VGAscr *scr;
-	int x;
-
-	scr = &vgascreen[0];
-	if(scr->gscreen == nil)
-		return 0;
-
-	switch(scr->gscreen->depth){
-	case 1:
-	case 2:
-	case 4:
-		x = 0x0F;
-		break;
-	case 8:
-		x = 0xFF;
-		break;
-	default:
-		return 0;
-	}
-	p &= x;
-
-	return setpalette(p, r, g, b);
-}
-
-int
-cursoron(int dolock)
-{
-	VGAscr *scr;
-	int v;
-
-	scr = &vgascreen[0];
-	if(scr->cur == nil || scr->cur->move == nil)
-		return 0;
-
-	if(dolock)
-		lock(&cursor);
-	v = scr->cur->move(scr, mousexy());
-	if(dolock)
-		unlock(&cursor);
-
-	return v;
-}
-
-void
-cursoroff(int)
-{
-}
-
-void
-setcursor(Cursor* curs)
-{
-	VGAscr *scr;
-
-	scr = &vgascreen[0];
-	if(scr->cur == nil || scr->cur->load == nil)
-		return;
-
-	scr->cur->load(scr, curs);
-}
-
-static ulong
-pixelbits(Memimage *i, Point pt)
-{
-	uchar *p;
-	ulong val;
-	int off, bpp, npack;
-
-	val = 0;
-	p = byteaddr(i, pt);
-	switch(bpp=i->depth){
-	case 1:
-	case 2:
-	case 4:
-		npack = 8/bpp;
-		off = pt.x%npack;
-		val = p[0] >> bpp*(npack-1-off);
-		val &= (1<<bpp)-1;
-		break;
-	case 8:
-		val = p[0];
-		break;
-	case 16:
-		val = p[0]|(p[1]<<8);
-		break;
-	case 24:
-		val = p[0]|(p[1]<<8)|(p[2]<<16);
-		break;
-	case 32:
-		val = p[0]|(p[1]<<8)|(p[2]<<16)|(p[3]<<24);
-		break;
-	}
-	while(bpp<32){
-		val |= val<<bpp;
-		bpp *= 2;
-	}
-	return val;
-}
-
-
-static ulong
-imgtorgba(Memimage *img, ulong val)
-{
-	uchar r, g, b, a;
-	int nb, ov, v;
-	ulong chan;
-	uchar *p;
-
-	a = 0xFF;
-	r = g = b = 0xAA;	/* garbage */
-	for(chan=img->chan; chan; chan>>=8){
-		nb = NBITS(chan);
-		ov = v = val&((1<<nb)-1);
-		val >>= nb;
-
-		while(nb < 8){
-			v |= v<<nb;
-			nb *= 2;
-		}
-		v >>= (nb-8);
-
-		switch(TYPE(chan)){
-		case CRed:
-			r = v;
-			break;
-		case CGreen:
-			g = v;
-			break;
-		case CBlue:
-			b = v;
-			break;
-		case CAlpha:
-			a = v;
-			break;
-		case CGrey:
-			r = g = b = v;
-			break;
-		case CMap:
-			p = img->cmap->cmap2rgb+3*ov;
-			r = *p++;
-			g = *p++;	
-			b = *p;
-			break;
-		}
-	}
-	return (r<<24)|(g<<16)|(b<<8)|a;	
-}
-
-static ulong
-rgbatoimg(Memimage *img, ulong rgba)
-{
-	ulong chan;
-	int d, nb;
-	ulong v;
-	uchar *p, r, g, b, a, m;
-
-	v = 0;
-	r = rgba>>24;
-	g = rgba>>16;
-	b = rgba>>8;
-	a = rgba;
-	d = 0;
-	for(chan=img->chan; chan; chan>>=8){
-		nb = NBITS(chan);
-		switch(TYPE(chan)){
-		case CRed:
-			v |= (r>>(8-nb))<<d;
-			break;
-		case CGreen:
-			v |= (g>>(8-nb))<<d;
-			break;
-		case CBlue:
-			v |= (b>>(8-nb))<<d;
-			break;
-		case CAlpha:
-			v |= (a>>(8-nb))<<d;
-			break;
-		case CMap:
-			p = img->cmap->rgb2cmap;
-			m = p[(r>>4)*256+(g>>4)*16+(b>>4)];
-			v |= m<<d;
-			break;
-		case CGrey:
-			m = RGB2K(r,g,b);
-			v |= m<<d;
-			break;
-		}
-		d += nb;
-	}
-//	print("rgba2img %.8lux = %.*lux\n", rgba, 2*d/8, v);
-	return v;
-}
-
-Memimage *lastbadi;
-Memdata *lastbad;
-Memimage *lastbadsrc, *lastbaddst;
-int hwaccel = 1;
-int hwblank = 1;
-
-int
-hwdraw(Memdrawparam *par)
-{
-	int m;
-	VGAscr *scr;
-	Memimage *dst, *src;
-
-	if(hwaccel == 0)
-		return 0;
-
-	dst = par->dst;
-	scr = &vgascreen[0];
-	if(dst == nil || dst->data == nil)
-		return 0;
-
-	if(dst->data->bdata != gscreendata.bdata)
-		return 0;
-
-//	if(dst->data != &gscreendata){
-//		lastbad = dst->data;
-//		lastbadi = dst;
-//		return 0;
-//	}
-
-	if(scr->fill==nil && scr->scroll==nil)
-		return 0;
-
-	/*
-	 * If we have an opaque mask and source is one opaque
-	 * pixel we can convert to the destination format and just
-	 * replicate with memset.
-	 */
-	m = Simplesrc|Simplemask|Fullmask;
-	if(scr->fill && (par->state&m)==m && ((par->srgba&0xFF) == 0xFF))
-		return scr->fill(scr, par->r, par->sdval);
-
-	/*
-	 * If no source alpha, an opaque mask, we can just copy the
-	 * source onto the destination.  If the channels are the same and
-	 * the source is not replicated, memmove suffices.
-	 */
-	src = par->src;
-	if(scr->scroll && src->data->bdata==dst->data->bdata && !(src->flags&Falpha)
-	&& (par->state&(Simplemask|Fullmask))==(Simplemask|Fullmask)){
-//		if(src->zero != dst->zero){
-//			lastbadsrc = src;
-//			lastbaddst = dst;
-//			iprint("#");
-//		}
-		return scr->scroll(scr, par->r, par->sr);
-	}
-
-	return 0;	
-}
-
-void
-blankscreen(int blank)
-{
-	VGAscr *scr;
-
-	scr = &vgascreen[0];
-	if(hwblank && scr->blank)
-		scr->blank(scr, blank);
-}
+#include "../pc/screen.c"

+ 2 - 0
sys/src/9/alphapc/screen.h

@@ -47,6 +47,8 @@ enum {
 	Pwhite		= 0xFF,
 	Pwhite		= 0xFF,
 };
 };
 
 
+#define VGAMEM()	PADDR(arch->pcimem(0xA0000, 1<<16))
+
 #define vgai(port)		inb(port)
 #define vgai(port)		inb(port)
 #define vgao(port, data)	outb(port, data)
 #define vgao(port, data)	outb(port, data)
 
 

+ 1 - 1
sys/src/9/bitsy/main.c

@@ -145,7 +145,7 @@ bootargs(ulong base)
 	 */
 	 */
 	sp = (uchar*)base + BY2PG - sizeof(Sargs);
 	sp = (uchar*)base + BY2PG - sizeof(Sargs);
 
 
-	bootpath = pusharg("/boot");
+	bootpath = pusharg("/boot/boot");
 	ac = 0;
 	ac = 0;
 	av[ac++] = pusharg("boot");
 	av[ac++] = pusharg("boot");
 
 

+ 8 - 8
sys/src/9/bitsy/screen.c

@@ -393,12 +393,12 @@ screenwin(void)
 
 
 	r = insetrect(gscreen->r, 4);
 	r = insetrect(gscreen->r, 4);
 
 
-	memimagedraw(gscreen, r, memblack, ZP, memopaque, ZP);
+	memimagedraw(gscreen, r, memblack, ZP, memopaque, ZP, S);
 	window = insetrect(r, 4);
 	window = insetrect(r, 4);
-	memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP);
+	memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP, S);
 
 
 	memimagedraw(gscreen, Rect(window.min.x, window.min.y,
 	memimagedraw(gscreen, Rect(window.min.x, window.min.y,
-			window.max.x, window.min.y+h+5+6), orange, ZP, nil, ZP);
+			window.max.x, window.min.y+h+5+6), orange, ZP, nil, ZP, S);
 	freememimage(orange);
 	freememimage(orange);
 	window = insetrect(window, 5);
 	window = insetrect(window, 5);
 
 
@@ -445,7 +445,7 @@ screenputc(char *buf)
 		pos = 4-(pos%4);
 		pos = 4-(pos%4);
 		*xp++ = curpos.x;
 		*xp++ = curpos.x;
 		r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h);
 		r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h);
-		memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min);
+		memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
 		flushmemscreen(r);
 		flushmemscreen(r);
 		curpos.x += pos*w;
 		curpos.x += pos*w;
 		break;
 		break;
@@ -454,7 +454,7 @@ screenputc(char *buf)
 			break;
 			break;
 		xp--;
 		xp--;
 		r = Rect(*xp, curpos.y, curpos.x, curpos.y + h);
 		r = Rect(*xp, curpos.y, curpos.x, curpos.y + h);
-		memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min);
+		memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
 		flushmemscreen(r);
 		flushmemscreen(r);
 		curpos.x = *xp;
 		curpos.x = *xp;
 		break;
 		break;
@@ -469,7 +469,7 @@ screenputc(char *buf)
 
 
 		*xp++ = curpos.x;
 		*xp++ = curpos.x;
 		r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y + h);
 		r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y + h);
-		memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min);
+		memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
 		memimagestring(gscreen, curpos, conscol, ZP, memdefont, buf);
 		memimagestring(gscreen, curpos, conscol, ZP, memdefont, buf);
 		flushmemscreen(r);
 		flushmemscreen(r);
 		curpos.x += w;
 		curpos.x += w;
@@ -486,10 +486,10 @@ scroll(void)
 	o = 8*h;
 	o = 8*h;
 	r = Rpt(window.min, Pt(window.max.x, window.max.y-o));
 	r = Rpt(window.min, Pt(window.max.x, window.max.y-o));
 	p = Pt(window.min.x, window.min.y+o);
 	p = Pt(window.min.x, window.min.y+o);
-	memimagedraw(gscreen, r, gscreen, p, nil, p);
+	memimagedraw(gscreen, r, gscreen, p, nil, p, S);
 	flushmemscreen(r);
 	flushmemscreen(r);
 	r = Rpt(Pt(window.min.x, window.max.y-o), window.max);
 	r = Rpt(Pt(window.min.x, window.max.y-o), window.max);
-	memimagedraw(gscreen, r, back, ZP, nil, ZP);
+	memimagedraw(gscreen, r, back, ZP, nil, ZP, S);
 	flushmemscreen(r);
 	flushmemscreen(r);
 
 
 	curpos.y -= o;
 	curpos.y -= o;

+ 3 - 3
sys/src/9/boot/bootauth.c

@@ -13,7 +13,7 @@ authentication(int cpuflag)
 	char *argv[16], **av;
 	char *argv[16], **av;
 	int ac;
 	int ac;
 
 
-	if(access("/factotum", AEXEC) < 0){
+	if(access("/boot/factotum", AEXEC) < 0){
 		glenda();
 		glenda();
 		return;
 		return;
 	}
 	}
@@ -38,8 +38,8 @@ authentication(int cpuflag)
 	case -1:
 	case -1:
 		fatal("starting factotum: %r");
 		fatal("starting factotum: %r");
 	case 0:
 	case 0:
-		exec("/factotum", av);
-		fatal("execing /factotum");
+		exec("/boot/factotum", av);
+		fatal("execing /boot/factotum");
 	default:
 	default:
 		break;
 		break;
 	}
 	}

+ 3 - 3
sys/src/9/boot/bootcache.c

@@ -10,7 +10,7 @@ cache(int fd)
 	int argc, i, p[2];
 	int argc, i, p[2];
 	char *argv[5], bd[32], buf[256], partition[64], *pp;
 	char *argv[5], bd[32], buf[256], partition[64], *pp;
 
 
-	if(stat("/cfs", statbuf, sizeof statbuf) < 0)
+	if(stat("/boot/cfs", statbuf, sizeof statbuf) < 0)
 		return fd;
 		return fd;
 
 
 	*partition = 0;
 	*partition = 0;
@@ -63,9 +63,9 @@ cache(int fd)
 		dup(p[0], 1);
 		dup(p[0], 1);
 		close(p[0]);
 		close(p[0]);
 		if(fflag)
 		if(fflag)
-			execl("/cfs", "bootcfs", "-rs", "-f", partition, 0);
+			execl("/boot/cfs", "bootcfs", "-rs", "-f", partition, 0);
 		else
 		else
-			execl("/cfs", "bootcfs", "-s", "-f", partition, 0);
+			execl("/boot/cfs", "bootcfs", "-s", "-f", partition, 0);
 		break;
 		break;
 	default:
 	default:
 		close(p[0]);
 		close(p[0]);

+ 1 - 1
sys/src/9/boot/bootip.c

@@ -60,7 +60,7 @@ configip(void)
 	case -1:
 	case -1:
 		fatal("configuring ip: %r");
 		fatal("configuring ip: %r");
 	case 0:
 	case 0:
-		exec("/ipconfig", arg);
+		exec("/boot/ipconfig", arg);
 		fatal("execing /ipconfig");
 		fatal("execing /ipconfig");
 	default:
 	default:
 		break;
 		break;

+ 3 - 3
sys/src/9/boot/embed.c

@@ -28,7 +28,7 @@ connectembed(void)
 	Dir *dir;
 	Dir *dir;
 	char **arg, **argp;
 	char **arg, **argp;
 
 
-	dir = dirstat("/paqfs");
+	dir = dirstat("/boot/paqfs");
 	if(dir == nil)
 	if(dir == nil)
 		return -1;
 		return -1;
 	free(dir);
 	free(dir);
@@ -51,7 +51,7 @@ connectembed(void)
 	case 0:
 	case 0:
 		arg = malloc((bargc+5)*sizeof(char*));
 		arg = malloc((bargc+5)*sizeof(char*));
 		argp = arg;
 		argp = arg;
-		*argp++ = "/paqfs";
+		*argp++ = "/boot/paqfs";
 		*argp++ = "-iv";
 		*argp++ = "-iv";
 		*argp++ = paqfile;
 		*argp++ = paqfile;
 		for(i=1; i<bargc; i++)
 		for(i=1; i<bargc; i++)
@@ -62,7 +62,7 @@ connectembed(void)
 		dup(p[1], 1);
 		dup(p[1], 1);
 		close(p[0]);
 		close(p[0]);
 		close(p[1]);
 		close(p[1]);
-		exec("/paqfs", arg);
+		exec("/boot/paqfs", arg);
 		fatal("can't exec paqfs");
 		fatal("can't exec paqfs");
 	default:
 	default:
 		break;
 		break;

+ 2 - 2
sys/src/9/boot/local.c

@@ -58,7 +58,7 @@ connectlocal(void)
 	char **arg, **argp;
 	char **arg, **argp;
 	ulong mode;
 	ulong mode;
 
 
-	if(stat("/kfs", statbuf, sizeof statbuf) < 0)
+	if(stat("/boot/kfs", statbuf, sizeof statbuf) < 0)
 		return -1;
 		return -1;
 
 
 	dev = disk ? disk : bootdisk;
 	dev = disk ? disk : bootdisk;
@@ -100,7 +100,7 @@ connectlocal(void)
 		dup(p[1], 1);
 		dup(p[1], 1);
 		close(p[0]);
 		close(p[0]);
 		close(p[1]);
 		close(p[1]);
-		exec("/kfs", arg);
+		exec("/boot/kfs", arg);
 		fatal("can't exec kfs");
 		fatal("can't exec kfs");
 	default:
 	default:
 		break;
 		break;

+ 1 - 1
sys/src/9/boot/paq.c

@@ -55,7 +55,7 @@ connectpaq(void)
 		dup(p[1], 1);
 		dup(p[1], 1);
 		close(p[0]);
 		close(p[0]);
 		close(p[1]);
 		close(p[1]);
-		exec("/paqfs", arg);
+		exec("/boot/paqfs", arg);
 		fatal("can't exec paqfs");
 		fatal("can't exec paqfs");
 	default:
 	default:
 		break;
 		break;

+ 37 - 0
sys/src/9/boot/testboot.c

@@ -0,0 +1,37 @@
+#include <u.h>
+#include <libc.h>
+#include <auth.h>
+
+void
+usage(void)
+{
+	fprint(2, "usage: testboot cmd args...\n");
+	exits("usage");
+}
+
+void
+main(int argc, char **argv)
+{
+	int p[2];
+
+	if(argc == 1)
+		usage();
+
+	pipe(p);
+	switch(rfork(RFPROC|RFFDG|RFNAMEG)){
+	case -1:
+		sysfatal("fork: %r");
+
+	case 0:
+		dup(p[0], 0);
+		dup(p[1], 1);
+		exec(argv[1], argv+1);
+		sysfatal("exec: %r");
+
+	default:
+		if(amount(p[0], "/n/kremvax", MREPL, "") < 0)
+			sysfatal("amount: %r");
+		break;
+	}
+	exits(nil);
+}

+ 3 - 2
sys/src/9/mtx/initcode

@@ -19,6 +19,7 @@ loop:
 	BR	loop
 	BR	loop
 
 
 DATA	boot+0(SB)/5,$"/boot"
 DATA	boot+0(SB)/5,$"/boot"
-DATA	bootv+0(SB)/4,$boot+1(SB)
-GLOBL	boot+0(SB),$6
+DATA	boot+5(SB)/5,$"/boot"
+DATA	bootv+0(SB)/4,$boot+6(SB)
+GLOBL	boot+0(SB),$11
 GLOBL	bootv+0(SB),$8
 GLOBL	bootv+0(SB),$8

+ 1 - 1
sys/src/9/mtx/mkfile

@@ -50,7 +50,6 @@ OBJ=\
 	trap.$O\
 	trap.$O\
 	$DEVS\
 	$DEVS\
 	$PORT\
 	$PORT\
-	boot$CONF.root.$O\
 
 
 LIB=\
 LIB=\
 	/$objtype/lib/libmemlayer.a\
 	/$objtype/lib/libmemlayer.a\
@@ -75,6 +74,7 @@ install:V: $p$CONF
 
 
 <../boot/bootmkfile
 <../boot/bootmkfile
 <../port/portmkfile
 <../port/portmkfile
+<|../port/mkbootrules $CONF
 
 
 clock.$O devether.$O main.$O trap.$O:	/$objtype/include/ureg.h
 clock.$O devether.$O main.$O trap.$O:	/$objtype/include/ureg.h
 
 

+ 5 - 3
sys/src/9/mtx/mtx

@@ -24,9 +24,6 @@ link
 	netdevmedium
 	netdevmedium
 
 
 misc
 misc
-	ipconfig.root
-	factotum.root
-
 	uarti8250
 	uarti8250
 
 
 ip
 ip
@@ -42,3 +39,8 @@ port
 
 
 boot
 boot
 	il
 	il
+
+bootdir
+	bootmtx.out boot
+	ipconfig.hack ipconfig
+	factotum.hack factotum

+ 6 - 3
sys/src/9/mtx/mtxcpu

@@ -24,9 +24,6 @@ link
 	netdevmedium
 	netdevmedium
 
 
 misc
 misc
-	ipconfig.root
-	factotum.root
-
 	uarti8250
 	uarti8250
 
 
 ip
 ip
@@ -42,3 +39,9 @@ port
 
 
 boot cpu
 boot cpu
 	il
 	il
+
+bootdir
+	bootmtxcpu.out boot
+	ipconfig.hack ipconfig
+	factotum.hack factotum
+

+ 3 - 2
sys/src/9/pc/devvga.c

@@ -179,7 +179,8 @@ vgaread(Chan* c, void* a, long n, vlong off)
 					physgscreenr.max.x, physgscreenr.max.y);
 					physgscreenr.max.x, physgscreenr.max.y);
 		}
 		}
 
 
-		len += snprint(p+len, READSTR-len, "blanktime %lud\n", blanktime);
+		len += snprint(p+len, READSTR-len, "blank time %lud idle %d state %s\n",
+			blanktime, drawidletime(), scr->isblank ? "off" : "on");
 		len += snprint(p+len, READSTR-len, "hwaccel %s\n", hwaccel ? "on" : "off");
 		len += snprint(p+len, READSTR-len, "hwaccel %s\n", hwaccel ? "on" : "off");
 		len += snprint(p+len, READSTR-len, "hwblank %s\n", hwblank ? "on" : "off");
 		len += snprint(p+len, READSTR-len, "hwblank %s\n", hwblank ? "on" : "off");
 		len += snprint(p+len, READSTR-len, "panning %s\n", panning ? "on" : "off");
 		len += snprint(p+len, READSTR-len, "panning %s\n", panning ? "on" : "off");
@@ -321,7 +322,7 @@ vgactl(Cmdbuf *cb)
 		return;
 		return;
 
 
 	case CMdrawinit:
 	case CMdrawinit:
-		memimagedraw(scr->gscreen, scr->gscreen->r, memblack, ZP, nil, ZP);
+		memimagedraw(scr->gscreen, scr->gscreen->r, memblack, ZP, nil, ZP, S);
 		if(scr && scr->dev && scr->dev->drawinit)
 		if(scr && scr->dev && scr->dev->drawinit)
 			scr->dev->drawinit(scr);
 			scr->dev->drawinit(scr);
 		return;
 		return;

+ 1 - 1
sys/src/9/pc/kbd.c

@@ -383,7 +383,7 @@ i8042intr(Ureg*, void*)
 			 * come back into focus, Plan 9 thinks you want to type
 			 * come back into focus, Plan 9 thinks you want to type
 			 * a compose sequence (you just typed alt). 
 			 * a compose sequence (you just typed alt). 
 			 *
 			 *
-			 * As a clusmy hack around this, we look for ctl-alt
+			 * As a clumsy hack around this, we look for ctl-alt
 			 * and don't treat it as the start of a compose sequence.
 			 * and don't treat it as the start of a compose sequence.
 			 */
 			 */
 			if(!ctl){
 			if(!ctl){

+ 5 - 5
sys/src/9/pc/mkfile

@@ -50,7 +50,6 @@ OBJ=\
 	trap.$O\
 	trap.$O\
 	$DEVS\
 	$DEVS\
 	$PORT\
 	$PORT\
-	boot$CONF.root.$O\
 
 
 LIB=\
 LIB=\
 	/$objtype/lib/libmemlayer.a\
 	/$objtype/lib/libmemlayer.a\
@@ -77,6 +76,7 @@ install:V: $p$CONF $p$CONF.gz
 
 
 <../boot/bootmkfile
 <../boot/bootmkfile
 <../port/portmkfile
 <../port/portmkfile
+<|../port/mkbootrules $CONF
 
 
 $ETHER: 			etherif.h ../port/netif.h
 $ETHER: 			etherif.h ../port/netif.h
 ether8003.$O ether8390.$O:	ether8390.h
 ether8003.$O ether8390.$O:	ether8390.h
@@ -94,11 +94,11 @@ devusb.$O usbuhci.$O usbohci.$O:	usb.h
 sd53c8xx.i:	sd53c8xx.n
 sd53c8xx.i:	sd53c8xx.n
 	aux/na $prereq > $target
 	aux/na $prereq > $target
 
 
-init.h:	initcode.s /sys/src/libc/9syscall/sys.h
-	$AS initcode.s
-	$LD -l -R4 -o init.out initcode.$O
+init.h:	../port/initcode.c /sys/src/libc/9syscall/sys.h
+	$CC ../port/initcode.c
+	$LD -l -R1 -o init.out initcode.$O /386/lib/libc.a
 	{echo 'uchar initcode[]={'
 	{echo 'uchar initcode[]={'
-	 xd -1x init.out |
+	 strip < init.out | xd -1x |
 		sed -e 's/^[0-9a-f]+ //' -e 's/ ([0-9a-f][0-9a-f])/0x\1,/g'
 		sed -e 's/^[0-9a-f]+ //' -e 's/ ([0-9a-f][0-9a-f])/0x\1,/g'
 	 echo '};'} > init.h
 	 echo '};'} > init.h
 
 

+ 5 - 3
sys/src/9/pc/pc

@@ -60,9 +60,6 @@ link
 misc
 misc
 	archmp		mp apic
 	archmp		mp apic
 
 
-	ipconfig.root
-	factotum.root
-
 	sdata		pci sdscsi
 	sdata		pci sdscsi
 	sd53c8xx	pci sdscsi
 	sd53c8xx	pci sdscsi
 	sdmylex		pci sdscsi
 	sdmylex		pci sdscsi
@@ -105,3 +102,8 @@ port
 
 
 boot
 boot
 	il
 	il
+
+bootdir
+	bootpc.out boot
+	/386/bin/ip/ipconfig
+	factotum.hack factotum

+ 7 - 4
sys/src/9/pc/pcauth

@@ -32,12 +32,9 @@ link
 	ether82557	pci
 	ether82557	pci
 	ethermedium
 	ethermedium
 	netdevmedium
 	netdevmedium
+	loopbackmedium
 
 
 misc
 misc
-	factotum.root
-	ipconfig.root
-	kfs.root
-
 	sdata		pci sdscsi
 	sdata		pci sdscsi
 
 
 	uarti8250
 	uarti8250
@@ -59,3 +56,9 @@ port
 boot cpu boot #S/sdC0/
 boot cpu boot #S/sdC0/
 	il
 	il
 	local
 	local
+
+bootdir
+	bootpcauth.out boot
+	/386/bin/ip/ipconfig
+	factotum.hack factotum
+	/386/bin/disk/kfs

+ 6 - 5
sys/src/9/pc/pccd

@@ -58,11 +58,6 @@ link
 misc
 misc
 	archmp		mp apic
 	archmp		mp apic
 
 
-	ipconfig.root
-	9660srv.root
-	factotum.root
-	cfs.root
-
 	sdata		pci sdscsi
 	sdata		pci sdscsi
 	sd53c8xx		pci sdscsi
 	sd53c8xx		pci sdscsi
 	sdmylex		pci sdscsi
 	sdmylex		pci sdscsi
@@ -104,3 +99,9 @@ port
 boot boot #S/sdD0/data
 boot boot #S/sdD0/data
 	il
 	il
 	local
 	local
+
+bootdir
+	bootpccd.out boot
+	/386/bin/ip/ipconfig ipconfig
+	/386/bin/9660srv kfs
+

+ 6 - 2
sys/src/9/pc/pccpu

@@ -32,6 +32,7 @@ link
 	ether79c970	pci
 	ether79c970	pci
 	ether8003	ether8390
 	ether8003	ether8390
 	ether8139	pci
 	ether8139	pci
+	ether82543	pci ethermii
 	ether82543gc	pci
 	ether82543gc	pci
 	ether82557	pci
 	ether82557	pci
 	ether83815	pci
 	ether83815	pci
@@ -49,8 +50,6 @@ misc
 	sdata		pci sdscsi
 	sdata		pci sdscsi
 	sd53c8xx	pci sdscsi
 	sd53c8xx	pci sdscsi
 
 
-	ipconfig.root
-	factotum.root
 
 
 ip
 ip
 	il
 	il
@@ -69,3 +68,8 @@ port
 
 
 boot cpu
 boot cpu
 	il
 	il
+
+bootdir
+	bootpccpu.out boot
+	/386/bin/ip/ipconfig ipconfig
+	factotum.hack factotum

+ 8 - 6
sys/src/9/pc/pcdisk

@@ -60,11 +60,6 @@ link
 misc
 misc
 	archmp		mp apic
 	archmp		mp apic
 
 
-	ipconfig.root
-	kfs.root
-	factotum.root
-	cfs.root
-
 	sdata		pci sdscsi
 	sdata		pci sdscsi
 	sd53c8xx		pci sdscsi
 	sd53c8xx		pci sdscsi
 	sdmylex		pci sdscsi
 	sdmylex		pci sdscsi
@@ -105,5 +100,12 @@ port
 	int cpuserver = 0;
 	int cpuserver = 0;
 
 
 boot boot #S/sdC0/
 boot boot #S/sdC0/
-	il
 	local
 	local
+	il
+
+bootdir
+	bootpcdisk.out boot
+	/386/bin/ip/ipconfig
+	factotum.hack factotum
+	/386/bin/disk/kfs
+	/386/bin/cfs

+ 11 - 5
sys/src/9/pc/screen.c

@@ -58,7 +58,7 @@ screensize(int x, int y, int z, ulong chan)
 			error("screensize: vga soft memory");
 			error("screensize: vga soft memory");
 /*		memset(gscreendata.bdata, 0x72, width*BY2WD*y);	/* not really black */
 /*		memset(gscreendata.bdata, 0x72, width*BY2WD*y);	/* not really black */
 		scr->useflush = 1;
 		scr->useflush = 1;
-		scr->aperture = 0xA0000;
+		scr->aperture = VGAMEM();
 		scr->apsize = 1<<16;
 		scr->apsize = 1<<16;
 	}
 	}
 	else
 	else
@@ -362,7 +362,10 @@ hwdraw(Memdrawparam *par)
 	 * replicate with memset.
 	 * replicate with memset.
 	 */
 	 */
 	m = Simplesrc|Simplemask|Fullmask;
 	m = Simplesrc|Simplemask|Fullmask;
-	if(scr->fill && (par->state&m)==m && ((par->srgba&0xFF) == 0xFF))
+	if(scr->fill
+	&& (par->state&m)==m
+	&& ((par->srgba&0xFF) == 0xFF)
+	&& (par->op&S) == S)
 		return scr->fill(scr, par->r, par->sdval);
 		return scr->fill(scr, par->r, par->sdval);
 
 
 	/*
 	/*
@@ -370,11 +373,14 @@ hwdraw(Memdrawparam *par)
 	 * source onto the destination.  If the channels are the same and
 	 * source onto the destination.  If the channels are the same and
 	 * the source is not replicated, memmove suffices.
 	 * the source is not replicated, memmove suffices.
 	 */
 	 */
+	m = Simplemask|Fullmask;
 	src = par->src;
 	src = par->src;
-	if(scr->scroll && src->data->bdata==dst->data->bdata && !(src->flags&Falpha)
-	&& (par->state&(Simplemask|Fullmask))==(Simplemask|Fullmask)){
+	if(scr->scroll
+	&& src->data->bdata==dst->data->bdata
+	&& !(src->flags&Falpha)
+	&& (par->state&m)==m
+	&& (par->op&S) == S)
 		return scr->scroll(scr, par->r, par->sr);
 		return scr->scroll(scr, par->r, par->sr);
-	}
 
 
 	return 0;	
 	return 0;	
 }
 }

+ 3 - 0
sys/src/9/pc/screen.h

@@ -47,6 +47,7 @@ enum {
 	Pwhite		= 0xFF,
 	Pwhite		= 0xFF,
 };
 };
 
 
+#define VGAMEM()	0xA0000
 #define vgai(port)		inb(port)
 #define vgai(port)		inb(port)
 #define vgao(port, data)	outb(port, data)
 #define vgao(port, data)	outb(port, data)
 
 
@@ -114,6 +115,7 @@ struct VGAscr {
 	int	(*scroll)(VGAscr*, Rectangle, Rectangle);
 	int	(*scroll)(VGAscr*, Rectangle, Rectangle);
 	void	(*blank)(VGAscr*, int);
 	void	(*blank)(VGAscr*, int);
 	ulong	id;	/* internal identifier for driver use */
 	ulong	id;	/* internal identifier for driver use */
+	int isblank;
 };
 };
 
 
 extern VGAscr vgascreen[];
 extern VGAscr vgascreen[];
@@ -146,6 +148,7 @@ extern int		drawhasclients(void);
 extern ulong	blanktime;
 extern ulong	blanktime;
 extern void	setscreenimageclipr(Rectangle);
 extern void	setscreenimageclipr(Rectangle);
 extern void	drawflush(void);
 extern void	drawflush(void);
+extern int drawidletime(void);
 
 
 /* vga.c */
 /* vga.c */
 extern void	vgascreenwin(VGAscr*);
 extern void	vgascreenwin(VGAscr*);

+ 6 - 6
sys/src/9/pc/vga.c

@@ -54,9 +54,9 @@ vgascroll(VGAscr* scr)
 	o = 8*h;
 	o = 8*h;
 	r = Rpt(window.min, Pt(window.max.x, window.max.y-o));
 	r = Rpt(window.min, Pt(window.max.x, window.max.y-o));
 	p = Pt(window.min.x, window.min.y+o);
 	p = Pt(window.min.x, window.min.y+o);
-	memimagedraw(scr->gscreen, r, scr->gscreen, p, nil, p);
+	memimagedraw(scr->gscreen, r, scr->gscreen, p, nil, p, S);
 	r = Rpt(Pt(window.min.x, window.max.y-o), window.max);
 	r = Rpt(Pt(window.min.x, window.max.y-o), window.max);
-	memimagedraw(scr->gscreen, r, back, ZP, nil, ZP);
+	memimagedraw(scr->gscreen, r, back, ZP, nil, ZP, S);
 
 
 	curpos.y -= o;
 	curpos.y -= o;
 }
 }
@@ -99,7 +99,7 @@ vgascreenputc(VGAscr* scr, char* buf, Rectangle *flushr)
 		pos = 4-(pos%4);
 		pos = 4-(pos%4);
 		*xp++ = curpos.x;
 		*xp++ = curpos.x;
 		r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h);
 		r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h);
-		memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min);
+		memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min, S);
 		curpos.x += pos*w;
 		curpos.x += pos*w;
 		break;
 		break;
 
 
@@ -108,7 +108,7 @@ vgascreenputc(VGAscr* scr, char* buf, Rectangle *flushr)
 			break;
 			break;
 		xp--;
 		xp--;
 		r = Rect(*xp, curpos.y, curpos.x, curpos.y+h);
 		r = Rect(*xp, curpos.y, curpos.x, curpos.y+h);
-		memimagedraw(scr->gscreen, r, back, back->r.min, nil, ZP);
+		memimagedraw(scr->gscreen, r, back, back->r.min, nil, ZP, S);
 		combinerect(flushr, r);
 		combinerect(flushr, r);
 		curpos.x = *xp;
 		curpos.x = *xp;
 		break;
 		break;
@@ -125,7 +125,7 @@ vgascreenputc(VGAscr* scr, char* buf, Rectangle *flushr)
 
 
 		*xp++ = curpos.x;
 		*xp++ = curpos.x;
 		r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y+h);
 		r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y+h);
-		memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min);
+		memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min, S);
 		memimagestring(scr->gscreen, curpos, conscol, ZP, scr->memdefont, buf);
 		memimagestring(scr->gscreen, curpos, conscol, ZP, scr->memdefont, buf);
 		combinerect(flushr, r);
 		combinerect(flushr, r);
 		curpos.x += w;
 		curpos.x += w;
@@ -248,7 +248,7 @@ cornerstring(char *s)
 	h = scr->memdefont->height;
 	h = scr->memdefont->height;
 
 
 	r = Rect(0, 0, w, h);
 	r = Rect(0, 0, w, h);
-	memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min);
+	memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min, S);
 	memimagestring(scr->gscreen, r.min, conscol, ZP, scr->memdefont, s);
 	memimagestring(scr->gscreen, r.min, conscol, ZP, scr->memdefont, s);
 //	flushmemscreen(r);
 //	flushmemscreen(r);
 }
 }

+ 65 - 21
sys/src/9/port/devdraw.c

@@ -80,6 +80,7 @@ struct Client
 	int		slot;
 	int		slot;
 	int		refreshme;
 	int		refreshme;
 	int		infoid;
 	int		infoid;
+	int		op;
 };
 };
 
 
 struct Refresh
 struct Refresh
@@ -384,6 +385,11 @@ dstflush(int dstid, Memimage *dst, Rectangle r)
 		combinerect(&flushrect, r);
 		combinerect(&flushrect, r);
 		return;
 		return;
 	}
 	}
+	/* how can this happen? -rsc, dec 12 2002 */
+	if(dst == 0){
+		print("nil dstflush\n");
+		return;
+	}
 	l = dst->layer;
 	l = dst->layer;
 	if(l == nil)
 	if(l == nil)
 		return;
 		return;
@@ -750,10 +756,21 @@ drawnewclient(void)
 	memset(cl, 0, sizeof(Client));
 	memset(cl, 0, sizeof(Client));
 	cl->slot = i;
 	cl->slot = i;
 	cl->clientid = ++sdraw.clientid;
 	cl->clientid = ++sdraw.clientid;
+	cl->op = SoverD;
 	sdraw.client[i] = cl;
 	sdraw.client[i] = cl;
 	return cl;
 	return cl;
 }
 }
 
 
+static int
+drawclientop(Client *cl)
+{
+	int op;
+
+	op = cl->op;
+	cl->op = SoverD;
+	return op;
+}
+
 int
 int
 drawhasclients(void)
 drawhasclients(void)
 {
 {
@@ -820,7 +837,7 @@ drawpoint(Point *p, uchar *a)
 }
 }
 
 
 Point
 Point
-drawchar(Memimage *dst, Point p, Memimage *src, Point *sp, DImage *font, int index)
+drawchar(Memimage *dst, Point p, Memimage *src, Point *sp, DImage *font, int index, int op)
 {
 {
 	FChar *fc;
 	FChar *fc;
 	Rectangle r;
 	Rectangle r;
@@ -833,7 +850,7 @@ drawchar(Memimage *dst, Point p, Memimage *src, Point *sp, DImage *font, int ind
 	r.max.y = r.min.y+(fc->maxy-fc->miny);
 	r.max.y = r.min.y+(fc->maxy-fc->miny);
 	sp1.x = sp->x+fc->left;
 	sp1.x = sp->x+fc->left;
 	sp1.y = sp->y+fc->miny;
 	sp1.y = sp->y+fc->miny;
-	memdraw(dst, r, src, sp1, font->image, Pt(fc->minx, fc->miny));
+	memdraw(dst, r, src, sp1, font->image, Pt(fc->minx, fc->miny), op);
 	p.x += fc->width;
 	p.x += fc->width;
 	sp->x += fc->width;
 	sp->x += fc->width;
 	return p;
 	return p;
@@ -877,7 +894,7 @@ deletescreenimage(void)
 	qunlock(&sdraw);
 	qunlock(&sdraw);
 }
 }
 
 
-Chan*
+static Chan*
 drawattach(char *spec)
 drawattach(char *spec)
 {
 {
 	qlock(&sdraw);
 	qlock(&sdraw);
@@ -889,7 +906,7 @@ drawattach(char *spec)
 	return devattach('i', spec);
 	return devattach('i', spec);
 }
 }
 
 
-Walkqid*
+static Walkqid*
 drawwalk(Chan *c, Chan *nc, char **name, int nname)
 drawwalk(Chan *c, Chan *nc, char **name, int nname)
 {
 {
 	if(screendata.bdata == nil)
 	if(screendata.bdata == nil)
@@ -1272,7 +1289,7 @@ printmesg(char *fmt, uchar *a, int plsprnt)
 void
 void
 drawmesg(Client *client, void *av, int n)
 drawmesg(Client *client, void *av, int n)
 {
 {
-	int c, repl, m, y, dstid, scrnid, ni, ci, j, nw, e0, e1, ox, oy, esize, doflush;
+	int c, repl, m, y, dstid, scrnid, ni, ci, j, nw, e0, e1, op, ox, oy, oesize, esize, doflush;
 	uchar *u, *a, refresh;
 	uchar *u, *a, refresh;
 	char *fmt;
 	char *fmt;
 	ulong value, chan;
 	ulong value, chan;
@@ -1427,7 +1444,8 @@ drawmesg(Client *client, void *av, int n)
 			drawrectangle(&r, a+13);
 			drawrectangle(&r, a+13);
 			drawpoint(&p, a+29);
 			drawpoint(&p, a+29);
 			drawpoint(&q, a+37);
 			drawpoint(&q, a+37);
-			memdraw(dst, r, src, p, mask, q);
+			op = drawclientop(client);
+			memdraw(dst, r, src, p, mask, q, op);
 			dstflush(dstid, dst, r);
 			dstflush(dstid, dst, r);
 			continue;
 			continue;
 
 
@@ -1464,13 +1482,14 @@ drawmesg(Client *client, void *av, int n)
 				c = -1;
 				c = -1;
 			ox = BGLONG(a+37);
 			ox = BGLONG(a+37);
 			oy = BGLONG(a+41);
 			oy = BGLONG(a+41);
+			op = drawclientop(client);
 			/* high bit indicates arc angles are present */
 			/* high bit indicates arc angles are present */
 			if(ox & (1<<31)){
 			if(ox & (1<<31)){
 				if((ox & (1<<30)) == 0)
 				if((ox & (1<<30)) == 0)
 					ox &= ~(1<<31);
 					ox &= ~(1<<31);
-				memarc(dst, p, e0, e1, c, src, sp, ox, oy);
+				memarc(dst, p, e0, e1, c, src, sp, ox, oy, op);
 			}else
 			}else
-				memellipse(dst, p, e0, e1, c, src, sp);
+				memellipse(dst, p, e0, e1, c, src, sp, op);
 			dstflush(dstid, dst, Rect(p.x-e0-j, p.y-e1-j, p.x+e0+j+1, p.y+e1+j+1));
 			dstflush(dstid, dst, Rect(p.x-e0-j, p.y-e1-j, p.x+e0+j+1, p.y+e1+j+1));
 			continue;
 			continue;
 
 
@@ -1539,7 +1558,7 @@ drawmesg(Client *client, void *av, int n)
 				error(Eindex);
 				error(Eindex);
 			drawrectangle(&r, a+11);
 			drawrectangle(&r, a+11);
 			drawpoint(&p, a+27);
 			drawpoint(&p, a+27);
-			memdraw(font->image, r, src, p, memopaque, p);
+			memdraw(font->image, r, src, p, memopaque, p, S);
 			fc = &font->fchar[ci];
 			fc = &font->fchar[ci];
 			fc->minx = r.min.x;
 			fc->minx = r.min.x;
 			fc->maxx = r.max.x;
 			fc->maxx = r.max.x;
@@ -1566,7 +1585,8 @@ drawmesg(Client *client, void *av, int n)
 				error("negative line width");
 				error("negative line width");
 			src = drawimage(client, a+33);
 			src = drawimage(client, a+33);
 			drawpoint(&sp, a+37);
 			drawpoint(&sp, a+37);
-			memline(dst, p, q, e0, e1, j, src, sp);
+			op = drawclientop(client);
+			memline(dst, p, q, e0, e1, j, src, sp, op);
 			/* avoid memlinebbox if possible */
 			/* avoid memlinebbox if possible */
 			if(dstid==0 || dst->layer!=nil){
 			if(dstid==0 || dst->layer!=nil){
 				/* BUG: this is terribly inefficient: update maximal containing rect*/
 				/* BUG: this is terribly inefficient: update maximal containing rect*/
@@ -1672,6 +1692,15 @@ drawmesg(Client *client, void *av, int n)
 			}
 			}
 			continue;
 			continue;
 
 
+		/* set compositing operator for next draw operation: 'O' op */
+		case 'O':
+			printmesg(fmt="b", a, 0);
+			m = 1+1;
+			if(n < m)
+				error(Eshortdraw);
+			client->op = a[1];
+			continue;
+
 		/* filled polygon: 'P' dstid[4] n[2] wind[4] ignore[2*4] srcid[4] sp[2*4] p0[2*4] dp[2*2*n] */
 		/* filled polygon: 'P' dstid[4] n[2] wind[4] ignore[2*4] srcid[4] sp[2*4] p0[2*4] dp[2*2*n] */
 		/* polygon: 'p' dstid[4] n[2] end0[4] end1[4] radius[4] srcid[4] sp[2*4] p0[2*4] dp[2*2*n] */
 		/* polygon: 'p' dstid[4] n[2] end0[4] end1[4] radius[4] srcid[4] sp[2*4] p0[2*4] dp[2*2*n] */
 		case 'p':
 		case 'p':
@@ -1704,8 +1733,11 @@ drawmesg(Client *client, void *av, int n)
 			if(dstid==0 || (dst->layer && dst->layer->screen->image->data == screenimage->data))
 			if(dstid==0 || (dst->layer && dst->layer->screen->image->data == screenimage->data))
 				doflush = 1;	/* simplify test in loop */
 				doflush = 1;	/* simplify test in loop */
 			ox = oy = 0;
 			ox = oy = 0;
+			esize = 0;
 			u = a+m;
 			u = a+m;
 			for(y=0; y<ni; y++){
 			for(y=0; y<ni; y++){
+				q = p;
+				oesize = esize;
 				u = drawcoord(u, a+n, ox, &p.x);
 				u = drawcoord(u, a+n, ox, &p.x);
 				u = drawcoord(u, a+n, oy, &p.y);
 				u = drawcoord(u, a+n, oy, &p.y);
 				ox = p.x;
 				ox = p.x;
@@ -1726,16 +1758,22 @@ drawmesg(Client *client, void *av, int n)
 					}
 					}
 					if(*a=='P' && e0!=1 && e0 !=~0)
 					if(*a=='P' && e0!=1 && e0 !=~0)
 						r = dst->clipr;
 						r = dst->clipr;
-					else
-						r = Rect(p.x-esize, p.y-esize, p.x+esize+1, p.y+esize+1);
-					dstflush(dstid, dst, r);
+					else if(y > 0){
+						r = Rect(q.x-oesize, q.y-oesize, q.x+oesize+1, q.y+oesize+1);
+						combinerect(&r, Rect(p.x-esize, p.y-esize, p.x+esize+1, p.y+esize+1));
+					}
+					if(rectclip(&r, dst->clipr))		/* should perhaps be an arg to dstflush */
+						dstflush(dstid, dst, r);
 				}
 				}
 				pp[y] = p;
 				pp[y] = p;
 			}
 			}
+			if(y == 1)
+				dstflush(dstid, dst, Rect(p.x-esize, p.y-esize, p.x+esize+1, p.y+esize+1));
+			op = drawclientop(client);
 			if(*a == 'p')
 			if(*a == 'p')
-				mempoly(dst, pp, ni, e0, e1, j, src, sp);
+				mempoly(dst, pp, ni, e0, e1, j, src, sp, op);
 			else
 			else
-				memfillpoly(dst, pp, ni, e0, src, sp);
+				memfillpoly(dst, pp, ni, e0, src, sp, op);
 			free(pp);
 			free(pp);
 			m = u-a;
 			m = u-a;
 			continue;
 			continue;
@@ -1793,6 +1831,7 @@ drawmesg(Client *client, void *av, int n)
 				error(Eshortdraw);
 				error(Eshortdraw);
 			clipr = dst->clipr;
 			clipr = dst->clipr;
 			dst->clipr = r;
 			dst->clipr = r;
+			op = drawclientop(client);
 			if(*a == 'x'){
 			if(*a == 'x'){
 				/* paint background */
 				/* paint background */
 				l = drawimage(client, a+47);
 				l = drawimage(client, a+47);
@@ -1811,7 +1850,7 @@ drawmesg(Client *client, void *av, int n)
 					r.max.x += font->fchar[ci].width;
 					r.max.x += font->fchar[ci].width;
 					u += 2;
 					u += 2;
 				}
 				}
-				memdraw(dst, r, l, q, memopaque, ZP);
+				memdraw(dst, r, l, q, memopaque, ZP, op);
 				u -= 2*ni;
 				u -= 2*ni;
 			}
 			}
 			q = p;
 			q = p;
@@ -1821,7 +1860,7 @@ drawmesg(Client *client, void *av, int n)
 					dst->clipr = clipr;
 					dst->clipr = clipr;
 					error(Eindex);
 					error(Eindex);
 				}
 				}
-				q = drawchar(dst, q, src, &sp, font, ci);
+				q = drawchar(dst, q, src, &sp, font, ci, op);
 				u += 2;
 				u += 2;
 			}
 			}
 			dst->clipr = clipr;
 			dst->clipr = clipr;
@@ -2020,11 +2059,16 @@ drawactive(int active)
 {
 {
 	if(active){
 	if(active){
 		drawblankscreen(0);
 		drawblankscreen(0);
-		sdraw.blanktime = 0;
+		sdraw.blanktime = MACHP(0)->ticks;
 	}else{
 	}else{
-		if(blanktime && TK2SEC(sdraw.blanktime)/60 >= blanktime)
+		if(blanktime && sdraw.blanktime && TK2SEC(MACHP(0)->ticks - sdraw.blanktime)/60 >= blanktime)
 			drawblankscreen(1);
 			drawblankscreen(1);
-		else
-			sdraw.blanktime++;
 	}
 	}
 }
 }
+
+int
+drawidletime(void)
+{
+	return TK2SEC(MACHP(0)->ticks - sdraw.blanktime)/60;
+}
+

+ 27 - 13
sys/src/9/port/devmnt.c

@@ -829,6 +829,24 @@ mountio(Mnt *m, Mntrpc *r)
 	mntflushfree(m, r);
 	mntflushfree(m, r);
 }
 }
 
 
+static int
+doread(Mnt *m, int len)
+{
+	Block *b;
+
+	while(qlen(m->q) < len){
+		b = devtab[m->c->type]->bread(m->c, m->msize, 0);
+		if(b == nil)
+			return -1;
+		if(BLEN(b) == 0){
+			freeblist(b);
+			return -1;
+		}
+		qaddlist(m->q, b);
+	}
+	return 0;
+}
+
 int
 int
 mntrpcread(Mnt *m, Mntrpc *r)
 mntrpcread(Mnt *m, Mntrpc *r)
 {
 {
@@ -839,22 +857,18 @@ mntrpcread(Mnt *m, Mntrpc *r)
 	r->reply.tag = 0;
 	r->reply.tag = 0;
 
 
 	/* read at least length, type, and tag and pullup to a single block */
 	/* read at least length, type, and tag and pullup to a single block */
-	while(qlen(m->q) < BIT32SZ+BIT8SZ+BIT16SZ){
-		b = devtab[m->c->type]->bread(m->c, m->msize, 0);
-		if(b == nil)
-			return -1;
-		qaddlist(m->q, b);
-	}
+	if(doread(m, BIT32SZ+BIT8SZ+BIT16SZ) < 0)
+		return -1;
 	nb = pullupqueue(m->q, BIT32SZ+BIT8SZ+BIT16SZ);
 	nb = pullupqueue(m->q, BIT32SZ+BIT8SZ+BIT16SZ);
-	len = GBIT32(nb->rp);
 
 
-	/* read in the rest of the message */
-	while(qlen(m->q) < len){
-		b = devtab[m->c->type]->bread(m->c, m->msize, 0);
-		if(b == nil)
-			return -1;
-		qaddlist(m->q, b);
+	/* read in the rest of the message, avoid rediculous (for now) message sizes */
+	len = GBIT32(nb->rp);
+	if(len > m->msize){
+		qdiscard(m->q, qlen(m->q));
+		return -1;
 	}
 	}
+	if(doread(m, len) < 0)
+		return -1;
 
 
 	/* pullup the header (i.e. everything except data) */
 	/* pullup the header (i.e. everything except data) */
 	t = nb->rp[BIT32SZ];
 	t = nb->rp[BIT32SZ];

+ 102 - 38
sys/src/9/port/devroot.c

@@ -5,61 +5,90 @@
 #include	"fns.h"
 #include	"fns.h"
 #include	"../port/error.h"
 #include	"../port/error.h"
 
 
-enum{
-	Qdir=	0,
+enum
+{
+	Qdir = 0,
+	Qboot = 0x1000,
 
 
-	Nfiles=32,	/* max root files */
+	Nrootfiles = 32,
+	Nbootfiles = 16,
 };
 };
 
 
-extern ulong	bootlen;
-extern uchar	bootcode[];
+typedef struct Dirlist Dirlist;
+struct Dirlist
+{
+	uint base;
+	Dirtab *dir;
+	uchar **data;
+	int ndir;
+	int mdir;
+};
 
 
-Dirtab rootdir[Nfiles] = {
-	".",	{Qdir, 0, QTDIR},	0,		DMDIR|0555,
+static Dirtab rootdir[Nrootfiles] = {
+	"#/",		{Qdir, 0, QTDIR},	0,		DMDIR|0555,
+	"boot",	{Qboot, 0, QTDIR},	0,		DMDIR|0555,
+};
+static uchar *rootdata[Nrootfiles];
+static Dirlist rootlist = 
+{
+	0,
+	rootdir,
+	rootdata,
+	2,
+	Nrootfiles
 };
 };
 
 
-static uchar	*rootdata[Nfiles];
-static int	nroot = 1;
+static Dirtab bootdir[Nbootfiles] = {
+	"boot",	{Qboot, 0, QTDIR},	0,		DMDIR|0555,
+};
+static uchar *bootdata[Nbootfiles];
+static Dirlist bootlist =
+{
+	Qboot,
+	bootdir,
+	bootdata,
+	1,
+	Nbootfiles
+};
 
 
 /*
 /*
- *  add a root file
+ *  add a file to the list
  */
  */
 static void
 static void
-addroot(char *name, uchar *contents, ulong len, int perm)
+addlist(Dirlist *l, char *name, uchar *contents, ulong len, int perm)
 {
 {
 	Dirtab *d;
 	Dirtab *d;
 
 
-	if(nroot >= Nfiles)
+	if(l->ndir >= l->mdir)
 		panic("too many root files");
 		panic("too many root files");
-	rootdata[nroot] = contents;
-	d = &rootdir[nroot];
+	l->data[l->ndir] = contents;
+	d = &l->dir[l->ndir];
 	strcpy(d->name, name);
 	strcpy(d->name, name);
 	d->length = len;
 	d->length = len;
 	d->perm = perm;
 	d->perm = perm;
 	d->qid.type = 0;
 	d->qid.type = 0;
 	d->qid.vers = 0;
 	d->qid.vers = 0;
-	d->qid.path = nroot+1;
+	d->qid.path = ++l->ndir + l->base;
 	if(perm & DMDIR)
 	if(perm & DMDIR)
 		d->qid.type |= QTDIR;
 		d->qid.type |= QTDIR;
-	nroot++;
 }
 }
 
 
 /*
 /*
  *  add a root file
  *  add a root file
  */
  */
 void
 void
-addrootfile(char *name, uchar *contents, ulong len)
+addbootfile(char *name, uchar *contents, ulong len)
 {
 {
-	addroot(name, contents, len, 0555);
+	addlist(&bootlist, name, contents, len, 0555);
 }
 }
 
 
 /*
 /*
- *  add a root file
+ *  add a root directory
  */
  */
 static void
 static void
 addrootdir(char *name)
 addrootdir(char *name)
 {
 {
-	addroot(name, nil, 0, DMDIR|0555);
+	addlist(&rootlist, name, nil, 0, DMDIR|0555);
 }
 }
 
 
 static void
 static void
@@ -75,8 +104,6 @@ rootreset(void)
 	addrootdir("proc");
 	addrootdir("proc");
 	addrootdir("root");
 	addrootdir("root");
 	addrootdir("srv");
 	addrootdir("srv");
-
-	addrootfile("boot", bootcode, bootlen);	/* always have a boot file */
 }
 }
 
 
 static Chan*
 static Chan*
@@ -85,27 +112,57 @@ rootattach(char *spec)
 	return devattach('/', spec);
 	return devattach('/', spec);
 }
 }
 
 
+static int
+rootgen(Chan *c, char *name, Dirtab*, int, int s, Dir *dp)
+{
+	int t;
+	Dirtab *d;
+	Dirlist *l;
+
+	switch((int)c->qid.path){
+	case Qdir:
+		return devgen(c, name, rootlist.dir, rootlist.ndir, s, dp);
+	case Qboot:
+		if(s == DEVDOTDOT){
+			devdir(c, (Qid){Qdir, 0, QTDIR}, "#/", 0, eve, 0555, dp);
+			return 1;
+		}
+		return devgen(c, name, bootlist.dir, bootlist.ndir, s, dp);
+	default:
+		if((int)c->qid.path < Qboot){
+			t = c->qid.path-1;
+			l = &rootlist;
+		}else{
+			t = c->qid.path - Qboot - 1;
+			l = &bootlist;
+		}
+		if(t >= l->ndir)
+			return -1;
+		if(s != 0)
+			return -1;
+		d = &l->dir[t];
+		devdir(c, d->qid, d->name, d->length, eve, d->perm, dp);
+		return 1;
+	}
+	return -1;
+}
+
 static Walkqid*
 static Walkqid*
 rootwalk(Chan *c, Chan *nc, char **name, int nname)
 rootwalk(Chan *c, Chan *nc, char **name, int nname)
 {
 {
-	return devwalk(c,  nc, name, nname, rootdir, nroot, devgen);
+	return devwalk(c,  nc, name, nname, nil, 0, rootgen);
 }
 }
 
 
 static int
 static int
 rootstat(Chan *c, uchar *dp, int n)
 rootstat(Chan *c, uchar *dp, int n)
 {
 {
-	return devstat(c, dp, n, rootdir, nroot, devgen);
+	return devstat(c, dp, n, nil, 0, rootgen);
 }
 }
 
 
 static Chan*
 static Chan*
 rootopen(Chan *c, int omode)
 rootopen(Chan *c, int omode)
 {
 {
-	switch((ulong)c->qid.path) {
-	default:
-		break;
-	}
-
-	return devopen(c, omode, rootdir, nroot, devgen);
+	return devopen(c, omode, nil, 0, devgen);
 }
 }
 
 
 /*
 /*
@@ -121,17 +178,26 @@ rootread(Chan *c, void *buf, long n, vlong off)
 {
 {
 	ulong t;
 	ulong t;
 	Dirtab *d;
 	Dirtab *d;
+	Dirlist *l;
 	uchar *data;
 	uchar *data;
 	ulong offset = off;
 	ulong offset = off;
 
 
 	t = c->qid.path;
 	t = c->qid.path;
 	switch(t){
 	switch(t){
 	case Qdir:
 	case Qdir:
-		return devdirread(c, buf, n, rootdir, nroot, devgen);
+	case Qboot:
+		return devdirread(c, buf, n, nil, 0, rootgen);
+	}
+
+	if(t<Qboot)
+		l = &rootlist;
+	else{
+		t -= Qboot;
+		l = &bootlist;
 	}
 	}
 
 
-	d = &rootdir[t-1];
-	data = rootdata[t-1];
+	d = &l->dir[t-1];
+	data = l->data[t-1];
 	if(offset >= d->length)
 	if(offset >= d->length)
 		return 0;
 		return 0;
 	if(offset+n > d->length)
 	if(offset+n > d->length)
@@ -141,12 +207,9 @@ rootread(Chan *c, void *buf, long n, vlong off)
 }
 }
 
 
 static long
 static long
-rootwrite(Chan *c, void*, long, vlong)
+rootwrite(Chan*, void*, long, vlong)
 {
 {
-	switch((ulong)c->qid.path){
-	default:
-		error(Egreg);
-	}
+	error(Egreg);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -170,3 +233,4 @@ Dev rootdevtab = {
 	devremove,
 	devremove,
 	devwstat,
 	devwstat,
 };
 };
+

+ 26 - 0
sys/src/9/port/initcode.c

@@ -0,0 +1,26 @@
+#include <u.h>
+#include <libc.h>
+
+char cons[] = "#c/cons";
+char boot[] = "/boot/boot";
+char dev[] = "/dev";
+char c[] = "#c";
+char e[] = "#e";
+char ec[] = "#ec";
+char s[] = "#s";
+char srv[] = "/srv";
+char env[] = "/env";
+
+void
+main(void)
+{
+	open(cons, OREAD);
+	open(cons, OWRITE);
+	open(cons, OWRITE);
+	bind(c, dev, MAFTER);
+	bind(ec, env, MAFTER);
+	bind(e, env, MCREATE|MAFTER);
+	bind(s, srv, MREPL|MCREATE);
+	execl(boot, boot, nil);
+	for(;;);
+}

+ 26 - 0
sys/src/9/port/mkbootrules

@@ -0,0 +1,26 @@
+#!/bin/rc
+
+awk -v 'objtype='$objtype '
+/^$/{
+		next;
+}
+/^#/{
+		next;
+}
+collect && /^[^ \t]/{
+		collect = 0;
+}
+collect && section ~ "bootdir"{
+		x = $1;
+		gsub(/[^a-zA-Z0-9_]/, "_", x);
+		printf "%s.root.s: %s\n\t../port/mkroot %s %s\n", x, $1, $1, x;
+}
+$0 ~ /^[^ \t]/{
+		if($0 ~ "bootdir"){
+			section = $0;
+			collect = 1;
+		}
+		next;
+}
+
+' $*

+ 17 - 2
sys/src/9/port/mkdevc

@@ -2,6 +2,7 @@
 
 
 awk -v 'objtype='$objtype '
 awk -v 'objtype='$objtype '
 BEGIN{
 BEGIN{
+		nfs = 0;
 		if(ARGC < 2)
 		if(ARGC < 2)
 			exit
 			exit
 }
 }
@@ -50,14 +51,28 @@ collect && section ~ "misc"{
 				x = "kfs";
 				x = "kfs";
 			if(x ~ "nfactotum")
 			if(x ~ "nfactotum")
 				x = "factotum";
 				x = "factotum";
+			fsname[nfs] = x;
 			fs[nfs++] = x;
 			fs[nfs++] = x;
 		}
 		}
 }
 }
+collect && section ~ "bootdir"{
+		if(NF >= 2)
+			x = $2;
+		else{
+			x = $1;
+			sub(/.*\//, "", x);
+		}
+		fsname[nfs] = x;
+		x = $1;
+		gsub(/[^a-zA-Z0-9_]/, "_", x);
+		fs[nfs++] = x;
+}
+
 collect && section ~ "port"{
 collect && section ~ "port"{
 		port[nport++] = $0;
 		port[nport++] = $0;
 }
 }
 $0 ~ /^[^ \t]/{
 $0 ~ /^[^ \t]/{
-		if($0 ~ "(dev|ip|link|misc|port)"){
+		if($0 ~ "(bootdir|dev|ip|link|misc|port)"){
 			section = $0;
 			section = $0;
 			collect = 1;
 			collect = 1;
 		}
 		}
@@ -93,7 +108,7 @@ END{
 
 
 		printf "void links(void){\n";
 		printf "void links(void){\n";
 		for(i = 0; i < nfs; i++)
 		for(i = 0; i < nfs; i++)
-			printf "\taddrootfile(\"%s\", %scode, %slen);\n", fs[i], fs[i], fs[i];
+			printf "\taddbootfile(\"%s\", %scode, %slen);\n", fsname[i], fs[i], fs[i];
 		for(i = 0; i < nlink; i++)
 		for(i = 0; i < nlink; i++)
 			printf "\t%slink();\n", link[i];
 			printf "\t%slink();\n", link[i];
 		printf "}\n\n";
 		printf "}\n\n";

+ 13 - 2
sys/src/9/port/mkdevlist

@@ -1,7 +1,7 @@
 #!/bin/rc
 #!/bin/rc
 
 
 awk '
 awk '
-BEGIN{		collect = isdev = 0;
+BEGIN{		collect = isdev = isbootdir = 0;
 }
 }
 
 
 /^$/{		next;
 /^$/{		next;
@@ -9,9 +9,15 @@ BEGIN{		collect = isdev = 0;
 /^#/{		next;
 /^#/{		next;
 }
 }
 collect && /^[^	\t]/{
 collect && /^[^	\t]/{
-		collect = isdev = 0;
+		collect = isdev = isbootdir = 0;
 }
 }
 collect && $0 ~ /[^ \t]+/{
 collect && $0 ~ /[^ \t]+/{
+		if(isbootdir){
+			x = $1;
+			gsub(/[^a-zA-Z0-9_]/, "_", x);
+			obj[x ".root.'$O'"]++;
+			next;
+		}
 		if(isdev)
 		if(isdev)
 			obj["dev" $1 "'.$O'"]++;
 			obj["dev" $1 "'.$O'"]++;
 		else
 		else
@@ -28,10 +34,15 @@ $0 ~ /^[^ \t]/{
 		}
 		}
 		else if($1 ~ "misc" || $1 ~ "link" || $1 ~ "ip")
 		else if($1 ~ "misc" || $1 ~ "link" || $1 ~ "ip")
 			collect = 1;
 			collect = 1;
+		else if($1 ~ "bootdir"){
+			isbootdir = 1;
+			collect = 1;
+		}
 		next
 		next
 }
 }
 
 
 END{
 END{
+		x = ""
 		for(i in obj)
 		for(i in obj)
 			x = x i "\n"
 			x = x i "\n"
 		printf x
 		printf x

+ 1 - 1
sys/src/9/port/mkextract

@@ -25,7 +25,7 @@ fn select {
 		/^#/			{ next }
 		/^#/			{ next }
 		doprint && /^[^	]/	{ doprint=0 }
 		doprint && /^[^	]/	{ doprint=0 }
 		doprint			{ print $'^$n^' }
 		doprint			{ print $'^$n^' }
-		$0 ~ "^'^$field^'"	{ doprint=1; next }
+		$1 ~ "^'^$field^'$"	{ doprint=1; next }
 	' $*
 	' $*
 }
 }
 
 

+ 8 - 3
sys/src/9/port/mkroot

@@ -1,10 +1,15 @@
 #!/bin/rc
 #!/bin/rc
 
 
+rfork e
 echo mkroot $*
 echo mkroot $*
 if(! ~ $#* 2){
 if(! ~ $#* 2){
-	echo usage: mkroot file name >[2=1]
+	echo usage: mkroot path name >[2=1]
 	exit 1
 	exit 1
 }
 }
-strip $1.out
-aux/data2s $2 < $1.out > $1.root.s
+n=`{basename $1}
+cp $1 $2.out
+t=`{file $2.out}
+if(~ $"t *executable*)
+	strip $2.out
+aux/data2s $2 < $2.out > $2.root.s
 echo mkroot $* done
 echo mkroot $* done

+ 1 - 1
sys/src/9/port/portfns.h

@@ -1,7 +1,7 @@
 void		accounttime(void);
 void		accounttime(void);
 void		addclock0link(void (*)(void), int);
 void		addclock0link(void (*)(void), int);
 int		addphysseg(Physseg*);
 int		addphysseg(Physseg*);
-void		addrootfile(char*, uchar*, ulong);
+void		addbootfile(char*, uchar*, ulong);
 Block*		adjustblock(Block*, int);
 Block*		adjustblock(Block*, int);
 void		alarmkproc(void*);
 void		alarmkproc(void*);
 Block*		allocb(int);
 Block*		allocb(int);

+ 10 - 49
sys/src/9/port/portmkfile

@@ -30,7 +30,7 @@ all:V:
 		mk 'CONF='$i
 		mk 'CONF='$i
 
 
 clean:V:
 clean:V:
-	rm -f *.[$OS] *.root.s cfs.h fs.h init.h conf.h *.out
+	rm -f *.[$OS] *.root.s cfs.h fs.h init.h conf.h *.out factotum.hack ipconfig.hack
 	for(i in $CONFLIST)
 	for(i in $CONFLIST)
 		mk $i.clean
 		mk $i.clean
 
 
@@ -77,54 +77,15 @@ unthwack.$O:	../port/thwack.h
 devsdp.$O:	../port/thwack.h
 devsdp.$O:	../port/thwack.h
 devrealtime.$O edf.$O realtime.$O: ../port/edf.h
 devrealtime.$O edf.$O realtime.$O: ../port/edf.h
 
 
-nkfs.root.s:	/$objtype/bin/disk/nkfs
-	cp $prereq nkfs.out
-	../port/mkroot nkfs kfs
-
-dossrv.root.s:	/$objtype/bin/dossrv
-	cp $prereq dossrv.out
-	../port/mkroot dossrv kfs
-
-bzfs.root.s: /sys/lib/dist/bin/$objtype/bzfs
-	cp $prereq bzfs.out
-	../port/mkroot bzfs kfs
-
-bzroot.root.s: /sys/lib/dist/pc/root.bz2
-	aux/data2s bzroot < /sys/lib/dist/pc/root.bz2 > bzroot.root.s
-
-9660srv.root.s: /$objtype/bin/9660srv
-	cp $prereq 9660srv.out	
-	../port/mkroot 9660srv kfs
-
-factotum.root.s:	/$objtype/bin/auth/factotum
-	cp $prereq factotum.out
-	../port/mkroot factotum factotum
-
-nfactotum.root.s: /$objtype/bin/auth/nfactotum
-	cp $prereq nfactotum.out
-	../port/mkroot nfactotum factotum
-
-rcmain.root.s: /rc/lib/rcmain
-	cp /rc/lib/rcmain rcmain.out
-	../port/mkroot rcmain rcmain
-
-%.root.s:	/$objtype/bin/%
-	cp $prereq $stem.out
-	../port/mkroot $stem $stem
-
-%.root.s:	/$objtype/bin/disk/%
-	cp $prereq $stem.out
-	../port/mkroot $stem $stem
-
-%.root.s:	/$objtype/bin/ip/%
-	cp $prereq $stem.out
-	../port/mkroot $stem $stem
-
-%.embed.root.s: ../embed/%
-	aux/data2s $stem < $prereq > $target
-
-boot$CONF.root.s: $CONF print.$O $BOOTDIR/boot.c $BOOTLIB
+boot$CONF.out: $CONF print.$O $BOOTDIR/boot.c $BOOTLIB
 	$BOOTDIR/mkboot $CONF > boot$CONF.c
 	$BOOTDIR/mkboot $CONF > boot$CONF.c
 	$CC $CFLAGS boot$CONF.c
 	$CC $CFLAGS boot$CONF.c
 	$LD -o boot$CONF.out boot$CONF.$O $BOOTLIB print.$O
 	$LD -o boot$CONF.out boot$CONF.$O $BOOTLIB print.$O
-	../port/mkroot boot$CONF boot
+
+# this lets us say "factotum.hack factotum" instead of "/386/bin/auth/factotum factotum"
+# in the kernel config files.  the latter won't work until we have long file names.
+factotum.hack: /$objtype/bin/auth/factotum
+	cp $prereq $target
+
+ipconfig.hack: /$objtype/bin/ip/ipconfig
+	cp $prereq $target

+ 2 - 2
sys/src/cmd/crop.c

@@ -52,7 +52,7 @@ crop(Memimage *m, ulong c)
 		n = allocmemimage(m->r, RGBA32);
 		n = allocmemimage(m->r, RGBA32);
 		if(n == nil)
 		if(n == nil)
 			sysfatal("can't allocate temporary image: %r");
 			sysfatal("can't allocate temporary image: %r");
-		memimagedraw(n, n->r, m, m->r.min, nil, ZP);
+		memimagedraw(n, n->r, m, m->r.min, nil, ZP, S);
 		m = n;
 		m = n;
 	}
 	}
 	wpl = wordsperline(m->r, m->depth);
 	wpl = wordsperline(m->r, m->depth);
@@ -201,7 +201,7 @@ main(int argc, char *argv[])
 	else
 	else
 		memfillcolor(new, 0x000000FF);
 		memfillcolor(new, 0x000000FF);
 
 
-	memimagedraw(new, m->clipr, m, m->clipr.min, nil, ZP);
+	memimagedraw(new, m->clipr, m, m->clipr.min, nil, ZP, S);
 	dw = byteaddr(new, ZP) - byteaddr(new, t);
 	dw = byteaddr(new, ZP) - byteaddr(new, t);
 	new->r = rectaddpt(new->r, t);
 	new->r = rectaddpt(new->r, t);
 	new->zero += dw;
 	new->zero += dw;

+ 1 - 2
sys/src/cmd/exportfs/exportfs.c

@@ -211,9 +211,8 @@ main(int argc, char **argv)
 	if(srv == nil && srvfd == -1 && write(0, "OK", 2) != 2)
 	if(srv == nil && srvfd == -1 && write(0, "OK", 2) != 2)
 		fatal("open ack write");
 		fatal("open ack write");
 
 
-	if ((n = readn(netfd, &initial, sizeof(ulong))) < 0)
+	if (readn(netfd, &initial, sizeof(ulong)) < sizeof(ulong))
 		fatal("can't read initial string: %r\n");
 		fatal("can't read initial string: %r\n");
-	assert(n == sizeof(ulong));
 
 
 	if (!strncmp((char *)&initial, "impo", sizeof(ulong))) {
 	if (!strncmp((char *)&initial, "impo", sizeof(ulong))) {
 		char buf[128], *p, *args[3];
 		char buf[128], *p, *args[3];

+ 20 - 8
sys/src/cmd/fax/mkfile

@@ -3,23 +3,35 @@
 TARG =	faxreceive\
 TARG =	faxreceive\
 	faxsend\
 	faxsend\
 
 
-RECEIVE=\
+OFILES=\
 	fax2modem.$O\
 	fax2modem.$O\
-	fax2receive.$O\
 	file.$O\
 	file.$O\
-	receive.$O\
 	modem.$O\
 	modem.$O\
 	subr.$O\
 	subr.$O\
 
 
+RECEIVE=\
+	$OFILES\
+	receive.$O\
+	fax2receive.$O\
+
 SEND=\
 SEND=\
-	fax2modem.$O\
-	fax2send.$O\
-	file.$O\
+	$OFILES\
 	send.$O\
 	send.$O\
-	modem.$O\
-	subr.$O\
+	fax2send.$O\
 
 
 BIN=/$objtype/bin/aux
 BIN=/$objtype/bin/aux
+
+UPDATE=\
+	mkfile\
+	$HFILES\
+	${OFILES:%.$O=%.c}\
+	receive.c\
+	send.c\
+	fax2receive.c\
+	fax2send.c\
+	${TARG:%=%.c}\
+	${TARG:%=/386/bin/%}\
+
 </sys/src/cmd/mkmany
 </sys/src/cmd/mkmany
 
 
 $O.faxreceive: $RECEIVE
 $O.faxreceive: $RECEIVE

+ 1 - 1
sys/src/cmd/iconv.c

@@ -93,7 +93,7 @@ main(int argc, char *argv[])
 	if(n == nil)
 	if(n == nil)
 		sysfatal("can't allocate new image: %r");
 		sysfatal("can't allocate new image: %r");
 
 
-	memimagedraw(n, n->r, m, m->r.min, nil, ZP);
+	memimagedraw(n, n->r, m, m->r.min, nil, ZP, S);
 	if(uncompressed)
 	if(uncompressed)
 		writeuncompressed(1, n);
 		writeuncompressed(1, n);
 	else
 	else

+ 1 - 1
sys/src/cmd/jpg/multichan.c

@@ -49,6 +49,6 @@ memmultichan(Memimage *i)
 	ni = allocmemimage(i->r, RGB24);
 	ni = allocmemimage(i->r, RGB24);
 	if(ni == nil)
 	if(ni == nil)
 		return ni;
 		return ni;
-	memimagedraw(ni, ni->r, i, i->r.min, nil, i->r.min);
+	memimagedraw(ni, ni->r, i, i->r.min, nil, i->r.min, S);
 	return ni;
 	return ni;
 }
 }

+ 1 - 1
sys/src/cmd/jpg/onechan.c

@@ -210,7 +210,7 @@ memonechan(Memimage *i)
 		ni = allocmemimage(i->r, RGB24);
 		ni = allocmemimage(i->r, RGB24);
 		if(ni == nil)
 		if(ni == nil)
 			return ni;
 			return ni;
-		memimagedraw(ni, ni->r, i, i->r.min, nil, ZP);
+		memimagedraw(ni, ni->r, i, i->r.min, nil, ZP, S);
 		data = load(nil, ni);
 		data = load(nil, ni);
 		freememimage(ni);
 		freememimage(ni);
 	}
 	}

+ 1 - 1
sys/src/cmd/jpg/writepng.c

@@ -134,7 +134,7 @@ memRGB(Memimage *i)
 	ni = allocmemimage(i->r, RGB24);
 	ni = allocmemimage(i->r, RGB24);
 	if(ni == nil)
 	if(ni == nil)
 		return ni;
 		return ni;
-	memimagedraw(ni, ni->r, i, i->r.min, nil, i->r.min);
+	memimagedraw(ni, ni->r, i, i->r.min, nil, i->r.min, S);
 	return ni;
 	return ni;
 }
 }
 
 

+ 2 - 2
sys/src/cmd/postscript/p9bitpost/pslib.c

@@ -665,7 +665,7 @@ imagebits(Biobuf *ioutb, Memimage *im)
 			fprint(2, "p9bitpost: allocmemimage failed: %r\n");
 			fprint(2, "p9bitpost: allocmemimage failed: %r\n");
 			exits("alloc");
 			exits("alloc");
 		}
 		}
-		memimagedraw(tmp, r, im, im->r.min, nil, ZP);
+		memimagedraw(tmp, r, im, im->r.min, nil, ZP, S);
 		im = tmp;
 		im = tmp;
 	}
 	}
 	lsf = 0;
 	lsf = 0;
@@ -732,7 +732,7 @@ image2psfile(int fd, Memimage *im, int dpi) {
 		tmp = allocmemimage(im->r, strtochan("b8g8r8"));
 		tmp = allocmemimage(im->r, strtochan("b8g8r8"));
 		if(tmp == nil)
 		if(tmp == nil)
 			return 1;
 			return 1;
-		memimagedraw(tmp, tmp->r, im, im->r.min, nil, ZP);
+		memimagedraw(tmp, tmp->r, im, im->r.min, nil, ZP, S);
 		freememimage(im);
 		freememimage(im);
 		im = tmp;
 		im = tmp;
 	}
 	}

+ 2 - 2
sys/src/cmd/resample.c

@@ -304,14 +304,14 @@ main(int argc, char *argv[])
 		t1 = allocmemimage(m->r, tchan);
 		t1 = allocmemimage(m->r, tchan);
 		if(t1 == nil)
 		if(t1 == nil)
 			sysfatal("can't allocate temporary image: %r");
 			sysfatal("can't allocate temporary image: %r");
-		memimagedraw(t1, t1->r, m, m->r.min, nil, ZP);
+		memimagedraw(t1, t1->r, m, m->r.min, nil, ZP, S);
 		t2 = resample(xsize, ysize, t1);
 		t2 = resample(xsize, ysize, t1);
 		freememimage(t1);
 		freememimage(t1);
 		new = allocmemimage(Rect(0, 0, xsize, ysize), m->chan);
 		new = allocmemimage(Rect(0, 0, xsize, ysize), m->chan);
 		if(new == nil)
 		if(new == nil)
 			sysfatal("can't allocate new image: %r");
 			sysfatal("can't allocate new image: %r");
 		/* should do error diffusion here */
 		/* should do error diffusion here */
-		memimagedraw(new, new->r, t2, t2->r.min, nil, ZP);
+		memimagedraw(new, new->r, t2, t2->r.min, nil, ZP, S);
 		freememimage(t2);
 		freememimage(t2);
 		break;
 		break;
 
 

+ 25 - 0
sys/src/cmd/venti/backup.example

@@ -0,0 +1,25 @@
+#!/bin/rc
+
+rfork e
+cd /usr/rsc
+. bkup.info
+fn x {
+	echo x $*
+	y=$1
+	if(~ $#$y 0){
+		$y=0
+	}
+	echo venti/wrarena -o $2 $3 $$y
+	end=`{venti/wrarena -o $2 $3 $$y | grep '^end offset ' | sed 's/^end offset //'}
+	if(~ $#end 1 && ! ~ $$y $end){
+		$y=$end
+		whatis $y >>bkup.info
+	}
+}
+hget http://127.1:8000/index | 
+awk '
+/^index=/ { blockSize=0+substr($3, 11); }
+/^arena=/ { arena=substr($1, 7); }
+/^	arena=/ { start=0+substr($5, 2)-blockSize; printf("x %s %d %s\n", arena, start, $3); }
+' |rc
+

+ 181 - 0
sys/src/cmd/venti/copy.c

@@ -0,0 +1,181 @@
+#include "stdinc.h"
+#include "dat.h"
+#include "fns.h"
+
+int fast;
+
+VtSession *zsrc, *zdst;
+
+void
+usage(void)
+{
+	fprint(2, "usage: copy src-host dst-host score [type]\n");
+	exits("usage");
+}
+
+int
+parseScore(uchar *score, char *buf, int n)
+{
+	int i, c;
+
+	memset(score, 0, VtScoreSize);
+
+	if(n < VtScoreSize*2)
+		return 0;
+	for(i=0; i<VtScoreSize*2; i++) {
+		if(buf[i] >= '0' && buf[i] <= '9')
+			c = buf[i] - '0';
+		else if(buf[i] >= 'a' && buf[i] <= 'f')
+			c = buf[i] - 'a' + 10;
+		else if(buf[i] >= 'A' && buf[i] <= 'F')
+			c = buf[i] - 'A' + 10;
+		else {
+			return 0;
+		}
+
+		if((i & 1) == 0)
+			c <<= 4;
+	
+		score[i>>1] |= c;
+	}
+	return 1;
+}
+
+void
+walk(uchar score[VtScoreSize], uint type, int base)
+{
+	int i, n, sub;
+	uchar *buf;
+	VtEntry e;
+	VtRoot root;
+
+	if(memcmp(score, vtZeroScore, VtScoreSize) == 0)
+		return;
+
+	buf = vtMemAllocZ(VtMaxLumpSize);
+	if(fast && vtRead(zdst, score, type, buf, VtMaxLumpSize) >= 0){
+		fprint(2, "skip %V\n", score);
+		free(buf);
+		return;
+	}
+
+	n = vtRead(zsrc, score, type, buf, VtMaxLumpSize);
+	if(n < 0){
+		fprint(2, "warning: could not read block %V %d: %R", score, type);
+		return;
+	}
+
+	switch(type){
+	case VtRootType:
+		if(!vtRootUnpack(&root, buf)){
+			fprint(2, "warning: could not unpack root in %V %d\n", score, type);
+			break;
+		}
+		walk(root.score, VtDirType, 0);
+		walk(root.prev, VtRootType, 0);
+		break;
+
+	case VtDirType:
+		for(i=0; i<n/VtEntrySize; i++){
+			if(!vtEntryUnpack(&e, buf, i)){
+				fprint(2, "warning: could not unpack entry #%d in %V %d\n", i, score, type);
+				continue;
+			}
+			if(!(e.flags & VtEntryActive))
+				continue;
+			if(e.flags&VtEntryDir)
+				base = VtDirType;
+			else
+				base = VtDataType;
+			if(e.depth == 0)
+				sub = base;
+			else
+				sub = VtPointerType0+e.depth-1;
+			walk(e.score, sub, base);
+		}
+		break;
+
+	case VtDataType:
+		break;
+
+	default:	/* pointers */
+		if(type == VtPointerType0)
+			sub = base;
+		else
+			sub = type-1;
+		for(i=0; i<n; i+=VtScoreSize)
+			if(memcmp(buf+i, vtZeroScore, VtScoreSize) != 0)
+				walk(buf+i, sub, base);
+		break;
+	}
+
+	if(!vtWrite(zdst, score, type, buf, n))
+		fprint(2, "warning: could not write block %V %d: %R", score, type);
+	free(buf);
+}
+
+int
+main(int argc, char *argv[])
+{
+	int type, n;
+	uchar score[VtScoreSize];
+	uchar *buf;
+
+	ARGBEGIN{
+	case 'f':
+		fast = 1;
+		break;
+	default:
+		usage();
+		break;
+	}ARGEND
+
+	if(argc != 3 && argc != 4)
+		usage();
+
+	vtAttach();
+
+	fmtinstall('V', vtScoreFmt);
+	fmtinstall('R', vtErrFmt);
+
+	if(!parseScore(score, argv[2], strlen(argv[2])))
+		vtFatal("could not parse score: %s", vtGetError());
+
+	buf = vtMemAllocZ(VtMaxLumpSize);
+
+	zsrc = vtDial(argv[0], 0);
+	if(zsrc == nil)
+		vtFatal("could not dial src server: %R");
+	if(!vtConnect(zsrc, 0))
+		sysfatal("vtConnect src: %r");
+
+	zdst = vtDial(argv[1], 0);
+	if(zdst == nil)
+		vtFatal("could not dial dst server: %R");
+	if(!vtConnect(zdst, 0))
+		sysfatal("vtConnect dst: %r");
+
+	if(argc == 4){
+		type = atoi(argv[3]);
+		n = vtRead(zsrc, score, type, buf, VtMaxLumpSize);
+		if(n < 0)
+			vtFatal("could not read block: %R");
+	}else{
+		for(type=0; type<VtMaxType; type++){
+			n = vtRead(zsrc, score, type, buf, VtMaxLumpSize);
+			if(n >= 0)
+				break;
+		}
+		if(type == VtMaxType)
+			vtFatal("could not find block %V of any type", score);
+	}
+
+	walk(score, type, VtDirType);
+
+	if(!vtSync(zdst))
+		vtFatal("could not sync dst server: %R");
+
+	vtDetach();
+	exits(0);
+	return 0;	/* shut up compiler */
+}

+ 1 - 0
sys/src/cmd/venti/mkfile

@@ -61,6 +61,7 @@ TARG=\
 	sync\
 	sync\
 	read\
 	read\
 	write\
 	write\
+	copy\
 #	dumparena\
 #	dumparena\
 
 
 CFILES=${TARG:%=%.c} $LIBCFILES
 CFILES=${TARG:%=%.c} $LIBCFILES

+ 16 - 7
sys/src/cmd/venti/read.c

@@ -7,7 +7,7 @@ char *host;
 void
 void
 usage(void)
 usage(void)
 {
 {
-	fprint(2, "usage: read [-h host] [-t type] score\n");
+	fprint(2, "usage: read [-h host] score [type]\n");
 	exits("usage");
 	exits("usage");
 }
 }
 
 
@@ -47,20 +47,16 @@ main(int argc, char *argv[])
 	uchar *buf;
 	uchar *buf;
 	VtSession *z;
 	VtSession *z;
 
 
-	type = VtDataType;
 	ARGBEGIN{
 	ARGBEGIN{
 	case 'h':
 	case 'h':
 		host = EARGF(usage());
 		host = EARGF(usage());
 		break;
 		break;
-	case 't':
-		type = atoi(EARGF(usage()));
-		break;
 	default:
 	default:
 		usage();
 		usage();
 		break;
 		break;
 	}ARGEND
 	}ARGEND
 
 
-	if(argc != 1)
+	if(argc != 1 && argc != 2)
 		usage();
 		usage();
 
 
 	vtAttach();
 	vtAttach();
@@ -80,7 +76,20 @@ main(int argc, char *argv[])
 	if(!vtConnect(z, 0))
 	if(!vtConnect(z, 0))
 		sysfatal("vtConnect: %r");
 		sysfatal("vtConnect: %r");
 
 
-	n = vtRead(z, score, type, buf, VtMaxLumpSize);
+	if(argc == 1){
+		n = -1;
+		for(type=0; type<VtMaxType; type++){
+			n = vtRead(z, score, type, buf, VtMaxLumpSize);
+			if(n >= 0){
+				fprint(2, "venti/read%s%s %V %d\n", host ? " -h" : "", host ? host : "",
+					score, type);
+				break;
+			}
+		}
+	}else{
+		type = atoi(argv[1]);
+		n = vtRead(z, score, type, buf, VtMaxLumpSize);
+	}
 	vtClose(z);
 	vtClose(z);
 	if(n < 0)
 	if(n < 0)
 		vtFatal("could not read block: %s", vtGetError());
 		vtFatal("could not read block: %s", vtGetError());

+ 1 - 0
sys/src/cmd/vl/l.h

@@ -203,6 +203,7 @@ EXTERN	long	datsize;
 EXTERN	char	debug[128];
 EXTERN	char	debug[128];
 EXTERN	Prog*	etextp;
 EXTERN	Prog*	etextp;
 EXTERN	Prog*	firstp;
 EXTERN	Prog*	firstp;
+EXTERN	char	fnuxi4[4];	/* for 3l [sic] */
 EXTERN	char	fnuxi8[8];
 EXTERN	char	fnuxi8[8];
 EXTERN	char*	noname;
 EXTERN	char*	noname;
 EXTERN	Sym*	hash[NHASH];
 EXTERN	Sym*	hash[NHASH];

+ 49 - 15
sys/src/cmd/vnc/devdraw.c

@@ -77,6 +77,7 @@ struct Client
 	int		slot;
 	int		slot;
 	int		refreshme;
 	int		refreshme;
 	int		infoid;
 	int		infoid;
+	int		op;
 };
 };
 
 
 struct Refresh
 struct Refresh
@@ -774,10 +775,21 @@ drawnewclient(void)
 	memset(cl, 0, sizeof(Client));
 	memset(cl, 0, sizeof(Client));
 	cl->slot = i;
 	cl->slot = i;
 	cl->clientid = ++sdraw.clientid;
 	cl->clientid = ++sdraw.clientid;
+	cl->op = SoverD;
 	sdraw.client[i] = cl;
 	sdraw.client[i] = cl;
 	return cl;
 	return cl;
 }
 }
 
 
+static int
+drawclientop(Client *cl)
+{
+	int op;
+
+	op = cl->op;
+	cl->op = SoverD;
+	return op;
+}
+
 int
 int
 drawhasclients(void)
 drawhasclients(void)
 {
 {
@@ -844,7 +856,7 @@ drawpoint(Point *p, uchar *a)
 }
 }
 
 
 Point
 Point
-drawchar(Memimage *dst, Point p, Memimage *src, Point *sp, DImage *font, int index)
+drawchar(Memimage *dst, Point p, Memimage *src, Point *sp, DImage *font, int index, int op)
 {
 {
 	FChar *fc;
 	FChar *fc;
 	Rectangle r;
 	Rectangle r;
@@ -857,7 +869,7 @@ drawchar(Memimage *dst, Point p, Memimage *src, Point *sp, DImage *font, int ind
 	r.max.y = r.min.y+(fc->maxy-fc->miny);
 	r.max.y = r.min.y+(fc->maxy-fc->miny);
 	sp1.x = sp->x+fc->left;
 	sp1.x = sp->x+fc->left;
 	sp1.y = sp->y+fc->miny;
 	sp1.y = sp->y+fc->miny;
-	memdraw(dst, r, src, sp1, font->image, Pt(fc->minx, fc->miny));
+	memdraw(dst, r, src, sp1, font->image, Pt(fc->minx, fc->miny), op);
 	p.x += fc->width;
 	p.x += fc->width;
 	sp->x += fc->width;
 	sp->x += fc->width;
 	return p;
 	return p;
@@ -1299,7 +1311,7 @@ printmesg(char *fmt, uchar *a, int plsprnt)
 void
 void
 drawmesg(Client *client, void *av, int n)
 drawmesg(Client *client, void *av, int n)
 {
 {
-	int c, repl, m, y, dstid, scrnid, ni, ci, j, nw, e0, e1, ox, oy, esize, doflush;
+	int c, repl, m, y, dstid, scrnid, ni, ci, j, nw, e0, e1, op, ox, oy, oesize, esize, doflush;
 	uchar *u, *a, refresh;
 	uchar *u, *a, refresh;
 	char *fmt;
 	char *fmt;
 	ulong value, chan;
 	ulong value, chan;
@@ -1454,7 +1466,8 @@ drawmesg(Client *client, void *av, int n)
 			drawrectangle(&r, a+13);
 			drawrectangle(&r, a+13);
 			drawpoint(&p, a+29);
 			drawpoint(&p, a+29);
 			drawpoint(&q, a+37);
 			drawpoint(&q, a+37);
-			memdraw(dst, r, src, p, mask, q);
+			op = drawclientop(client);
+			memdraw(dst, r, src, p, mask, q, op);
 			dstflush(dstid, dst, r);
 			dstflush(dstid, dst, r);
 			continue;
 			continue;
 
 
@@ -1491,13 +1504,14 @@ drawmesg(Client *client, void *av, int n)
 				c = -1;
 				c = -1;
 			ox = BGLONG(a+37);
 			ox = BGLONG(a+37);
 			oy = BGLONG(a+41);
 			oy = BGLONG(a+41);
+			op = drawclientop(client);
 			/* high bit indicates arc angles are present */
 			/* high bit indicates arc angles are present */
 			if(ox & (1<<31)){
 			if(ox & (1<<31)){
 				if((ox & (1<<30)) == 0)
 				if((ox & (1<<30)) == 0)
 					ox &= ~(1<<31);
 					ox &= ~(1<<31);
-				memarc(dst, p, e0, e1, c, src, sp, ox, oy);
+				memarc(dst, p, e0, e1, c, src, sp, ox, oy, op);
 			}else
 			}else
-				memellipse(dst, p, e0, e1, c, src, sp);
+				memellipse(dst, p, e0, e1, c, src, sp, op);
 			dstflush(dstid, dst, Rect(p.x-e0-j, p.y-e1-j, p.x+e0+j+1, p.y+e1+j+1));
 			dstflush(dstid, dst, Rect(p.x-e0-j, p.y-e1-j, p.x+e0+j+1, p.y+e1+j+1));
 			continue;
 			continue;
 
 
@@ -1564,7 +1578,7 @@ drawmesg(Client *client, void *av, int n)
 				error(Eindex);
 				error(Eindex);
 			drawrectangle(&r, a+11);
 			drawrectangle(&r, a+11);
 			drawpoint(&p, a+27);
 			drawpoint(&p, a+27);
-			memdraw(font->image, r, src, p, memopaque, p);
+			memdraw(font->image, r, src, p, memopaque, p, S);
 			fc = &font->fchar[ci];
 			fc = &font->fchar[ci];
 			fc->minx = r.min.x;
 			fc->minx = r.min.x;
 			fc->maxx = r.max.x;
 			fc->maxx = r.max.x;
@@ -1591,7 +1605,8 @@ drawmesg(Client *client, void *av, int n)
 				error("negative line width");
 				error("negative line width");
 			src = drawimage(client, a+33);
 			src = drawimage(client, a+33);
 			drawpoint(&sp, a+37);
 			drawpoint(&sp, a+37);
-			memline(dst, p, q, e0, e1, j, src, sp);
+			op = drawclientop(client);
+			memline(dst, p, q, e0, e1, j, src, sp, op);
 			/* avoid memlinebbox if possible */
 			/* avoid memlinebbox if possible */
 			if(dstid==0 || dst->layer!=nil){
 			if(dstid==0 || dst->layer!=nil){
 				/* BUG: this is terribly inefficient: update maximal containing rect*/
 				/* BUG: this is terribly inefficient: update maximal containing rect*/
@@ -1697,6 +1712,15 @@ drawmesg(Client *client, void *av, int n)
 			}
 			}
 			continue;
 			continue;
 
 
+		/* set compositing operator for next draw operation: 'O' op */
+		case 'O':
+			printmesg(fmt="b", a, 0);
+			m = 1+1;
+			if(n < m)
+				error(Eshortdraw);
+			client->op = a[1];
+			continue;
+
 		/* filled polygon: 'P' dstid[4] n[2] wind[4] ignore[2*4] srcid[4] sp[2*4] p0[2*4] dp[2*2*n] */
 		/* filled polygon: 'P' dstid[4] n[2] wind[4] ignore[2*4] srcid[4] sp[2*4] p0[2*4] dp[2*2*n] */
 		/* polygon: 'p' dstid[4] n[2] end0[4] end1[4] radius[4] srcid[4] sp[2*4] p0[2*4] dp[2*2*n] */
 		/* polygon: 'p' dstid[4] n[2] end0[4] end1[4] radius[4] srcid[4] sp[2*4] p0[2*4] dp[2*2*n] */
 		case 'p':
 		case 'p':
@@ -1729,8 +1753,11 @@ drawmesg(Client *client, void *av, int n)
 			if(dstid==0 || (dst->layer && dst->layer->screen->image->data == screenimage->data))
 			if(dstid==0 || (dst->layer && dst->layer->screen->image->data == screenimage->data))
 				doflush = 1;	/* simplify test in loop */
 				doflush = 1;	/* simplify test in loop */
 			ox = oy = 0;
 			ox = oy = 0;
+			esize = 0;
 			u = a+m;
 			u = a+m;
 			for(y=0; y<ni; y++){
 			for(y=0; y<ni; y++){
+				q = p;
+				oesize = esize;
 				u = drawcoord(u, a+n, ox, &p.x);
 				u = drawcoord(u, a+n, ox, &p.x);
 				u = drawcoord(u, a+n, oy, &p.y);
 				u = drawcoord(u, a+n, oy, &p.y);
 				ox = p.x;
 				ox = p.x;
@@ -1751,16 +1778,22 @@ drawmesg(Client *client, void *av, int n)
 					}
 					}
 					if(*a=='P' && e0!=1 && e0 !=~0)
 					if(*a=='P' && e0!=1 && e0 !=~0)
 						r = dst->clipr;
 						r = dst->clipr;
-					else
-						r = Rect(p.x-esize, p.y-esize, p.x+esize+1, p.y+esize+1);
-					dstflush(dstid, dst, r);
+					else if(y > 0){
+						r = Rect(q.x-oesize, q.y-oesize, q.x+oesize+1, q.y+oesize+1);
+						combinerect(&r, Rect(p.x-esize, p.y-esize, p.x+esize+1, p.y+esize+1));
+					}
+					if(rectclip(&r, dst->clipr))		/* should perhaps be an arg to dstflush */
+						dstflush(dstid, dst, r);
 				}
 				}
 				pp[y] = p;
 				pp[y] = p;
 			}
 			}
+			if(y == 1)
+				dstflush(dstid, dst, Rect(p.x-esize, p.y-esize, p.x+esize+1, p.y+esize+1));
+			op = drawclientop(client);
 			if(*a == 'p')
 			if(*a == 'p')
-				mempoly(dst, pp, ni, e0, e1, j, src, sp);
+				mempoly(dst, pp, ni, e0, e1, j, src, sp, op);
 			else
 			else
-				memfillpoly(dst, pp, ni, e0, src, sp);
+				memfillpoly(dst, pp, ni, e0, src, sp, op);
 			free(pp);
 			free(pp);
 			m = u-a;
 			m = u-a;
 			continue;
 			continue;
@@ -1820,6 +1853,7 @@ drawmesg(Client *client, void *av, int n)
 				error(Eshortdraw);
 				error(Eshortdraw);
 			clipr = dst->clipr;
 			clipr = dst->clipr;
 			dst->clipr = r;
 			dst->clipr = r;
+			op = drawclientop(client);
 			if(*a == 'x'){
 			if(*a == 'x'){
 				/* paint background */
 				/* paint background */
 				l = drawimage(client, a+47);
 				l = drawimage(client, a+47);
@@ -1838,7 +1872,7 @@ drawmesg(Client *client, void *av, int n)
 					r.max.x += font->fchar[ci].width;
 					r.max.x += font->fchar[ci].width;
 					u += 2;
 					u += 2;
 				}
 				}
-				memdraw(dst, r, l, q, memopaque, ZP);
+				memdraw(dst, r, l, q, memopaque, ZP, op);
 				u -= 2*ni;
 				u -= 2*ni;
 			}
 			}
 			q = p;
 			q = p;
@@ -1848,7 +1882,7 @@ drawmesg(Client *client, void *av, int n)
 					dst->clipr = clipr;
 					dst->clipr = clipr;
 					error(Eindex);
 					error(Eindex);
 				}
 				}
-				q = drawchar(dst, q, src, &sp, font, ci);
+				q = drawchar(dst, q, src, &sp, font, ci, op);
 				u += 2;
 				u += 2;
 			}
 			}
 			dst->clipr = clipr;
 			dst->clipr = clipr;

+ 5 - 1
sys/src/cmd/vnc/kbd_vwr.c

@@ -113,8 +113,12 @@ readkbd(Vnc *v)
 				keyevent(v, Xctl, 1);
 				keyevent(v, Xctl, 1);
 				keyevent(v, r+0x60, 1);	/* 0x60: make capital letter */
 				keyevent(v, r+0x60, 1);	/* 0x60: make capital letter */
 				keyevent(v, Xctl, 0);
 				keyevent(v, Xctl, 0);
-			} else
+			} else	{
 				keyevent(v, ks, 1);
 				keyevent(v, ks, 1);
+				keyevent(v, ks, 0);	/* vmware does autorepeat,
+							   shut it up with an UP
+							*/
+			}
 
 
 			if(alt) {
 			if(alt) {
 				keyevent(v, Xalt, 0);
 				keyevent(v, Xalt, 0);

+ 10 - 10
sys/src/cmd/vnc/screen.c

@@ -113,9 +113,9 @@ screeninit(int x, int y, char *chanstr)
 	window.max.x = window.min.x + Dx(gscreen->r)*3/4-40;
 	window.max.x = window.min.x + Dx(gscreen->r)*3/4-40;
 	window.max.y = window.min.y + Dy(gscreen->r)*3/4-100;
 	window.max.y = window.min.y + Dy(gscreen->r)*3/4-100;
 
 
-	memimagedraw(gscreen, window, memblack, ZP, memopaque, ZP);
+	memimagedraw(gscreen, window, memblack, ZP, memopaque, ZP, S);
 	window = insetrect(window, 4);
 	window = insetrect(window, 4);
-	memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP);
+	memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP, S);
 
 
 	/* a lot of work to get a grey color */
 	/* a lot of work to get a grey color */
 	grey = allocmemimage(Rect(0,0,1,1), CMAP8);
 	grey = allocmemimage(Rect(0,0,1,1), CMAP8);
@@ -123,7 +123,7 @@ screeninit(int x, int y, char *chanstr)
 	grey->clipr = gscreen->r;
 	grey->clipr = gscreen->r;
 	memfillcolor(grey, 0xAAAAAAFF);
 	memfillcolor(grey, 0xAAAAAAFF);
 	memimagedraw(gscreen, Rect(window.min.x, window.min.y,
 	memimagedraw(gscreen, Rect(window.min.x, window.min.y,
-			window.max.x, window.min.y+h+5+6), grey, ZP, nil, ZP);
+			window.max.x, window.min.y+h+5+6), grey, ZP, nil, ZP, S);
 	freememimage(grey);
 	freememimage(grey);
 	window = insetrect(window, 5);
 	window = insetrect(window, 5);
 
 
@@ -196,8 +196,8 @@ cursordraw(Memimage *dst, Rectangle r)
 		loadmemimage(cursorclear, cursorr, clr, CURSORDIM*CURSORDIM/8);
 		loadmemimage(cursorclear, cursorr, clr, CURSORDIM*CURSORDIM/8);
 	}else
 	}else
 		unlock(&cursor);
 		unlock(&cursor);
-	memimagedraw(dst, r, memwhite, ZP, cursorclear, ZP);
-	memimagedraw(dst, r, curscol, ZP, cursorset, ZP);
+	memimagedraw(dst, r, memwhite, ZP, cursorclear, ZP, S);
+	memimagedraw(dst, r, curscol, ZP, cursorset, ZP, S);
 }
 }
 
 
 /*
 /*
@@ -280,9 +280,9 @@ scroll(void)
 	o = 8*h;
 	o = 8*h;
 	r = Rpt(window.min, Pt(window.max.x, window.max.y-o));
 	r = Rpt(window.min, Pt(window.max.x, window.max.y-o));
 	p = Pt(window.min.x, window.min.y+o);
 	p = Pt(window.min.x, window.min.y+o);
-	memimagedraw(gscreen, r, gscreen, p, nil, p);
+	memimagedraw(gscreen, r, gscreen, p, nil, p, S);
 	r = Rpt(Pt(window.min.x, window.max.y-o), window.max);
 	r = Rpt(Pt(window.min.x, window.max.y-o), window.max);
-	memimagedraw(gscreen, r, back, ZP, nil, ZP);
+	memimagedraw(gscreen, r, back, ZP, nil, ZP, S);
 	flushmemscreen(gscreen->r);
 	flushmemscreen(gscreen->r);
 
 
 	curpos.y -= o;
 	curpos.y -= o;
@@ -318,7 +318,7 @@ screenputc(char *buf)
 		pos = (curpos.x-window.min.x)/w;
 		pos = (curpos.x-window.min.x)/w;
 		pos = 8-(pos%8);
 		pos = 8-(pos%8);
 		r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h);
 		r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h);
-		memimagedraw(gscreen, r, back, back->r.min, memopaque, ZP);
+		memimagedraw(gscreen, r, back, back->r.min, memopaque, ZP, S);
 		addflush(r);
 		addflush(r);
 		curpos.x += pos*w;
 		curpos.x += pos*w;
 		break;
 		break;
@@ -327,7 +327,7 @@ screenputc(char *buf)
 			break;
 			break;
 		xp--;
 		xp--;
 		r = Rect(*xp, curpos.y, curpos.x, curpos.y + h);
 		r = Rect(*xp, curpos.y, curpos.x, curpos.y + h);
-		memimagedraw(gscreen, r, back, back->r.min, memopaque, ZP);
+		memimagedraw(gscreen, r, back, back->r.min, memopaque, ZP, S);
 		addflush(r);
 		addflush(r);
 		curpos.x = *xp;
 		curpos.x = *xp;
 		break;
 		break;
@@ -340,7 +340,7 @@ screenputc(char *buf)
 
 
 		*xp++ = curpos.x;
 		*xp++ = curpos.x;
 		r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y + h);
 		r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y + h);
-		memimagedraw(gscreen, r, back, back->r.min, memopaque, ZP);
+		memimagedraw(gscreen, r, back, back->r.min, memopaque, ZP, S);
 		memimagestring(gscreen, curpos, conscol, ZP, memdefont, buf);
 		memimagestring(gscreen, curpos, conscol, ZP, memdefont, buf);
 		addflush(r);
 		addflush(r);
 		curpos.x += w;
 		curpos.x += w;

+ 38 - 13
sys/src/cmd/vnc/vncs.c

@@ -6,6 +6,9 @@
 #include "screen.h"
 #include "screen.h"
 #include "kbd.h"
 #include "kbd.h"
 
 
+#include <mp.h>
+#include <libsec.h>
+
 enum
 enum
 {
 {
 	MaxCorreDim	= 48,
 	MaxCorreDim	= 48,
@@ -270,7 +273,7 @@ sendupdate(Vncs *v, int dowarp, Point warppt)
 	for(i = 0; i < updateregion.nrects; i++){
 	for(i = 0; i < updateregion.nrects; i++){
 		if(!docursor)
 		if(!docursor)
 			docursor = rectXrect(v->cursorr, updateregion.rects[i]);
 			docursor = rectXrect(v->cursorr, updateregion.rects[i]);
-		memimagedraw(v->clientimage, updateregion.rects[i], gscreen, updateregion.rects[i].min, memopaque, ZP);
+		memimagedraw(v->clientimage, updateregion.rects[i], gscreen, updateregion.rects[i].min, memopaque, ZP, S);
 	}
 	}
 
 
 	if(docursor){
 	if(docursor){
@@ -694,7 +697,7 @@ vnc_newclient(int dfd, int cfd)
 	Vncs * v;
 	Vncs * v;
 
 
 	/* caller returns to listen */
 	/* caller returns to listen */
-	switch(rfork(RFPROC|RFMEM)){
+	switch(rfork(RFPROC|RFMEM|RFNAMEG)){
 	case -1:
 	case -1:
 		close(dfd);
 		close(dfd);
 		close(cfd);
 		close(cfd);
@@ -834,15 +837,15 @@ noteshut(void*, char *msg)
  * auto:	/net | nil
  * auto:	/net | nil
  */
  */
 int
 int
-vncannounce(char *netmt, char * darg, char * adir)
+vncannounce(char *netmt, char * darg, char * adir, int bport)
 {
 {
 	int port, eport, fd;
 	int port, eport, fd;
 	char portstr[NETPATHLEN];
 	char portstr[NETPATHLEN];
 
 
-	port = 5900;
-	eport = port + 50;
+	port = bport;
+	eport = bport + 50;
 	if( darg != nil && darg[0] == ':' ) {
 	if( darg != nil && darg[0] == ':' ) {
-		port = 5900 + strtol(&darg[1], nil, 10);
+		port = bport + strtol(&darg[1], nil, 10);
 		eport = port;
 		eport = port;
 	}
 	}
 
 
@@ -850,7 +853,7 @@ vncannounce(char *netmt, char * darg, char * adir)
 		snprint(portstr, NETPATHLEN, "%s/tcp!*!%d", netmt, port);
 		snprint(portstr, NETPATHLEN, "%s/tcp!*!%d", netmt, port);
 		fd = announce(portstr, adir);
 		fd = announce(portstr, adir);
 		if( fd >= 0 ) {
 		if( fd >= 0 ) {
-			fprint(2, "server started on display :%d\n", port-5900);
+			fprint(2, "server started on display :%d\n", port-bport);
 			return fd;
 			return fd;
 		}
 		}
 	}
 	}
@@ -861,7 +864,7 @@ vncannounce(char *netmt, char * darg, char * adir)
 /* the user wants to kill the sever on a specified port 
 /* the user wants to kill the sever on a specified port 
 */
 */
 static void
 static void
-vnckillsrv(char * netroot, char * portstr)
+vnckillsrv(char * netroot, char * portstr, int bport)
 {
 {
 	int port, fd, lport;
 	int port, fd, lport;
 	char * p;
 	char * p;
@@ -871,7 +874,7 @@ vnckillsrv(char * netroot, char * portstr)
 
 
 	port = atoi(portstr);
 	port = atoi(portstr);
 	
 	
-	port += 5900;
+	port += bport;
 	/* find the listener in /net/tcp/ */
 	/* find the listener in /net/tcp/ */
 	snprint(buf, sizeof buf, "%s/tcp", netroot);
 	snprint(buf, sizeof buf, "%s/tcp", netroot);
 	fdir = open(buf, OREAD);
 	fdir = open(buf, OREAD);
@@ -924,9 +927,12 @@ void
 main(int argc, char * argv[])
 main(int argc, char * argv[])
 {
 {
 	static char *defargv[] = { "/bin/rc", "-i", nil };
 	static char *defargv[] = { "/bin/rc", "-i", nil };
-	char *addr, netmt[NETPATHLEN], adir[NETPATHLEN], ldir[NETPATHLEN], *p, *darg, *karg;
-	int cfd, s, n, fd, w, h;
+	char *addr, netmt[NETPATHLEN], adir[NETPATHLEN], ldir[NETPATHLEN], *p, *darg, *karg, *pem;
+	int cfd, s, n, fd, w, h, vncport;
+	TLSconn *conn;
 
 
+	vncport = 5900;
+	pem = nil;
 	w = 1024;
 	w = 1024;
 	h = 768;
 	h = 768;
 	addr = nil;
 	addr = nil;
@@ -934,6 +940,12 @@ main(int argc, char * argv[])
 	karg = nil;
 	karg = nil;
 	setnetmtpt(netmt, NETPATHLEN, nil);
 	setnetmtpt(netmt, NETPATHLEN, nil);
 	ARGBEGIN{
 	ARGBEGIN{
+	case 'c':
+		pem = ARGF();
+		if(pem == nil)
+			usage();
+		vncport = 35729;	/* base port# for vnc/tls */
+		break;
 	case 'd':
 	case 'd':
 		darg = ARGF();
 		darg = ARGF();
 		if(darg == nil || *darg != ':')
 		if(darg == nil || *darg != ':')
@@ -970,7 +982,7 @@ main(int argc, char * argv[])
 	if(karg != nil){
 	if(karg != nil){
 		if(argc ||  darg != nil )
 		if(argc ||  darg != nil )
 			usage();
 			usage();
-		vnckillsrv(netmt, &karg[1]);
+		vnckillsrv(netmt, &karg[1], vncport);
 		exits(nil);
 		exits(nil);
 	}
 	}
 
 
@@ -1045,7 +1057,7 @@ main(int argc, char * argv[])
 	/*
 	/*
 	 * run the service
 	 * run the service
 	 */
 	 */
-	srvfd = vncannounce(netmt, darg, adir);
+	srvfd = vncannounce(netmt, darg, adir, vncport);
 	if(srvfd < 0)
 	if(srvfd < 0)
 		sysfatal("announce %s: %r", addr);
 		sysfatal("announce %s: %r", addr);
 
 
@@ -1063,6 +1075,19 @@ main(int argc, char * argv[])
 			fprint(2, "received call at %s\n", ldir);
 			fprint(2, "received call at %s\n", ldir);
 
 
 		s = accept(cfd, ldir);
 		s = accept(cfd, ldir);
+		if(pem != nil) {
+			/* this code requires the user's own
+				factotum running on the cpuserver
+			*/
+			conn = (TLSconn*)mallocz(sizeof *conn, 1);
+			conn->cert = readcert(pem, &conn->certlen);
+			s = tlsServer(s, conn);
+			if(conn->certlen) 
+				free(conn->cert);
+			if(conn->sessionIDlen)
+				free(conn->sessionID);
+			free(conn);
+		}
 		if(s < 0){
 		if(s < 0){
 			close(cfd);
 			close(cfd);
 			continue;
 			continue;

+ 22 - 6
sys/src/libc/fmt/dofmt.c

@@ -239,8 +239,18 @@ _runefmt(Fmt *f)
 int
 int
 fmtstrcpy(Fmt *f, char *s)
 fmtstrcpy(Fmt *f, char *s)
 {
 {
+	int p, i;
 	if(!s)
 	if(!s)
 		return _fmtcpy(f, "<nil>", 5, 5);
 		return _fmtcpy(f, "<nil>", 5, 5);
+	/* if precision is specified, make sure we don't wander off the end */
+	if(f->flags & FmtPrec){
+		p = f->prec;
+		for(i = 0; i < p; i++)
+			if(s[i] == 0)
+				break;
+		return _fmtcpy(f, s, utfnlen(s, i), i);	/* BUG?: won't print a partial rune at end */
+	}
+
 	return _fmtcpy(f, s, utflen(s), strlen(s));
 	return _fmtcpy(f, s, utflen(s), strlen(s));
 }
 }
 
 
@@ -259,15 +269,21 @@ int
 fmtrunestrcpy(Fmt *f, Rune *s)
 fmtrunestrcpy(Fmt *f, Rune *s)
 {
 {
 	Rune *e;
 	Rune *e;
-	int n;
+	int n, p;
 
 
 	if(!s)
 	if(!s)
 		return _fmtcpy(f, "<nil>", 5, 5);
 		return _fmtcpy(f, "<nil>", 5, 5);
-	for(e = s; *e; e++)
-		;
-	n = e - s;
-	if((f->flags & FmtPrec) && n > f->prec)
-		n = f->prec;
+	/* if precision is specified, make sure we don't wander off the end */
+	if(f->flags & FmtPrec){
+		p = f->prec;
+		for(n = 0; n < p; n++)
+			if(s[n] == 0)
+				break;
+	}else{
+		for(e = s; *e; e++)
+			;
+		n = e - s;
+	}
 	return _fmtrcpy(f, s, n);
 	return _fmtrcpy(f, s, n);
 }
 }
 
 

+ 1 - 0
sys/src/libmemdraw/alloc.c

@@ -95,6 +95,7 @@ allocmemimage(Rectangle r, ulong chan)
 
 
 	i = allocmemimaged(r, chan, md);
 	i = allocmemimaged(r, chan, md);
 	if(i == nil){
 	if(i == nil){
+		poolfree(imagmem, md->base);
 		free(md);
 		free(md);
 		return nil;
 		return nil;
 	}
 	}

+ 6 - 6
sys/src/libmemdraw/arc.c

@@ -33,7 +33,7 @@ Point p00;
  * wedge to make a mask through which to copy src to dst.
  * wedge to make a mask through which to copy src to dst.
  */
  */
 void
 void
-memarc(Memimage *dst, Point c, int a, int b, int t, Memimage *src, Point sp, int alpha, int phi)
+memarc(Memimage *dst, Point c, int a, int b, int t, Memimage *src, Point sp, int alpha, int phi, int op)
 {
 {
 	int i, w, beta, tmp, c1, c2, m, m1;
 	int i, w, beta, tmp, c1, c2, m, m1;
 	Rectangle rect;
 	Rectangle rect;
@@ -57,7 +57,7 @@ memarc(Memimage *dst, Point c, int a, int b, int t, Memimage *src, Point sp, int
 		phi = -phi;
 		phi = -phi;
 	}
 	}
 	if(phi >= 360){
 	if(phi >= 360){
-		memellipse(dst, c, a, b, t, src, sp);
+		memellipse(dst, c, a, b, t, src, sp, op);
 		return;
 		return;
 	}
 	}
 	while(alpha < 0)
 	while(alpha < 0)
@@ -96,19 +96,19 @@ memarc(Memimage *dst, Point c, int a, int b, int t, Memimage *src, Point sp, int
 	if(wedge == nil)
 	if(wedge == nil)
 		goto Return;
 		goto Return;
 	memfillcolor(wedge, DTransparent);
 	memfillcolor(wedge, DTransparent);
-	memfillpoly(wedge, bnd, i, ~0, memopaque, p00);
+	memfillpoly(wedge, bnd, i, ~0, memopaque, p00, S);
 	figure = allocmemimage(rect, GREY1);
 	figure = allocmemimage(rect, GREY1);
 	if(figure == nil)
 	if(figure == nil)
 		goto Return;
 		goto Return;
 	memfillcolor(figure, DTransparent);
 	memfillcolor(figure, DTransparent);
-	memellipse(figure, p00, a, b, t, memopaque, p00);
+	memellipse(figure, p00, a, b, t, memopaque, p00, S);
 	mask = allocmemimage(rect, GREY1);
 	mask = allocmemimage(rect, GREY1);
 	if(mask == nil)
 	if(mask == nil)
 		goto Return;
 		goto Return;
 	memfillcolor(mask, DTransparent);
 	memfillcolor(mask, DTransparent);
-	memimagedraw(mask, rect, figure, rect.min, wedge, rect.min);
+	memimagedraw(mask, rect, figure, rect.min, wedge, rect.min, S);
 	c = subpt(c, dst->r.min);
 	c = subpt(c, dst->r.min);
-	memdraw(dst, dst->r, src, subpt(sp, c), mask, subpt(p00, c));
+	memdraw(dst, dst->r, src, subpt(sp, c), mask, subpt(p00, c), op);
 
 
     Return:
     Return:
 	freememimage(wedge);
 	freememimage(wedge);

File diff suppressed because it is too large
+ 529 - 87
sys/src/libmemdraw/draw.c


+ 6 - 4
sys/src/libmemdraw/ellipse.c

@@ -30,6 +30,7 @@ struct Param {
 	int			t;
 	int			t;
 	Point			sp;
 	Point			sp;
 	Memimage	*disc;
 	Memimage	*disc;
+	int			op;
 };
 };
 
 
 /*
 /*
@@ -104,7 +105,7 @@ step(State *s)
 }
 }
 
 
 void
 void
-memellipse(Memimage *dst, Point c, int a, int b, int t, Memimage *src, Point sp)
+memellipse(Memimage *dst, Point c, int a, int b, int t, Memimage *src, Point sp, int op)
 {
 {
 	State in, out;
 	State in, out;
 	int y, inb, inx, outx, u;
 	int y, inb, inx, outx, u;
@@ -120,6 +121,7 @@ memellipse(Memimage *dst, Point c, int a, int b, int t, Memimage *src, Point sp)
 	p.t = t;
 	p.t = t;
 	p.sp = subpt(sp, c);
 	p.sp = subpt(sp, c);
 	p.disc = nil;
 	p.disc = nil;
+	p.op = op;
 
 
 	u = (t<<1)*(a-b);
 	u = (t<<1)*(a-b);
 	if(b<a && u>b*b || a<b && -u>a*a) {
 	if(b<a && u>b*b || a<b && -u>a*a) {
@@ -178,7 +180,7 @@ bellipse(int y, State *s, Param *p)
 	if(p->disc == nil)
 	if(p->disc == nil)
 		return;
 		return;
 	memfillcolor(p->disc, DTransparent);
 	memfillcolor(p->disc, DTransparent);
-	memellipse(p->disc, p00, t, t, -1, memopaque, p00);
+	memellipse(p->disc, p00, t, t, -1, memopaque, p00, p->op);
 	oy = y;
 	oy = y;
 	ox = 0;
 	ox = 0;
 	nx = x = step(s);
 	nx = x = step(s);
@@ -209,7 +211,7 @@ erect(int x0, int y0, int x1, int y1, Param *p)
 
 
 /*	print("R %d,%d %d,%d\n", x0, y0, x1, y1); /**/
 /*	print("R %d,%d %d,%d\n", x0, y0, x1, y1); /**/
 	r = Rect(p->c.x+x0, p->c.y+y0, p->c.x+x1+1, p->c.y+y1+1);
 	r = Rect(p->c.x+x0, p->c.y+y0, p->c.x+x1+1, p->c.y+y1+1);
-	memdraw(p->dst, r, p->src, addpt(p->sp, r.min), memopaque, p00);
+	memdraw(p->dst, r, p->src, addpt(p->sp, r.min), memopaque, p00, p->op);
 }
 }
 
 
 /*
 /*
@@ -225,7 +227,7 @@ epoint(int x, int y, Param *p)
 /*	print("P%d %d,%d\n", p->t, x, y);	/**/
 /*	print("P%d %d,%d\n", p->t, x, y);	/**/
 	p0 = Pt(p->c.x+x, p->c.y+y);
 	p0 = Pt(p->c.x+x, p->c.y+y);
 	r = Rpt(addpt(p0, p->disc->r.min), addpt(p0, p->disc->r.max));
 	r = Rpt(addpt(p0, p->disc->r.min), addpt(p0, p->disc->r.max));
-	memdraw(p->dst, r, p->src, addpt(p->sp, r.min), p->disc, p->disc->r.min);
+	memdraw(p->dst, r, p->src, addpt(p->sp, r.min), p->disc, p->disc->r.min, p->op);
 }
 }
 
 
 /* 
 /* 

+ 16 - 16
sys/src/libmemdraw/fillpoly.c

@@ -23,8 +23,8 @@ static	void	zsort(Seg **seg, Seg **ep);
 static	int	ycompare(void*, void*);
 static	int	ycompare(void*, void*);
 static	int	xcompare(void*, void*);
 static	int	xcompare(void*, void*);
 static	int	zcompare(void*, void*);
 static	int	zcompare(void*, void*);
-static	void	xscan(Memimage *dst, Seg **seg, Seg *segtab, int nseg, int wind, Memimage *src, Point sp, int, int, int);
-static	void	yscan(Memimage *dst, Seg **seg, Seg *segtab, int nseg, int wind, Memimage *src, Point sp, int);
+static	void	xscan(Memimage *dst, Seg **seg, Seg *segtab, int nseg, int wind, Memimage *src, Point sp, int, int, int, int);
+static	void	yscan(Memimage *dst, Seg **seg, Seg *segtab, int nseg, int wind, Memimage *src, Point sp, int, int);
 
 
 static void
 static void
 fillcolor(Memimage *dst, int left, int right, int y, Memimage *src, Point p)
 fillcolor(Memimage *dst, int left, int right, int y, Memimage *src, Point p)
@@ -39,7 +39,7 @@ fillcolor(Memimage *dst, int left, int right, int y, Memimage *src, Point p)
 }
 }
 
 
 static void
 static void
-fillline(Memimage *dst, int left, int right, int y, Memimage *src, Point p)
+fillline(Memimage *dst, int left, int right, int y, Memimage *src, Point p, int op)
 {
 {
 	Rectangle r;
 	Rectangle r;
 
 
@@ -49,11 +49,11 @@ fillline(Memimage *dst, int left, int right, int y, Memimage *src, Point p)
 	r.max.y = y+1;
 	r.max.y = y+1;
 	p.x += left;
 	p.x += left;
 	p.y += y;
 	p.y += y;
-	memdraw(dst, r, src, p, memopaque, p);
+	memdraw(dst, r, src, p, memopaque, p, op);
 }
 }
 
 
 static void
 static void
-fillpoint(Memimage *dst, int x, int y, Memimage *src, Point p)
+fillpoint(Memimage *dst, int x, int y, Memimage *src, Point p, int op)
 {
 {
 	Rectangle r;
 	Rectangle r;
 
 
@@ -63,17 +63,17 @@ fillpoint(Memimage *dst, int x, int y, Memimage *src, Point p)
 	r.max.y = y+1;
 	r.max.y = y+1;
 	p.x += x;
 	p.x += x;
 	p.y += y;
 	p.y += y;
-	memdraw(dst, r, src, p, memopaque, p);
+	memdraw(dst, r, src, p, memopaque, p, op);
 }
 }
 
 
 void
 void
-memfillpoly(Memimage *dst, Point *vert, int nvert, int w, Memimage *src, Point sp)
+memfillpoly(Memimage *dst, Point *vert, int nvert, int w, Memimage *src, Point sp, int op)
 {
 {
-	_memfillpolysc(dst, vert, nvert, w, src, sp, 0, 0, 0);
+	_memfillpolysc(dst, vert, nvert, w, src, sp, 0, 0, 0, op);
 }
 }
 
 
 void
 void
-_memfillpolysc(Memimage *dst, Point *vert, int nvert, int w, Memimage *src, Point sp, int detail, int fixshift, int clipped)
+_memfillpolysc(Memimage *dst, Point *vert, int nvert, int w, Memimage *src, Point sp, int detail, int fixshift, int clipped, int op)
 {
 {
 	Seg **seg, *segtab;
 	Seg **seg, *segtab;
 	Point p0;
 	Point p0;
@@ -111,9 +111,9 @@ _memfillpolysc(Memimage *dst, Point *vert, int nvert, int w, Memimage *src, Poin
 	if(!fixshift)
 	if(!fixshift)
 		fixshift = 1;
 		fixshift = 1;
 
 
-	xscan(dst, seg, segtab, nvert, w, src, sp, detail, fixshift, clipped);
+	xscan(dst, seg, segtab, nvert, w, src, sp, detail, fixshift, clipped, op);
 	if(detail)
 	if(detail)
-		yscan(dst, seg, segtab, nvert, w, src, sp, fixshift);
+		yscan(dst, seg, segtab, nvert, w, src, sp, fixshift, op);
 
 
 	free(seg);
 	free(seg);
 	free(segtab);
 	free(segtab);
@@ -159,13 +159,13 @@ smuldivmod(long x, long y, long z, long *mod)
 }
 }
 
 
 static void
 static void
-xscan(Memimage *dst, Seg **seg, Seg *segtab, int nseg, int wind, Memimage *src, Point sp, int detail, int fixshift, int clipped)
+xscan(Memimage *dst, Seg **seg, Seg *segtab, int nseg, int wind, Memimage *src, Point sp, int detail, int fixshift, int clipped, int op)
 {
 {
 	long y, maxy, x, x2, xerr, xden, onehalf;
 	long y, maxy, x, x2, xerr, xden, onehalf;
 	Seg **ep, **next, **p, **q, *s;
 	Seg **ep, **next, **p, **q, *s;
 	long n, i, iy, cnt, ix, ix2, minx, maxx;
 	long n, i, iy, cnt, ix, ix2, minx, maxx;
 	Point pt;
 	Point pt;
-	void	(*fill)(Memimage*, int, int, int, Memimage*, Point);
+	void	(*fill)(Memimage*, int, int, int, Memimage*, Point, int);
 
 
 	fill = fillline;
 	fill = fillline;
 /*
 /*
@@ -300,7 +300,7 @@ xscan(Memimage *dst, Seg **seg, Seg *segtab, int nseg, int wind, Memimage *src,
 				ix = (x + x2) >> (fixshift+1);
 				ix = (x + x2) >> (fixshift+1);
 				ix2 = ix+1;
 				ix2 = ix+1;
 			}
 			}
-			(*fill)(dst, ix, ix2, iy, src, sp);
+			(*fill)(dst, ix, ix2, iy, src, sp, op);
 		}
 		}
 		y += (1<<fixshift);
 		y += (1<<fixshift);
 		iy++;
 		iy++;
@@ -308,7 +308,7 @@ xscan(Memimage *dst, Seg **seg, Seg *segtab, int nseg, int wind, Memimage *src,
 }
 }
 
 
 static void
 static void
-yscan(Memimage *dst, Seg **seg, Seg *segtab, int nseg, int wind, Memimage *src, Point sp, int fixshift)
+yscan(Memimage *dst, Seg **seg, Seg *segtab, int nseg, int wind, Memimage *src, Point sp, int fixshift, int op)
 {
 {
 	long x, maxx, y, y2, yerr, yden, onehalf;
 	long x, maxx, y, y2, yerr, yden, onehalf;
 	Seg **ep, **next, **p, **q, *s;
 	Seg **ep, **next, **p, **q, *s;
@@ -428,7 +428,7 @@ yscan(Memimage *dst, Seg **seg, Seg *segtab, int nseg, int wind, Memimage *src,
 				if(yerr*p[0]->den + p[0]->zerr*yden > p[0]->den*yden)
 				if(yerr*p[0]->den + p[0]->zerr*yden > p[0]->den*yden)
 					y++;
 					y++;
 				iy = (y + y2) >> (fixshift+1);
 				iy = (y + y2) >> (fixshift+1);
-				fillpoint(dst, ix, iy, src, sp);
+				fillpoint(dst, ix, iy, src, sp, op);
 			}
 			}
 		}
 		}
 		x += (1<<fixshift);
 		x += (1<<fixshift);

+ 32 - 12
sys/src/libmemdraw/line.c

@@ -29,6 +29,7 @@ lmax(int a, int b)
 	return b;
 	return b;
 }
 }
 
 
+#ifdef NOTUSED
 /*
 /*
  * Rather than line clip, we run the Bresenham loop over the full line,
  * Rather than line clip, we run the Bresenham loop over the full line,
  * and clip on each pixel.  This is more expensive but means that
  * and clip on each pixel.  This is more expensive but means that
@@ -240,6 +241,7 @@ verline(Memimage *dst, Point p0, Point p1, Memimage *src, Point dsrc, Rectangle
 		}
 		}
 	}
 	}
 }
 }
+#endif /* NOTUSED */
 
 
 static Memimage*
 static Memimage*
 membrush(int radius)
 membrush(int radius)
@@ -252,7 +254,7 @@ membrush(int radius)
 		brush = allocmemimage(Rect(0, 0, 2*radius+1, 2*radius+1), memopaque->chan);
 		brush = allocmemimage(Rect(0, 0, 2*radius+1, 2*radius+1), memopaque->chan);
 		if(brush != nil){
 		if(brush != nil){
 			memfillcolor(brush, DTransparent);	/* zeros */
 			memfillcolor(brush, DTransparent);	/* zeros */
-			memellipse(brush, Pt(radius, radius), radius, radius, -1, memopaque, Pt(radius, radius));
+			memellipse(brush, Pt(radius, radius), radius, radius, -1, memopaque, Pt(radius, radius), S);
 		}
 		}
 		brushradius = radius;
 		brushradius = radius;
 	}
 	}
@@ -261,7 +263,7 @@ membrush(int radius)
 
 
 static
 static
 void
 void
-discend(Point p, int radius, Memimage *dst, Memimage *src, Point dsrc)
+discend(Point p, int radius, Memimage *dst, Memimage *src, Point dsrc, int op)
 {
 {
 	Memimage *disc;
 	Memimage *disc;
 	Rectangle r;
 	Rectangle r;
@@ -272,7 +274,7 @@ discend(Point p, int radius, Memimage *dst, Memimage *src, Point dsrc)
 		r.min.y = p.y - radius;
 		r.min.y = p.y - radius;
 		r.max.x = p.x + radius+1;
 		r.max.x = p.x + radius+1;
 		r.max.y = p.y + radius+1;
 		r.max.y = p.y + radius+1;
-		memdraw(dst, r, src, addpt(r.min, dsrc), disc, Pt(0,0));
+		memdraw(dst, r, src, addpt(r.min, dsrc), disc, Pt(0,0), op);
 	}
 	}
 }
 }
 
 
@@ -311,7 +313,7 @@ arrowend(Point tip, Point *pp, int end, int sin, int cos, int radius)
 }
 }
 
 
 void
 void
-_memimageline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp, Rectangle clipr)
+_memimageline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp, Rectangle clipr, int op)
 {
 {
 	/*
 	/*
 	 * BUG: We should really really pick off purely horizontal and purely
 	 * BUG: We should really really pick off purely horizontal and purely
@@ -321,7 +323,7 @@ _memimageline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius,
 
 
 	int hor;
 	int hor;
 	int sin, cos, dx, dy, t;
 	int sin, cos, dx, dy, t;
-	Rectangle oclipr;
+	Rectangle oclipr, r;
 	Point q, pts[10], *pp, d;
 	Point q, pts[10], *pp, d;
 
 
 	if(radius < 0)
 	if(radius < 0)
@@ -354,6 +356,24 @@ _memimageline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius,
 		end1 = t;
 		end1 = t;
 	}
 	}
 
 
+	if((p0.x == p1.x || p0.y == p1.y) && (end0&0x1F) == Endsquare && (end1&0x1F) == Endsquare){
+		r.min = p0;
+		r.max = p1;
+		if(p0.x == p1.x){
+			r.min.x -= radius;
+			r.max.x += radius+1;
+		}
+		else{
+			r.min.y -= radius;
+			r.max.y += radius+1;
+		}
+		oclipr = dst->clipr;
+		dst->clipr = clipr;
+		memimagedraw(dst, r, src, sp, memopaque, sp, op);
+		dst->clipr = oclipr;
+		return;
+	}
+
 /*    Hard: */
 /*    Hard: */
 	/* draw thick line using polygon fill */
 	/* draw thick line using polygon fill */
 	icossin2(p1.x-p0.x, p1.y-p0.y, &cos, &sin);
 	icossin2(p1.x-p0.x, p1.y-p0.y, &cos, &sin);
@@ -366,7 +386,7 @@ _memimageline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius,
 	q.y = ICOSSCALE*p0.y+ICOSSCALE/2-sin/2;
 	q.y = ICOSSCALE*p0.y+ICOSSCALE/2-sin/2;
 	switch(end0 & 0x1F){
 	switch(end0 & 0x1F){
 	case Enddisc:
 	case Enddisc:
-		discend(p0, radius, dst, src, d);
+		discend(p0, radius, dst, src, d, op);
 		/* fall through */
 		/* fall through */
 	case Endsquare:
 	case Endsquare:
 	default:
 	default:
@@ -379,7 +399,7 @@ _memimageline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius,
 		break;
 		break;
 	case Endarrow:
 	case Endarrow:
 		arrowend(q, pp, end0, -sin, -cos, radius);
 		arrowend(q, pp, end0, -sin, -cos, radius);
-		_memfillpolysc(dst, pts, 5, ~0, src, addpt(pts[0], mulpt(d, ICOSSCALE)), 1, 10, 1);
+		_memfillpolysc(dst, pts, 5, ~0, src, addpt(pts[0], mulpt(d, ICOSSCALE)), 1, 10, 1, op);
 		pp[1] = pp[4];
 		pp[1] = pp[4];
 		pp += 2;
 		pp += 2;
 	}
 	}
@@ -387,7 +407,7 @@ _memimageline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius,
 	q.y = ICOSSCALE*p1.y+ICOSSCALE/2+sin/2;
 	q.y = ICOSSCALE*p1.y+ICOSSCALE/2+sin/2;
 	switch(end1 & 0x1F){
 	switch(end1 & 0x1F){
 	case Enddisc:
 	case Enddisc:
-		discend(p1, radius, dst, src, d);
+		discend(p1, radius, dst, src, d, op);
 		/* fall through */
 		/* fall through */
 	case Endsquare:
 	case Endsquare:
 	default:
 	default:
@@ -400,19 +420,19 @@ _memimageline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius,
 		break;
 		break;
 	case Endarrow:
 	case Endarrow:
 		arrowend(q, pp, end1, sin, cos, radius);
 		arrowend(q, pp, end1, sin, cos, radius);
-		_memfillpolysc(dst, pp, 5, ~0, src, addpt(pts[0], mulpt(d, ICOSSCALE)), 1, 10, 1);
+		_memfillpolysc(dst, pp, 5, ~0, src, addpt(pts[0], mulpt(d, ICOSSCALE)), 1, 10, 1, op);
 		pp[1] = pp[4];
 		pp[1] = pp[4];
 		pp += 2;
 		pp += 2;
 	}
 	}
-	_memfillpolysc(dst, pts, pp-pts, ~0, src, addpt(pts[0], mulpt(d, ICOSSCALE)), 0, 10, 1);
+	_memfillpolysc(dst, pts, pp-pts, ~0, src, addpt(pts[0], mulpt(d, ICOSSCALE)), 0, 10, 1, op);
 	dst->clipr = oclipr;
 	dst->clipr = oclipr;
 	return;
 	return;
 }
 }
 
 
 void
 void
-memimageline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp)
+memimageline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp, int op)
 {
 {
-	_memimageline(dst, p0, p1, end0, end1, radius, src, sp, dst->clipr);
+	_memimageline(dst, p0, p1, end0, end1, radius, src, sp, dst->clipr, op);
 }
 }
 
 
 /*
 /*

+ 13 - 11
sys/src/libmemdraw/openmemsubfont.c

@@ -16,26 +16,21 @@ openmemsubfont(char *name)
 	fd = open(name, OREAD);
 	fd = open(name, OREAD);
 	if(fd < 0)
 	if(fd < 0)
 		return nil;
 		return nil;
+	p = nil;
 	i = readmemimage(fd);
 	i = readmemimage(fd);
 	if(i == nil)
 	if(i == nil)
-		return nil;
+		goto Err;
 	if(read(fd, hdr, 3*12) != 3*12){
 	if(read(fd, hdr, 3*12) != 3*12){
-		freememimage(i);
 		werrstr("openmemsubfont: header read error: %r");
 		werrstr("openmemsubfont: header read error: %r");
-		return nil;
+		goto Err;
 	}
 	}
 	n = atoi(hdr);
 	n = atoi(hdr);
 	p = malloc(6*(n+1));
 	p = malloc(6*(n+1));
-	if(p == nil){
-		freememimage(i);
-		return nil;
-	}
+	if(p == nil)
+		goto Err;
 	if(read(fd, p, 6*(n+1)) != 6*(n+1)){
 	if(read(fd, p, 6*(n+1)) != 6*(n+1)){
 		werrstr("openmemsubfont: fontchar read error: %r");
 		werrstr("openmemsubfont: fontchar read error: %r");
-    Err:
-		freememimage(i);
-		free(p);
-		return nil;
+		goto Err;
 	}
 	}
 	fc = malloc(sizeof(Fontchar)*(n+1));
 	fc = malloc(sizeof(Fontchar)*(n+1));
 	if(fc == nil)
 	if(fc == nil)
@@ -48,4 +43,11 @@ openmemsubfont(char *name)
 	}
 	}
 	free(p);
 	free(p);
 	return sf;
 	return sf;
+Err:
+	close(fd);
+	if (i != nil)
+		freememimage(i);
+	if (p != nil)
+		free(p);
+	return nil;
 }
 }

+ 2 - 2
sys/src/libmemdraw/poly.c

@@ -5,7 +5,7 @@
 #include <memlayer.h>
 #include <memlayer.h>
 
 
 void
 void
-mempoly(Memimage *dst, Point *vert, int nvert, int end0, int end1, int radius, Memimage *src, Point sp)
+mempoly(Memimage *dst, Point *vert, int nvert, int end0, int end1, int radius, Memimage *src, Point sp, int op)
 {
 {
 	int i, e0, e1;
 	int i, e0, e1;
 	Point d;
 	Point d;
@@ -19,6 +19,6 @@ mempoly(Memimage *dst, Point *vert, int nvert, int end0, int end1, int radius, M
 			e0 = end0;
 			e0 = end0;
 		if(i == nvert-1)
 		if(i == nvert-1)
 			e1 = end1;
 			e1 = end1;
-		memline(dst, vert[i-1], vert[i], e0, e1, radius, src, addpt(d, vert[i-1]));
+		memline(dst, vert[i-1], vert[i], e0, e1, radius, src, addpt(d, vert[i-1]), op);
 	}
 	}
 }
 }

+ 1 - 1
sys/src/libmemdraw/string.c

@@ -30,7 +30,7 @@ memimagestring(Memimage *b, Point p, Memimage *color, Point cp, Memsubfont *f, c
 		i = f->info+c;
 		i = f->info+c;
 		width = i->width;
 		width = i->width;
 		memdraw(b, Rect(p.x+i->left, p.y+i->top, p.x+i->left+(i[1].x-i[0].x), p.y+i->bottom),
 		memdraw(b, Rect(p.x+i->left, p.y+i->top, p.x+i->left+(i[1].x-i[0].x), p.y+i->bottom),
-			color, cp, f->bits, Pt(i->x, i->top));
+			color, cp, f->bits, Pt(i->x, i->top), SoverD);
 	}
 	}
 	return p;
 	return p;
 }
 }

+ 6 - 4
sys/src/libmemlayer/draw.c

@@ -12,6 +12,7 @@ struct Draw
 	Memlayer		*dstlayer;
 	Memlayer		*dstlayer;
 	Memimage	*src;
 	Memimage	*src;
 	Memimage	*mask;
 	Memimage	*mask;
+	int	op;
 };
 };
 
 
 static
 static
@@ -47,11 +48,11 @@ ldrawop(Memimage *dst, Rectangle screenr, Rectangle clipr, void *etc, int insave
 		if(!ok)
 		if(!ok)
 			return;
 			return;
 	}
 	}
-	memdraw(dst, r, d->src, p0, d->mask, p1);
+	memdraw(dst, r, d->src, p0, d->mask, p1, d->op);
 }
 }
 
 
 void
 void
-memdraw(Memimage *dst, Rectangle r, Memimage *src, Point p0, Memimage *mask, Point p1)
+memdraw(Memimage *dst, Rectangle r, Memimage *src, Point p0, Memimage *mask, Point p1, int op)
 {
 {
 	struct Draw d;
 	struct Draw d;
 	Rectangle srcr, tr, mr;
 	Rectangle srcr, tr, mr;
@@ -70,7 +71,7 @@ if(drawdebug)	iprint("mask->layer != nil\n");
 
 
     Top:
     Top:
 	if(dst->layer==nil && src->layer==nil){
 	if(dst->layer==nil && src->layer==nil){
-		memimagedraw(dst, r, src, p0, mask, p1);
+		memimagedraw(dst, r, src, p0, mask, p1, op);
 		return;
 		return;
 	}
 	}
 
 
@@ -141,7 +142,7 @@ if(drawdebug)	iprint("drawclip dstcr %R srccr %R maskcr %R\n", dst->clipr, src->
 			memlhide(dst, srcr);
 			memlhide(dst, srcr);
 		}
 		}
 		memdraw(dl->save, rectsubpt(r, dl->delta), dl->save,
 		memdraw(dl->save, rectsubpt(r, dl->delta), dl->save,
-			subpt(srcr.min, src->layer->delta), mask, p1);
+			subpt(srcr.min, src->layer->delta), mask, p1, op);
 		memlexpose(dst, r);
 		memlexpose(dst, r);
 		return;
 		return;
 	}
 	}
@@ -180,6 +181,7 @@ if(drawdebug)	iprint("drawclip dstcr %R srccr %R maskcr %R\n", dst->clipr, src->
 	d.deltam = subpt(p1, r.min);
 	d.deltam = subpt(p1, r.min);
 	d.dstlayer = dl;
 	d.dstlayer = dl;
 	d.src = src;
 	d.src = src;
+	d.op = op;
 	d.mask = mask;
 	d.mask = mask;
 	_memlayerop(ldrawop, dst, r, r, &d);
 	_memlayerop(ldrawop, dst, r, r, &d);
 }
 }

+ 1 - 1
sys/src/libmemlayer/lalloc.c

@@ -73,7 +73,7 @@ memlalloc(Memscreen *s, Rectangle screenr, Refreshfn refreshfn, void *refreshptr
 	if(val != DNofill){
 	if(val != DNofill){
 		memsetchan(paint, n->chan);
 		memsetchan(paint, n->chan);
 		memfillcolor(paint, val);
 		memfillcolor(paint, val);
-		memdraw(n, n->r, paint, n->r.min, nil, n->r.min);
+		memdraw(n, n->r, paint, n->r.min, nil, n->r.min, S);
 	}
 	}
 	return n;
 	return n;
 }
 }

+ 1 - 1
sys/src/libmemlayer/layerop.c

@@ -26,7 +26,7 @@ _layerop(
 	fr = front->layer->screenr;
 	fr = front->layer->screenr;
 	if(rectXrect(r, fr) == 0){
 	if(rectXrect(r, fr) == 0){
 		/* r doesn't touch this window; continue on next rearmost */
 		/* r doesn't touch this window; continue on next rearmost */
-assert(front && front->layer && front->layer->screen && front->layer->rear);
+		// assert(front && front->layer && front->layer->screen && front->layer->rear);
 		front = front->layer->rear;
 		front = front->layer->rear;
 		goto Top;
 		goto Top;
 	}
 	}

+ 1 - 1
sys/src/libmemlayer/ldelete.c

@@ -21,7 +21,7 @@ memldelete(Memimage *i)
 	s = i->layer->screen;
 	s = i->layer->screen;
 	if(s->fill){
 	if(s->fill){
 		i->clipr = i->r;
 		i->clipr = i->r;
-		memdraw(i, i->r, s->fill, i->r.min, nil, i->r.min);
+		memdraw(i, i->r, s->fill, i->r.min, nil, i->r.min, S);
 	}
 	}
 	if(l->front){
 	if(l->front){
 		l->front->layer->rear = nil;
 		l->front->layer->rear = nil;

+ 2 - 2
sys/src/libmemlayer/lhide.c

@@ -27,7 +27,7 @@ lhideop(Memimage *src, Rectangle screenr, Rectangle clipr, void *etc, int insave
 	l = etc;
 	l = etc;
 	if(src != l->save){	/* do nothing if src is already in save area */
 	if(src != l->save){	/* do nothing if src is already in save area */
 		r = rectsubpt(screenr, l->delta);
 		r = rectsubpt(screenr, l->delta);
-		memdraw(l->save, r, src, screenr.min, nil, screenr.min);
+		memdraw(l->save, r, src, screenr.min, nil, screenr.min, S);
 	}
 	}
 }
 }
 
 
@@ -54,7 +54,7 @@ lexposeop(Memimage *dst, Rectangle screenr, Rectangle clipr, void *etc, int insa
 	l = etc;
 	l = etc;
 	r = rectsubpt(screenr, l->delta);
 	r = rectsubpt(screenr, l->delta);
 	if(l->save)
 	if(l->save)
-		memdraw(dst, screenr, l->save, r.min, nil, r.min);
+		memdraw(dst, screenr, l->save, r.min, nil, r.min, S);
 	else
 	else
 		l->refreshfn(dst, r, l->refreshptr);
 		l->refreshfn(dst, r, l->refreshptr);
 }
 }

+ 7 - 5
sys/src/libmemlayer/line.c

@@ -15,13 +15,14 @@ struct Lline
 	Point			sp;
 	Point			sp;
 	Memlayer		*dstlayer;
 	Memlayer		*dstlayer;
 	Memimage	*src;
 	Memimage	*src;
+	int			op;
 };
 };
 
 
 static void llineop(Memimage*, Rectangle, Rectangle, void*, int);
 static void llineop(Memimage*, Rectangle, Rectangle, void*, int);
 
 
 static
 static
 void
 void
-_memline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp, Rectangle clipr)
+_memline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp, Rectangle clipr, int op)
 {
 {
 	Rectangle r;
 	Rectangle r;
 	struct Lline ll;
 	struct Lline ll;
@@ -38,7 +39,7 @@ _memline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memi
    Top:
    Top:
 	dl = dst->layer;
 	dl = dst->layer;
 	if(dl == nil){
 	if(dl == nil){
-		_memimageline(dst, p0, p1, end0, end1, radius, src, sp, clipr);
+		_memimageline(dst, p0, p1, end0, end1, radius, src, sp, clipr, op);
 		return;
 		return;
 	}
 	}
 	if(!srcclipped){
 	if(!srcclipped){
@@ -86,6 +87,7 @@ _memline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memi
 	ll.src = src;
 	ll.src = src;
 	ll.radius = radius;
 	ll.radius = radius;
 	ll.delta = dl->delta;
 	ll.delta = dl->delta;
+	ll.op = op;
 	_memlayerop(llineop, dst, r, r, &ll);
 	_memlayerop(llineop, dst, r, r, &ll);
 }
 }
 
 
@@ -110,11 +112,11 @@ llineop(Memimage *dst, Rectangle screenr, Rectangle clipr, void *etc, int insave
 		p0 = ll->p0;
 		p0 = ll->p0;
 		p1 = ll->p1;
 		p1 = ll->p1;
 	}
 	}
-	_memline(dst, p0, p1, ll->end0, ll->end1, ll->radius, ll->src, ll->sp, clipr);
+	_memline(dst, p0, p1, ll->end0, ll->end1, ll->radius, ll->src, ll->sp, clipr, ll->op);
 }
 }
 
 
 void
 void
-memline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp)
+memline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp, int op)
 {
 {
-	_memline(dst, p0, p1, end0, end1, radius, src, sp, dst->clipr);
+	_memline(dst, p0, p1, end0, end1, radius, src, sp, dst->clipr, op);
 }
 }

+ 1 - 1
sys/src/libmemlayer/load.c

@@ -49,7 +49,7 @@ memload(Memimage *dst, Rectangle r, uchar *data, int n, int iscompressed)
 	if(tmp == nil)
 	if(tmp == nil)
 		return -1;
 		return -1;
 	n = loadfn(tmp, lr, data, n);
 	n = loadfn(tmp, lr, data, n);
-	memdraw(dst, lr, tmp, lr.min, nil, lr.min);
+	memdraw(dst, lr, tmp, lr.min, nil, lr.min, S);
 	freememimage(tmp);
 	freememimage(tmp);
 	return n;
 	return n;
 }
 }

+ 2 - 2
sys/src/libmemlayer/lorigin.c

@@ -39,7 +39,7 @@ memlorigin(Memimage *i, Point log, Point scr)
 	wasclear = l->clear;
 	wasclear = l->clear;
 	if(nsave){
 	if(nsave){
 		if(!wasclear)
 		if(!wasclear)
-			memimagedraw(nsave, nsave->r, l->save, l->save->r.min, nil, Pt(0,0));
+			memimagedraw(nsave, nsave->r, l->save, l->save->r.min, nil, Pt(0,0), S);
 		freememimage(l->save);
 		freememimage(l->save);
 		l->save = nsave;
 		l->save = nsave;
 	}
 	}
@@ -90,7 +90,7 @@ memlorigin(Memimage *i, Point log, Point scr)
 	 * Everything's covered.  Copy to new position and delete shadow window.
 	 * Everything's covered.  Copy to new position and delete shadow window.
 	 */
 	 */
 	if(wasclear)
 	if(wasclear)
-		memdraw(s->image, newr, s->image, oldr.min, nil, Pt(0,0));
+		memdraw(s->image, newr, s->image, oldr.min, nil, Pt(0,0), S);
 	else
 	else
 		memlexpose(i, newr);
 		memlexpose(i, newr);
 	memldelete(shad);
 	memldelete(shad);

+ 0 - 1
sys/src/libmemlayer/mkfile

@@ -25,6 +25,5 @@ UPDATE=\
 	mkfile\
 	mkfile\
 	$HFILES\
 	$HFILES\
 	${OFILES:%.$O=%.c}\
 	${OFILES:%.$O=%.c}\
-	${LIB:/$objtype/%=/386/%}\
 
 
 </sys/src/cmd/mksyslib
 </sys/src/cmd/mksyslib

+ 1 - 1
sys/src/libmemlayer/unload.c

@@ -45,7 +45,7 @@ memunload(Memimage *src, Rectangle r, uchar *data, int n)
 	tmp = allocmemimage(lr, src->chan);
 	tmp = allocmemimage(lr, src->chan);
 	if(tmp == nil)
 	if(tmp == nil)
 		return -1;
 		return -1;
-	memdraw(tmp, lr, src, lr.min, nil, lr.min);
+	memdraw(tmp, lr, src, lr.min, nil, lr.min, S);
 	n = unloadmemimage(tmp, lr, data, n);
 	n = unloadmemimage(tmp, lr, data, n);
 	freememimage(tmp);
 	freememimage(tmp);
 	return n;
 	return n;

Some files were not shown because too many files changed in this diff