+++ /dev/null
-;\r
-; MODEX library default font\r
-; Copyright (c) 1993-1994 by Alessandro Scotti\r
-;\r
- DB 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; #0\r
- DB 07Eh, 081h, 0A5h, 081h, 0A5h, 099h, 081h, 07Eh ; #1\r
- DB 07Eh, 0FFh, 0DBh, 0FFh, 0DBh, 0E7h, 0FFh, 07Eh ; #2\r
- DB 06Ch, 0FEh, 0FEh, 0FEh, 07Ch, 038h, 010h, 000h ; #3\r
- DB 010h, 038h, 07Ch, 0FEh, 07Ch, 038h, 010h, 000h ; #4\r
- DB 010h, 038h, 010h, 054h, 0FEh, 054h, 010h, 0FEh ; #5\r
- DB 010h, 038h, 07Ch, 0FEh, 0FEh, 07Ch, 010h, 0FEh ; #6\r
- DB 000h, 018h, 03Ch, 07Eh, 07Eh, 03Ch, 018h, 000h ; #7\r
- DB 0FFh, 0E7h, 0C3h, 081h, 081h, 0C3h, 0E7h, 0FFh ; #8\r
- DB 000h, 03Ch, 066h, 042h, 042h, 066h, 03Ch, 000h ; #9\r
- DB 0FFh, 0C3h, 099h, 0BDh, 0BDh, 099h, 0C3h, 0FFh ; #10\r
- DB 007h, 003h, 005h, 078h, 084h, 084h, 084h, 078h ; #11\r
- DB 07Ch, 082h, 082h, 082h, 07Ch, 010h, 038h, 010h ; #12\r
- DB 01Ch, 010h, 01Ch, 010h, 010h, 010h, 030h, 030h ; #13\r
- DB 03Eh, 022h, 03Eh, 022h, 022h, 026h, 066h, 060h ; #14\r
- DB 099h, 05Ah, 03Ch, 0E7h, 0E7h, 03Ch, 05Ah, 099h ; #15\r
- DB 000h, 010h, 030h, 070h, 0F0h, 070h, 030h, 010h ; #16\r
- DB 000h, 080h, 0C0h, 0E0h, 0F0h, 0E0h, 0C0h, 080h ; #17\r
- DB 010h, 038h, 054h, 010h, 010h, 054h, 038h, 010h ; #18\r
- DB 048h, 048h, 048h, 048h, 048h, 000h, 048h, 000h ; #19\r
- DB 07Eh, 092h, 092h, 072h, 012h, 012h, 012h, 000h ; #20\r
- DB 03Ch, 022h, 018h, 024h, 024h, 018h, 044h, 03Ch ; #21\r
- DB 000h, 000h, 000h, 000h, 000h, 03Eh, 03Eh, 000h ; #22\r
- DB 038h, 054h, 010h, 010h, 010h, 054h, 038h, 0FEh ; #23\r
- DB 000h, 010h, 038h, 054h, 010h, 010h, 010h, 000h ; #24\r
- DB 000h, 010h, 010h, 010h, 054h, 038h, 010h, 000h ; #25\r
- DB 000h, 008h, 004h, 0FEh, 004h, 008h, 000h, 000h ; #26\r
- DB 000h, 020h, 040h, 0FEh, 040h, 020h, 000h, 000h ; #27\r
- DB 000h, 000h, 080h, 080h, 080h, 0FCh, 000h, 000h ; #28\r
- DB 000h, 024h, 042h, 0FFh, 042h, 024h, 000h, 000h ; #29\r
- DB 000h, 000h, 010h, 038h, 07Ch, 0FEh, 000h, 000h ; #30\r
- DB 000h, 000h, 0FEh, 07Ch, 038h, 010h, 000h, 000h ; #31\r
- DB 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; \r
- DB 010h, 010h, 010h, 010h, 010h, 000h, 010h, 000h ; !\r
- DB 000h, 024h, 024h, 000h, 000h, 000h, 000h, 000h ; "\r
- DB 024h, 024h, 07Eh, 024h, 07Eh, 024h, 024h, 000h ; #\r
- DB 038h, 054h, 050h, 038h, 014h, 054h, 038h, 010h ; $\r
- DB 000h, 002h, 044h, 008h, 010h, 020h, 042h, 000h ; %\r
- DB 038h, 044h, 038h, 060h, 094h, 088h, 074h, 000h ; &\r
- DB 020h, 020h, 040h, 000h, 000h, 000h, 000h, 000h ; '\r
- DB 010h, 020h, 040h, 040h, 040h, 020h, 010h, 000h ; (\r
- DB 040h, 020h, 010h, 010h, 010h, 020h, 040h, 000h ; )\r
- DB 000h, 024h, 018h, 07Eh, 018h, 024h, 000h, 000h ; *\r
- DB 000h, 010h, 010h, 07Ch, 010h, 010h, 000h, 000h ; +\r
- DB 000h, 000h, 000h, 000h, 000h, 010h, 010h, 020h ; ,\r
- DB 000h, 000h, 000h, 0FCh, 000h, 000h, 000h, 000h ; -\r
- DB 000h, 000h, 000h, 000h, 000h, 000h, 010h, 000h ; .\r
- DB 000h, 004h, 008h, 010h, 020h, 040h, 080h, 000h ; /\r
- DB 07Ch, 0C6h, 08Ah, 092h, 0A2h, 0C6h, 07Ch, 000h ; 0\r
- DB 010h, 030h, 010h, 010h, 010h, 010h, 038h, 000h ; 1\r
- DB 078h, 084h, 004h, 018h, 060h, 080h, 0FCh, 000h ; 2\r
- DB 078h, 084h, 004h, 038h, 004h, 084h, 078h, 000h ; 3\r
- DB 01Ch, 024h, 044h, 084h, 0FEh, 004h, 00Eh, 000h ; 4\r
- DB 0FCh, 080h, 0F8h, 004h, 004h, 084h, 078h, 000h ; 5\r
- DB 078h, 084h, 080h, 0F8h, 084h, 084h, 078h, 000h ; 6\r
- DB 0FCh, 004h, 004h, 008h, 010h, 020h, 020h, 000h ; 7\r
- DB 078h, 084h, 084h, 078h, 084h, 084h, 078h, 000h ; 8\r
- DB 078h, 084h, 084h, 07Ch, 004h, 084h, 078h, 000h ; 9\r
- DB 000h, 000h, 010h, 000h, 000h, 000h, 010h, 000h ; :\r
- DB 000h, 000h, 010h, 000h, 000h, 010h, 010h, 020h ; ;\r
- DB 008h, 010h, 020h, 040h, 020h, 010h, 008h, 000h ; <\r
- DB 000h, 000h, 0FCh, 000h, 000h, 0FCh, 000h, 000h ; =\r
- DB 040h, 020h, 010h, 008h, 010h, 020h, 040h, 000h ; >\r
- DB 078h, 084h, 004h, 008h, 010h, 000h, 010h, 000h ; ?\r
- DB 07Ch, 082h, 0BAh, 0A6h, 0BEh, 080h, 07Ch, 000h ; @\r
- DB 078h, 084h, 084h, 0FCh, 084h, 084h, 084h, 000h ; A\r
- DB 0F8h, 084h, 084h, 0F8h, 084h, 084h, 0F8h, 000h ; B\r
- DB 078h, 084h, 080h, 080h, 080h, 084h, 078h, 000h ; C\r
- DB 0F0h, 088h, 084h, 084h, 084h, 088h, 0F0h, 000h ; D\r
- DB 0FCh, 080h, 080h, 0F0h, 080h, 080h, 0FCh, 000h ; E\r
- DB 0FCh, 080h, 080h, 0F0h, 080h, 080h, 080h, 000h ; F\r
- DB 078h, 084h, 080h, 09Ch, 084h, 084h, 078h, 000h ; G\r
- DB 084h, 084h, 084h, 0FCh, 084h, 084h, 084h, 000h ; H\r
- DB 038h, 010h, 010h, 010h, 010h, 010h, 038h, 000h ; I\r
- DB 01Ch, 008h, 008h, 008h, 088h, 088h, 070h, 000h ; J\r
- DB 084h, 088h, 090h, 0E0h, 090h, 088h, 084h, 000h ; K\r
- DB 080h, 080h, 080h, 080h, 080h, 080h, 0FCh, 000h ; L\r
- DB 0C6h, 0AAh, 092h, 082h, 082h, 082h, 082h, 000h ; M\r
- DB 082h, 0C2h, 0A2h, 092h, 08Ah, 086h, 082h, 000h ; N\r
- DB 078h, 084h, 084h, 084h, 084h, 084h, 078h, 000h ; O\r
- DB 0F8h, 084h, 084h, 0F8h, 080h, 080h, 080h, 000h ; P\r
- DB 078h, 084h, 084h, 084h, 094h, 088h, 076h, 000h ; Q\r
- DB 0F8h, 084h, 084h, 0F8h, 090h, 088h, 084h, 000h ; R\r
- DB 078h, 084h, 080h, 078h, 004h, 084h, 078h, 000h ; S\r
- DB 0FEh, 010h, 010h, 010h, 010h, 010h, 010h, 000h ; T\r
- DB 084h, 084h, 084h, 084h, 084h, 084h, 078h, 000h ; U\r
- DB 084h, 084h, 084h, 084h, 084h, 048h, 030h, 000h ; V\r
- DB 082h, 082h, 082h, 082h, 092h, 0AAh, 0C6h, 000h ; W\r
- DB 082h, 044h, 028h, 010h, 028h, 044h, 082h, 000h ; X\r
- DB 044h, 044h, 044h, 038h, 010h, 010h, 010h, 000h ; Y\r
- DB 0FEh, 004h, 008h, 010h, 020h, 040h, 0FEh, 000h ; Z\r
- DB 078h, 040h, 040h, 040h, 040h, 040h, 078h, 000h ; [\r
- DB 000h, 080h, 040h, 020h, 010h, 008h, 004h, 000h ; \\r
- DB 078h, 008h, 008h, 008h, 008h, 008h, 078h, 000h ; ]\r
- DB 010h, 028h, 044h, 082h, 000h, 000h, 000h, 000h ; ^\r
- DB 000h, 000h, 000h, 000h, 000h, 000h, 000h, 0FFh ; _\r
- DB 020h, 020h, 010h, 000h, 000h, 000h, 000h, 000h ; `\r
- DB 000h, 000h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; a\r
- DB 000h, 040h, 040h, 078h, 044h, 044h, 078h, 000h ; b\r
- DB 000h, 000h, 03Ch, 040h, 040h, 040h, 03Ch, 000h ; c\r
- DB 000h, 004h, 004h, 03Ch, 044h, 044h, 03Ch, 000h ; d\r
- DB 000h, 000h, 038h, 044h, 07Ch, 040h, 03Ch, 000h ; e\r
- DB 000h, 00Ch, 010h, 03Ch, 010h, 010h, 010h, 000h ; f\r
- DB 000h, 000h, 03Ch, 044h, 044h, 03Ch, 004h, 038h ; g\r
- DB 000h, 040h, 040h, 078h, 044h, 044h, 044h, 000h ; h\r
- DB 000h, 010h, 000h, 010h, 010h, 010h, 010h, 000h ; i\r
- DB 000h, 004h, 000h, 004h, 004h, 004h, 044h, 038h ; j\r
- DB 000h, 040h, 040h, 050h, 060h, 050h, 048h, 000h ; k\r
- DB 000h, 030h, 010h, 010h, 010h, 010h, 010h, 000h ; l\r
- DB 000h, 000h, 068h, 054h, 054h, 044h, 044h, 000h ; m\r
- DB 000h, 000h, 078h, 044h, 044h, 044h, 044h, 000h ; n\r
- DB 000h, 000h, 038h, 044h, 044h, 044h, 038h, 000h ; o\r
- DB 000h, 000h, 078h, 044h, 044h, 078h, 040h, 040h ; p\r
- DB 000h, 000h, 03Ch, 044h, 044h, 03Ch, 004h, 004h ; q\r
- DB 000h, 000h, 05Ch, 060h, 040h, 040h, 040h, 000h ; r\r
- DB 000h, 000h, 038h, 040h, 07Ch, 004h, 07Ch, 000h ; s\r
- DB 000h, 010h, 038h, 010h, 010h, 010h, 018h, 000h ; t\r
- DB 000h, 000h, 044h, 044h, 044h, 044h, 038h, 000h ; u\r
- DB 000h, 000h, 044h, 044h, 044h, 028h, 010h, 000h ; v\r
- DB 000h, 000h, 044h, 044h, 054h, 054h, 06Ch, 000h ; w\r
- DB 000h, 000h, 044h, 028h, 010h, 028h, 044h, 000h ; x\r
- DB 000h, 000h, 044h, 044h, 044h, 03Ch, 004h, 07Ch ; y\r
- DB 000h, 000h, 07Ch, 004h, 038h, 040h, 07Ch, 000h ; z\r
- DB 000h, 008h, 010h, 010h, 030h, 010h, 010h, 008h ; {\r
- DB 000h, 010h, 010h, 010h, 000h, 010h, 010h, 010h ; |\r
- DB 000h, 020h, 010h, 010h, 018h, 010h, 010h, 020h ; }\r
- DB 064h, 098h, 000h, 000h, 000h, 000h, 000h, 000h ; ~\r
- DB 000h, 010h, 028h, 044h, 082h, 082h, 0FEh, 000h ; \7f\r
- DB 07Ch, 080h, 080h, 080h, 080h, 07Ch, 004h, 07Ch ; #128\r
- DB 000h, 028h, 000h, 044h, 044h, 044h, 038h, 000h ; #129\r
- DB 03Ch, 000h, 07Ch, 044h, 07Ch, 040h, 07Ch, 000h ; #130\r
- DB 07Eh, 081h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; #131\r
- DB 024h, 000h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; #132\r
- DB 078h, 000h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; #133\r
- DB 018h, 018h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; #134\r
- DB 000h, 000h, 078h, 080h, 080h, 078h, 008h, 038h ; #135\r
- DB 07Ch, 082h, 038h, 044h, 07Ch, 040h, 03Ch, 000h ; #136\r
- DB 048h, 000h, 038h, 044h, 07Ch, 040h, 03Ch, 000h ; #137\r
- DB 078h, 000h, 038h, 044h, 07Ch, 040h, 03Ch, 000h ; #138\r
- DB 000h, 028h, 000h, 010h, 010h, 010h, 010h, 000h ; #139\r
- DB 010h, 028h, 000h, 010h, 010h, 010h, 010h, 000h ; #140\r
- DB 000h, 030h, 000h, 010h, 010h, 010h, 010h, 000h ; #141\r
- DB 048h, 000h, 078h, 084h, 0FCh, 084h, 084h, 000h ; #142\r
- DB 030h, 030h, 078h, 084h, 0FCh, 084h, 084h, 000h ; #143\r
- DB 038h, 000h, 0FCh, 080h, 0F0h, 080h, 0FCh, 000h ; #144\r
- DB 000h, 000h, 07Eh, 008h, 07Eh, 048h, 07Eh, 000h ; #145\r
- DB 07Eh, 090h, 090h, 0FCh, 090h, 090h, 09Eh, 000h ; #146\r
- DB 07Ch, 082h, 038h, 044h, 044h, 044h, 038h, 000h ; #147\r
- DB 028h, 000h, 038h, 044h, 044h, 044h, 038h, 000h ; #148\r
- DB 070h, 000h, 038h, 044h, 044h, 044h, 038h, 000h ; #149\r
- DB 038h, 044h, 000h, 044h, 044h, 044h, 038h, 000h ; #150\r
- DB 070h, 000h, 044h, 044h, 044h, 044h, 038h, 000h ; #151\r
- DB 028h, 000h, 044h, 044h, 044h, 03Ch, 004h, 07Ch ; #152\r
- DB 048h, 000h, 078h, 084h, 084h, 084h, 078h, 000h ; #153\r
- DB 048h, 000h, 084h, 084h, 084h, 084h, 078h, 000h ; #154\r
- DB 000h, 010h, 038h, 040h, 040h, 040h, 038h, 010h ; #155\r
- DB 038h, 044h, 040h, 0E0h, 040h, 040h, 082h, 0FCh ; #156\r
- DB 044h, 07Ch, 010h, 07Ch, 010h, 07Ch, 010h, 000h ; #157\r
- DB 0F0h, 088h, 08Ah, 0F7h, 082h, 082h, 082h, 000h ; #158\r
- DB 00Ch, 012h, 010h, 018h, 030h, 010h, 090h, 060h ; #159\r
- DB 03Ch, 000h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; #160\r
- DB 000h, 018h, 000h, 010h, 010h, 010h, 010h, 000h ; #161\r
- DB 01Ch, 000h, 038h, 044h, 044h, 044h, 038h, 000h ; #162\r
- DB 01Ch, 000h, 044h, 044h, 044h, 044h, 038h, 000h ; #163\r
- DB 07Ch, 000h, 078h, 044h, 044h, 044h, 044h, 000h ; #164\r
- DB 07Ch, 000h, 044h, 064h, 054h, 04Ch, 044h, 000h ; #165\r
- DB 018h, 024h, 024h, 01Eh, 000h, 03Eh, 000h, 000h ; #166\r
- DB 01Ch, 022h, 022h, 01Ch, 000h, 03Eh, 000h, 000h ; #167\r
- DB 010h, 000h, 010h, 020h, 040h, 042h, 03Ch, 000h ; #168\r
- DB 000h, 000h, 000h, 0FCh, 080h, 080h, 000h, 000h ; #169\r
- DB 000h, 000h, 000h, 0FCh, 004h, 004h, 000h, 000h ; #170\r
- DB 040h, 044h, 048h, 057h, 021h, 047h, 004h, 007h ; #171\r
- DB 040h, 044h, 048h, 052h, 026h, 04Ah, 01Fh, 002h ; #172\r
- DB 010h, 000h, 010h, 010h, 010h, 010h, 010h, 000h ; #173\r
- DB 000h, 024h, 048h, 090h, 048h, 024h, 000h, 000h ; #174\r
- DB 000h, 048h, 024h, 012h, 024h, 048h, 000h, 000h ; #175\r
- DB 022h, 088h, 022h, 088h, 022h, 088h, 022h, 088h ; #176\r
- DB 055h, 0AAh, 055h, 0AAh, 055h, 0AAh, 055h, 0AAh ; #177\r
- DB 0DBh, 077h, 0DBh, 0EEh, 0DBh, 077h, 0DBh, 0EEh ; #178\r
- DB 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h ; #179\r
- DB 018h, 018h, 018h, 018h, 0F8h, 018h, 018h, 018h ; #180\r
- DB 018h, 018h, 0F8h, 018h, 0F8h, 018h, 018h, 018h ; #181\r
- DB 036h, 036h, 036h, 036h, 0F6h, 036h, 036h, 036h ; #182\r
- DB 000h, 000h, 000h, 000h, 0FEh, 036h, 036h, 036h ; #183\r
- DB 000h, 000h, 0F8h, 018h, 0F8h, 018h, 018h, 018h ; #184\r
- DB 036h, 036h, 0F6h, 006h, 0F6h, 036h, 036h, 036h ; #185\r
- DB 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h ; #186\r
- DB 000h, 000h, 0FEh, 006h, 0F6h, 036h, 036h, 036h ; #187\r
- DB 036h, 036h, 0F6h, 006h, 0FEh, 000h, 000h, 000h ; #188\r
- DB 036h, 036h, 036h, 036h, 0FEh, 000h, 000h, 000h ; #189\r
- DB 018h, 018h, 0F8h, 018h, 0F8h, 000h, 000h, 000h ; #190\r
- DB 000h, 000h, 000h, 000h, 0F8h, 018h, 018h, 018h ; #191\r
- DB 018h, 018h, 018h, 018h, 01Fh, 000h, 000h, 000h ; #192\r
- DB 018h, 018h, 018h, 018h, 0FFh, 000h, 000h, 000h ; #193\r
- DB 000h, 000h, 000h, 000h, 0FFh, 018h, 018h, 018h ; #194\r
- DB 018h, 018h, 018h, 018h, 01Fh, 018h, 018h, 018h ; #195\r
- DB 000h, 000h, 000h, 000h, 0FFh, 000h, 000h, 000h ; #196\r
- DB 018h, 018h, 018h, 018h, 0FFh, 018h, 018h, 018h ; #197\r
- DB 018h, 018h, 01Fh, 018h, 01Fh, 018h, 018h, 018h ; #198\r
- DB 036h, 036h, 036h, 036h, 037h, 036h, 036h, 036h ; #199\r
- DB 036h, 036h, 037h, 030h, 03Fh, 000h, 000h, 000h ; #200\r
- DB 000h, 000h, 03Fh, 030h, 037h, 036h, 036h, 036h ; #201\r
- DB 036h, 036h, 0F7h, 000h, 0FFh, 000h, 000h, 000h ; #202\r
- DB 000h, 000h, 0FFh, 000h, 0F7h, 036h, 036h, 036h ; #203\r
- DB 036h, 036h, 037h, 030h, 037h, 036h, 036h, 036h ; #204\r
- DB 000h, 000h, 0FFh, 000h, 0FFh, 000h, 000h, 000h ; #205\r
- DB 036h, 036h, 0F7h, 000h, 0F7h, 036h, 036h, 036h ; #206\r
- DB 018h, 018h, 0FFh, 000h, 0FFh, 000h, 000h, 000h ; #207\r
- DB 036h, 036h, 036h, 036h, 0FFh, 000h, 000h, 000h ; #208\r
- DB 000h, 000h, 0FFh, 000h, 0FFh, 018h, 018h, 018h ; #209\r
- DB 000h, 000h, 000h, 000h, 0FFh, 036h, 036h, 036h ; #210\r
- DB 036h, 036h, 036h, 036h, 03Fh, 000h, 000h, 000h ; #211\r
- DB 018h, 018h, 01Fh, 018h, 01Fh, 000h, 000h, 000h ; #212\r
- DB 000h, 000h, 01Fh, 018h, 01Fh, 018h, 018h, 018h ; #213\r
- DB 000h, 000h, 000h, 000h, 03Fh, 036h, 036h, 036h ; #214\r
- DB 036h, 036h, 036h, 036h, 0FFh, 036h, 036h, 036h ; #215\r
- DB 018h, 018h, 0FFh, 018h, 0FFh, 018h, 018h, 018h ; #216\r
- DB 018h, 018h, 018h, 018h, 0F8h, 000h, 000h, 000h ; #217\r
- DB 000h, 000h, 000h, 000h, 01Fh, 018h, 018h, 018h ; #218\r
- DB 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh ; #219\r
- DB 000h, 000h, 000h, 000h, 0FFh, 0FFh, 0FFh, 0FFh ; #220\r
- DB 0F0h, 0F0h, 0F0h, 0F0h, 0F0h, 0F0h, 0F0h, 0F0h ; #221\r
- DB 00Fh, 00Fh, 00Fh, 00Fh, 00Fh, 00Fh, 00Fh, 00Fh ; #222\r
- DB 0FFh, 0FFh, 0FFh, 0FFh, 000h, 000h, 000h, 000h ; #223\r
- DB 000h, 000h, 062h, 094h, 088h, 094h, 062h, 000h ; #224\r
- DB 000h, 0F0h, 088h, 0F0h, 088h, 088h, 0F0h, 080h ; #225\r
- DB 000h, 0F8h, 088h, 080h, 080h, 080h, 080h, 000h ; #226\r
- DB 000h, 0FCh, 048h, 048h, 048h, 048h, 048h, 000h ; #227\r
- DB 0FCh, 084h, 040h, 020h, 040h, 084h, 0FCh, 000h ; #228\r
- DB 03Ch, 040h, 038h, 044h, 044h, 044h, 038h, 000h ; #229\r
- DB 000h, 000h, 044h, 044h, 044h, 078h, 040h, 040h ; #230\r
- DB 000h, 036h, 048h, 008h, 008h, 008h, 008h, 000h ; #231\r
- DB 038h, 010h, 038h, 044h, 044h, 038h, 010h, 038h ; #232\r
- DB 078h, 084h, 084h, 0FCh, 084h, 084h, 078h, 000h ; #233\r
- DB 078h, 084h, 084h, 084h, 048h, 048h, 0CCh, 000h ; #234\r
- DB 078h, 004h, 038h, 044h, 044h, 044h, 038h, 000h ; #235\r
- DB 000h, 000h, 06Ch, 092h, 092h, 06Ch, 000h, 000h ; #236\r
- DB 000h, 000h, 03Ah, 044h, 05Ah, 022h, 05Ch, 000h ; #237\r
- DB 018h, 020h, 040h, 078h, 040h, 020h, 018h, 000h ; #238\r
- DB 078h, 084h, 084h, 084h, 084h, 084h, 084h, 000h ; #239\r
- DB 000h, 0FCh, 000h, 0FCh, 000h, 0FCh, 000h, 000h ; #240\r
- DB 020h, 020h, 0F8h, 020h, 020h, 000h, 0F8h, 000h ; #241\r
- DB 020h, 010h, 008h, 010h, 020h, 000h, 07Ch, 000h ; #242\r
- DB 008h, 010h, 020h, 010h, 008h, 000h, 07Ch, 000h ; #243\r
- DB 00Ch, 012h, 010h, 010h, 010h, 010h, 010h, 010h ; #244\r
- DB 010h, 010h, 010h, 010h, 010h, 010h, 090h, 060h ; #245\r
- DB 000h, 010h, 000h, 07Ch, 000h, 010h, 000h, 000h ; #246\r
- DB 000h, 032h, 04Ch, 000h, 032h, 04Ch, 000h, 000h ; #247\r
- DB 038h, 044h, 044h, 038h, 000h, 000h, 000h, 000h ; #248\r
- DB 000h, 000h, 000h, 018h, 018h, 000h, 000h, 000h ; #249\r
- DB 000h, 000h, 000h, 000h, 018h, 000h, 000h, 000h ; #250\r
- DB 00Eh, 008h, 008h, 008h, 048h, 028h, 018h, 008h ; #251\r
- DB 038h, 024h, 024h, 024h, 024h, 000h, 000h, 000h ; #252\r
- DB 03Ch, 004h, 03Ch, 020h, 03Ch, 000h, 000h, 000h ; #253\r
- DB 000h, 000h, 03Ch, 03Ch, 03Ch, 03Ch, 000h, 000h ; #254\r
- DB 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; #255\r
+++ /dev/null
-#\r
-# MODEX library makefile (for Borland MAKE)\r
-# Copyright (c) 1993,1994 by Alessandro Scotti\r
-#\r
-LIBINCS = MODEX.DEF\r
-\r
-LIBOBJS = MXBB.OBJ \\r
- MXCC.OBJ \\r
- MXCG.OBJ \\r
- MXCL.OBJ \\r
- MXCR.OBJ \\r
- MXFB.OBJ \\r
- MXFP.OBJ \\r
- MXGC.OBJ \\r
- MXGI.OBJ \\r
- MXGM.OBJ \\r
- MXGP.OBJ \\r
- MXGV.OBJ \\r
- MXHL.OBJ \\r
- MXIT.OBJ \\r
- MXLL.OBJ \\r
- MXLN.OBJ \\r
- MXOT.OBJ \\r
- MXPB.OBJ \\r
- MXPF.OBJ \\r
- MXPG.OBJ \\r
- MXPI.OBJ \\r
- MXPN.OBJ \\r
- MXPP.OBJ \\r
- MXRA.OBJ \\r
- MXRP.OBJ \\r
- MXSA.OBJ \\r
- MXSC.OBJ \\r
- MXSI.OBJ \\r
- MXSL.OBJ \\r
- MXSM.OBJ \\r
- MXSP.OBJ \\r
- MXSS.OBJ \\r
- MXTL.OBJ \\r
- MXVS.OBJ \\r
- MXWD.OBJ \\r
- MXWM.OBJ \\r
- MXWP.OBJ \\r
- MXWR.OBJ\r
-\r
-#\r
-# ASM compiler\r
-#\r
-ASMC = tasm\r
-ASMO = /m5 /p\r
-\r
-#\r
-# PAS compiler\r
-#\r
-PASC = tpc\r
-PASO = /m -$D- -$L- -$S-\r
-\r
-#\r
-# LIB maker, uses response file\r
-#\r
-LIBC = tlib\r
-\r
-.asm.obj:\r
- $(ASMC) $(ASMO) $<\r
-\r
-target: modex.lib
-# modex.tpu modex.tpp\r
-\r
-#modex.tpu: $(LIBOBJS) modex.pas\r
-# $(PASC) $(PASO) modex\r
-# copy modex.tpu ..\r
-# copy modex.pas ..\r
-\r
-#modex.tpp: $(LIBOBJS) modex.pas\r
-# $(PASC) /cp $(PASO) modex\r
-# copy modex.tpp ..\r
-\r
-modex.lib: modex.lbr $(LIBOBJS)\r
- $(LIBC) modex.lib @modex.lbr\r
-\r
-$(LIBOBJS): modex.def\r
+++ /dev/null
-;------------------------------------------------------------\r
-;\r
-; MODEX.DEF - Include file\r
-; Copyright (c) 1993-1994 by Alessandro Scotti\r
-;\r
-JUMPS\r
-LOCALS\r
-\r
-TRUE EQU 1 ; Boolean constants\r
-FALSE EQU 0\r
-\r
-USE286 = FALSE ; TRUE enables 80286 instructions\r
-USE386 = FALSE ; TRUE enables 80386 (and 80286) instructions\r
-\r
-IF USE286 EQ TRUE\r
- P286\r
-ENDIF\r
-\r
-IF USE386 EQ TRUE\r
- P386\r
- USE286 = TRUE\r
-ENDIF\r
-\r
-MXVERSION EQU 0128h ; Library version (1.40)\r
-\r
-;------------------------------------------------------------\r
-;\r
-; VGA definitions\r
-;\r
-MISC EQU 3C2h ; Miscellaneous output\r
-TS EQU 3C4h ; Timing Sequencer index register\r
-GDC EQU 3CEh ; Graphics Data Controller index register\r
-CRTC EQU 3D4h ; CRTC index register\r
-STATUS EQU 3DAh ; Input Status register one\r
-\r
-;------------------------------------------------------------\r
-;\r
-; Raster operators\r
-;\r
-OP_SET EQU 0\r
-OP_MOVE EQU 0 ; Same as OP_SET\r
-OP_AND EQU 1\r
-OP_OR EQU 2\r
-OP_XOR EQU 3\r
-OP_TRANS EQU 4\r
-OP_ADD EQU 5 ; Must be last op\r
-\r
-;------------------------------------------------------------\r
-;\r
-; Polygon fill functions\r
-;\r
-POLYSCANBUFSIZE EQU 4*1024\r
-\r
-;------------------------------------------------------------\r
-; Macro to push registers, variables or flags onto the stack\r
-; Usage: .push "loc16"[,"loc16"...]\r
-; where "loc16" is a 16-bit register, a word-sized variable or the\r
-; keyword "FLAGS".\r
-; Exmpl: .push ax, flags, var1\r
-; .pop ax, flags, var1\r
-;\r
-.push MACRO r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10\r
- IFNB <r10>\r
- .ERROR <.PUSH has more than 10 arguments>\r
- ENDIF\r
- IRP $reg, <r0, r1, r2, r3, r4, r5, r6, r7, r8, r9>\r
- IFB <$reg> ;; Is argument blank?\r
- EXITM ;; Yes, exit\r
- ELSEIFIDNI <$reg>, <FLAGS> ;; Is argument the keyword "FLAGS"?\r
- pushf ;; Yes, push flags\r
- ELSE\r
- push $reg ;; Push argument\r
- ENDIF\r
- ENDM\r
-ENDM\r
-\r
-;------------------------------------------------------------\r
-; Macro to pop registers, variables or flags from the stack\r
-; Usage: .pop "loc16"[,"loc16"...]\r
-; where "loc16" is a 16-bit register, a word-sized variable or the\r
-; keyword "FLAGS".\r
-; Exmpl: .push ax, flags, var1\r
-; .pop ax, flags, var1\r
-;\r
-.pop MACRO r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10\r
- IFNB <r10>\r
- .ERROR <.POP has more than 10 arguments>\r
- ENDIF\r
- IRP $reg, <r9, r8, r7, r6, r5, r4, r3, r2, r1, r0>\r
- IFNB <$reg> ;; Is argument non-blank?\r
- IFIDNI <$reg>, <FLAGS> ;; Yes, is it the keyword "FLAGS"?\r
- popf ;; Yes, pop flags\r
- ELSE\r
- pop $reg ;; Pop argument\r
- ENDIF\r
- ENDIF\r
- ENDM\r
-ENDM\r
-\r
-;------------------------------------------------------------\r
-;\r
-.enter MACRO localsize\r
- IF USE286 EQ TRUE\r
- enter localsize, 0\r
- ELSE\r
- push bp\r
- mov bp, sp\r
- sub sp, localsize\r
- ENDIF\r
-ENDM\r
-\r
-;------------------------------------------------------------\r
-;\r
-.leave MACRO argsize\r
- IF USE286 EQ TRUE\r
- leave\r
- ELSE\r
- mov sp, bp\r
- pop bp\r
- ENDIF\r
- IFNB <argspace>\r
- ret argsize\r
- ELSE\r
- ret\r
- ENDIF\r
-ENDM\r
-\r
-;------------------------------------------------------------\r
-;\r
-.shr MACRO arg, count\r
- IF USE286 EQ TRUE\r
- shr arg, count\r
- ELSE\r
- $temp = count\r
- WHILE $temp GT 0\r
- shr arg, 1\r
- $temp = $temp-1\r
- ENDM\r
- ENDIF\r
-ENDM\r
-\r
-;------------------------------------------------------------\r
-;\r
-.shl MACRO arg, count\r
- IF USE286 EQ TRUE\r
- shl arg, count\r
- ELSE\r
- $temp = count\r
- WHILE $temp GT 0\r
- shl arg, 1\r
- $temp = $temp-1\r
- ENDM\r
- ENDIF\r
-ENDM\r
-\r
-;------------------------------------------------------------\r
-;\r
-.chk386 MACRO name, jump\r
- IF USE386 EQ FALSE\r
- .OUT "Warning: ", <name>, " needs a 386 or better to run!"\r
- jmp @@jump\r
- ENDIF\r
-ENDM\r
+++ /dev/null
-/*\r
- MODEX.H - C/C++ include file for the MODEX library\r
- Copyright (c) 1994 Alessandro Scotti\r
-*/\r
-\r
-#ifndef _MODEX_H_ // Avoid nested inclusions\r
-#define _MODEX_H_\r
-\r
-//\r
-// Video modes\r
-//\r
-#define MX_TEXT 0 // 80x25 text\r
-#define MX_320x175 1 // 320x175x256\r
-#define MX_320x200 2 // 320x200x256, 4 pages, aspect 6:5\r
-#define MX_320x240 3 // 320x240x256, 3 pages, aspect 1:1\r
-#define MX_320x350 4 // 320x350x256\r
-#define MX_320x400 5 // 320x400x256, 2 pages\r
-#define MX_320x480 6 // 320x480x256, 1 page\r
-#define MX_360x175 7 // 360x175x256\r
-#define MX_360x200 8 // 360x200x256, 3 pages\r
-#define MX_360x240 9 // 360x240x256, 2 pages\r
-#define MX_360x350 10 // 360x350x256\r
-#define MX_360x400 11 // 360x400x256, 1 page\r
-#define MX_360x480 12 // 360x480x256, 1 page\r
-#define MX_400x600 13 // 400x600x256, 1 page\r
-\r
-//\r
-// Fade effects\r
-//\r
-#define MX_FADEIN 0\r
-#define MX_FADEOUT 1\r
-\r
-//\r
-// Raster ops\r
-//\r
-#define OP_SET 0 // No operator\r
-#define OP_AND 1 // And\r
-#define OP_OR 2 // Or\r
-#define OP_XOR 3 // Xor\r
-#define OP_TRANS 4 // Transparent\r
-#define OP_ADD 5 // Additive\r
-#define OP_MOVE 0 // Alias for OP_SET\r
-\r
-//\r
-// Temporary definitions\r
-//\r
-#define MXBYTE unsigned char\r
-#define MXBOOL short int\r
-#define MXSINT short int\r
-#define MXUINT unsigned short int\r
-#define MXAPI far pascal\r
-#define MXPTR void far *\r
-\r
-// Functions\r
-\r
-#ifdef __cplusplus // Avoid C++ name mangling\r
-extern "C" {\r
-#endif\r
-\r
-//\r
-// Initialization\r
-//\r
-MXSINT MXAPI mxInit( void ); // Returns 0 if successful\r
-void MXAPI mxTerm( void );\r
-MXUINT MXAPI mxGetVersion( void );\r
-//\r
-// Mode setting\r
-//\r
-void MXAPI mxChangeMode( MXUINT mode );\r
-void MXAPI mxSetMode( MXUINT mode );\r
-void MXAPI mxGetAspect( MXUINT far *aspectx, MXUINT far *aspecty );\r
-void MXAPI mxGetScreenSize( MXUINT far *width, MXUINT far *height );\r
-//\r
-// Hardware support\r
-//\r
-void MXAPI mxWriteMode( MXBYTE wm );\r
-void MXAPI mxSplitScreen( MXUINT line );\r
-void MXAPI mxStartAddress( MXUINT sa );\r
-void MXAPI mxStartLine( MXUINT sl );\r
-void MXAPI mxWaitDisplay( void );\r
-void MXAPI mxWaitRetrace( void );\r
-void MXAPI mxWritePlane( MXBYTE wp );\r
-void MXAPI mxReadPlane( MXBYTE rp );\r
-void MXAPI mxRowAddress( MXBYTE ra );\r
-//\r
-// Virtual screen\r
-//\r
-void MXAPI mxGetVirtualScreen( MXUINT far *width, MXUINT far *height );\r
-void MXAPI mxSetVirtualScreen( MXUINT width, MXUINT height );\r
-void MXAPI mxPan( MXUINT x, MXUINT y );\r
-//\r
-// Clipping\r
-//\r
-MXBOOL MXAPI mxGetClip( void );\r
-MXBOOL MXAPI mxGetClipRegion( MXSINT far *x, MXSINT far *y, MXSINT far *w, MXSINT far *h );\r
-MXBOOL MXAPI mxSetClip( MXBOOL );\r
-void MXAPI mxSetClipRegion( MXUINT x, MXUINT y, MXUINT width, MXUINT height );\r
-//\r
-// Graphics\r
-//\r
-void MXAPI mxBitBlt( MXSINT sx, MXSINT sy, MXUINT width, MXUINT height, MXSINT dx, MXSINT dy );\r
-void MXAPI mxFillBox( MXSINT x, MXSINT y, MXUINT width, MXUINT height, MXUINT color, MXUINT op );\r
-MXBYTE MXAPI mxGetPixel( MXSINT x, MXSINT y );\r
-void MXAPI mxPutPixel( MXSINT x, MXSINT y, MXBYTE color );\r
-void MXAPI mxLine( MXSINT x1, MXSINT y1, MXSINT x2, MXSINT y2, MXUINT color, MXUINT op );\r
-void MXAPI mxGetImage( MXPTR img, MXSINT x, MXSINT y, MXUINT width, MXUINT height );\r
-void MXAPI mxPutImage( MXPTR img, MXSINT x, MXSINT y, MXUINT w, MXUINT h, MXUINT op );\r
-void MXAPI mxPutTile( MXPTR tile, MXSINT x, MXSINT y, MXUINT width, MXUINT height );\r
-void MXAPI mxTransPutTile( MXPTR tile, MXSINT x, MXSINT y, MXUINT w, MXUINT h );\r
-void MXAPI mxCircle( MXSINT x, MXSINT y, MXUINT radius, MXBYTE color );\r
-void MXAPI mxStretchImage( MXPTR img, MXSINT x, MXSINT y, MXUINT w, MXUINT h, MXUINT neww, MXUINT newh, MXUINT op );\r
-//\r
-// Palette\r
-//\r
-void MXAPI mxColorToGray( MXPTR source, MXPTR dest, MXUINT count );\r
-void MXAPI mxGammaCorrect( MXPTR source, MXPTR dest, MXUINT count );\r
-void MXAPI mxGetColor( MXUINT index, MXSINT far *r, MXSINT far *g, MXSINT far *b );\r
-void MXAPI mxSetColor( MXUINT index, MXSINT red, MXSINT green, MXSINT blue );\r
-void MXAPI mxGetPalette( MXPTR palette, MXUINT index, MXUINT count );\r
-void MXAPI mxSetPalette( MXPTR palette, MXUINT index, MXUINT count );\r
-void MXAPI mxFadePalette( MXPTR, MXUINT, MXUINT, MXUINT, MXUINT, MXUINT, MXUINT );\r
-void MXAPI mxRotatePalette( MXPTR palette, MXUINT count, MXSINT step );\r
-//\r
-// Text\r
-//\r
-MXSINT MXAPI mxSetFont( MXPTR font, MXUINT charwidth, MXUINT charheight );\r
-void MXAPI mxSetTextColor( MXUINT color, MXUINT op );\r
-void MXAPI mxGetTextStep( MXSINT far *deltax, MXSINT far *deltay );\r
-void MXAPI mxSetTextStep( MXSINT deltax, MXSINT deltay );\r
-void MXAPI mxOutChar( MXSINT x, MXSINT y, char c );\r
-void MXAPI mxOutText( MXSINT x, MXSINT y, char far *sz );\r
-//\r
-// Convex polygons\r
-//\r
-void MXAPI mxFillPoly( MXUINT, MXPTR, MXPTR, MXUINT, MXUINT );\r
-void MXAPI mxGouraudPoly( MXUINT, MXPTR, MXPTR, MXPTR, MXUINT, MXUINT );\r
-void MXAPI mxTexturePoly( MXUINT, MXPTR, MXPTR, MXPTR, MXPTR, MXUINT, MXUINT );\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-//\r
-// Remove temporary defines\r
-//\r
-#undef MXBYTE\r
-#undef MXBOOL\r
-#undef MXSINT\r
-#undef MXUINT\r
-#undef MXPTR\r
-#undef MXAPI\r
-\r
-#endif // _MODEX_H_\r
+++ /dev/null
-+-MXBB.OBJ &\r
-+-MXCC.OBJ &\r
-+-MXCG.OBJ &\r
-+-MXCL.OBJ &\r
-+-MXCR.OBJ &\r
-+-MXFB.OBJ &\r
-+-MXFP.OBJ &\r
-+-MXGC.OBJ &\r
-+-MXGI.OBJ &\r
-+-MXGM.OBJ &\r
-+-MXGP.OBJ &\r
-+-MXGV.OBJ &\r
-+-MXHL.OBJ &\r
-+-MXIT.OBJ &\r
-+-MXLL.OBJ &\r
-+-MXLN.OBJ &\r
-+-MXOT.OBJ &\r
-+-MXPB.OBJ &\r
-+-MXPF.OBJ &\r
-+-MXPG.OBJ &\r
-+-MXPI.OBJ &\r
-+-MXPN.OBJ &\r
-+-MXPP.OBJ &\r
-+-MXPT.OBJ &\r
-+-MXRA.OBJ &\r
-+-MXRP.OBJ &\r
-+-MXSA.OBJ &\r
-+-MXSC.OBJ &\r
-+-MXSI.OBJ &\r
-+-MXSL.OBJ &\r
-+-MXSM.OBJ &\r
-+-MXSP.OBJ &\r
-+-MXSS.OBJ &\r
-+-MXTL.OBJ &\r
-+-MXVS.OBJ &\r
-+-MXWD.OBJ &\r
-+-MXWM.OBJ &\r
-+-MXWP.OBJ &\r
-+-MXWR.OBJ\r
+++ /dev/null
-(*\r
- Turbo Pascal interface to the MODEX library\r
- Copyright (c) 1993,1994 by Alessandro Scotti\r
-*)\r
-unit ModeX;\r
-interface\r
-\r
-const\r
- (* Video modes *)\r
- MX_TEXT = 0;\r
- MX_320x175 = 1;\r
- MX_320x200 = 2;\r
- MX_320x240 = 3;\r
- MX_320x350 = 4;\r
- MX_320x400 = 5;\r
- MX_320x480 = 6;\r
- MX_360x175 = 7;\r
- MX_360x200 = 8;\r
- MX_360x240 = 9;\r
- MX_360x350 = 10;\r
- MX_360x400 = 11;\r
- MX_360x480 = 12;\r
- MX_400x600 = 13;\r
-\r
- (* Fade effects *)\r
- MX_FADEIN = 0;\r
- MX_FADEOUT = 1;\r
-\r
- (* Raster ops *)\r
- OP_SET = 0;\r
- OP_AND = 1;\r
- OP_OR = 2;\r
- OP_XOR = 3;\r
- OP_TRANS = 4;\r
- OP_ADD = 5;\r
- OP_MOVE = 0; (* Alias for OP_SET *)\r
-\r
-procedure mxBitBlt( SX, SY: integer; Width, Height: word; DX, DY: integer );\r
-procedure mxCircle( CX, CY: integer; Radius: word; Color: byte );\r
-procedure mxChangeMode( Mode: word );\r
-procedure mxColorToGray( ColorPalette, GrayPalette: pointer; Count: word );\r
-procedure mxFadePalette( Palette: pointer; Cmd, Start, Count, R, G, B: word );\r
-procedure mxFillBox( X, Y: integer; Width, Height: word; Color: byte; Op: word );\r
-procedure mxGammaCorrect( ColorPalette, GammaPalette: pointer; Count: word );\r
-procedure mxGetAspect( var AspectX, AspectY: word );\r
-function mxGetClipRegion( var X1, Y1, Width, Height: word ): boolean;\r
-function mxGetClip: boolean;\r
-procedure mxGetImage( Image: pointer; X, Y: integer; Width, Height: word );\r
-procedure mxGetPalette( Palette: pointer; Start, Count: word );\r
-function mxGetPixel( X, Y: word ): byte;\r
-procedure mxGetScreenSize( var Width, Height: word );\r
-procedure mxGetTextStep( var DeltaX, DeltaY: integer );\r
-function mxGetVersion: word;\r
-procedure mxGetVirtualScreen( var Width, Height: word );\r
-procedure mxInit;\r
-procedure mxLine( X1, Y1, X2, Y2: integer; Color, Op: word );\r
-procedure mxOutChar( X, Y: integer; C: char );\r
-procedure mxOutText( X, Y: integer; S: pointer );\r
-procedure mxPan( X, Y: word );\r
-procedure mxPutImage( Image: pointer; X, Y: integer; Width, Height, Op: word );\r
-procedure mxPutPixel( X, Y: word; C: byte );\r
-procedure mxPutTile( Tile: pointer; X, Y: integer; Width, Height: word );\r
-procedure mxReadPlane( Plane: byte );\r
-procedure mxRotatePalette( Palette: pointer; Count: word; Step: integer );\r
-procedure mxRowAddress( RowAddress: byte );\r
-function mxSetClip( Clip: boolean ): boolean;\r
-procedure mxSetClipRegion( X1, Y1, Width, Height: word );\r
-procedure mxSetColor( Index, R, G, B: word );\r
-procedure mxSetFont( Font: pointer; Width, Height: word );\r
-procedure mxSetMode( Mode: word );\r
-procedure mxSetPalette( Palette: pointer; Start, Count: word );\r
-procedure mxSetTextColor( Color, Op: word );\r
-procedure mxSetTextStep( DeltaX, DeltaY: integer );\r
-procedure mxSetVirtualScreen( Width, Height: word );\r
-procedure mxStretchImage( Image: pointer; X, Y: integer; Width, Height, NewWidth, NewHeight, Op: word );\r
-procedure mxSplitScreen( Line: word );\r
-procedure mxStartAddress( StartAddress: word );\r
-procedure mxStartLine( Line: word );\r
-procedure mxTerm;\r
-procedure mxTransPutTile( Tile: pointer; X, Y: integer; Width, Height: word );\r
-procedure mxWaitDisplay;\r
-procedure mxWaitRetrace;\r
-procedure mxWriteMode( Mode: byte );\r
-procedure mxWritePlane( Plane: byte );\r
-\r
-procedure mxFillPoly( Count: word; var Map, Points; Color: word );\r
-procedure mxGouraudPoly( Count: word; var Map, Points, Colors; BaseColor: word );\r
-procedure mxTexturePoly( Count: word; var Map, Points, ImgPoints, Texture; Width: word );\r
-\r
-procedure mxOutStr( X, Y: integer; S: string );\r
-\r
-implementation\r
-\r
-procedure mxBitBlt; external;\r
-procedure mxChangeMode( Mode: word ); external;\r
-procedure mxCircle; external;\r
-procedure mxColorToGray; external;\r
-procedure mxFadePalette; external;\r
-procedure mxFillBox; external;\r
-procedure mxGammaCorrect; external;\r
-procedure mxGetAspect( var AspectX, AspectY: word ); external;\r
-function mxGetClipRegion; external;\r
-function mxGetClip: boolean; external;\r
-procedure mxGetImage; external;\r
-procedure mxGetPalette( Palette: pointer; Start, Count: word ); external;\r
-function mxGetPixel( X, Y: word ): byte; external;\r
-procedure mxGetScreenSize( var Width, Height: word ); external;\r
-procedure mxGetTextStep( var DeltaX, DeltaY: integer ); external;\r
-function mxGetVersion: word; external;\r
-procedure mxGetVirtualScreen( var Width, Height: word ); external;\r
-procedure mxInit; external;\r
-procedure mxLine( X1, Y1, X2, Y2: integer; Color, Op: word ); external;\r
-procedure mxOutChar( X, Y: integer; C: char ); external;\r
-procedure mxOutText( X, Y: integer; S: pointer ); external;\r
-procedure mxPan( X, Y: word ); external;\r
-procedure mxPutImage; external;\r
-procedure mxPutPixel( X, Y: word; C: byte ); external;\r
-procedure mxPutTile; external;\r
-procedure mxReadPlane( Plane: byte ); external;\r
-procedure mxRotatePalette; external;\r
-procedure mxRowAddress( RowAddress: byte ); external;\r
-function mxSetClip( Clip: boolean ): boolean; external;\r
-procedure mxSetClipRegion( X1, Y1, Width, Height: word ); external;\r
-procedure mxSetColor( Index, R, G, B: word ); external;\r
-procedure mxSetFont( Font: pointer; Width, Height: word ); external;\r
-procedure mxSetMode( Mode: word ); external;\r
-procedure mxSetPalette( Palette: pointer; Start, Count: word ); external;\r
-procedure mxSetTextColor( Color, Op: word ); external;\r
-procedure mxSetTextStep( DeltaX, DeltaY: integer ); external;\r
-procedure mxSetVirtualScreen( Width, Height: word ); external;\r
-procedure mxSplitScreen( Line: word ); external;\r
-procedure mxStartAddress( StartAddress: word ); external;\r
-procedure mxStartLine; external;\r
-procedure mxStretchImage; external;\r
-procedure mxTerm; external;\r
-procedure mxTransPutTile; external;\r
-procedure mxWaitDisplay; external;\r
-procedure mxWaitRetrace; external;\r
-procedure mxWriteMode( Mode: byte ); external;\r
-procedure mxWritePlane( Plane: byte ); external;\r
-\r
-procedure mxFillPoly; external;\r
-procedure mxGouraudPoly; external;\r
-procedure mxTexturePoly; external;\r
-{$L MXPB}\r
-{$L MXPF}\r
-{$L MXPG}\r
-{$L MXPT}\r
-\r
-{$L MXBB}\r
-{$L MXCC}\r
-{$L MXCG}\r
-{$L MXCL}\r
-{$L MXCR}\r
-{$L MXFB}\r
-{$L MXFP}\r
-{$L MXGI}\r
-{$L MXGM}\r
-{$L MXGP}\r
-{$L MXGV}\r
-{$L MXHL}\r
-{$L MXIT}\r
-{$L MXLN}\r
-{$L MXOT}\r
-{$L MXPI}\r
-{$L MXPN}\r
-{$L MXPP}\r
-{$L MXRA}\r
-{$L MXRP}\r
-{$L MXSA}\r
-{$L MXSC}\r
-{$L MXSI}\r
-{$L MXSL}\r
-{$L MXSM}\r
-{$L MXSP}\r
-{$L MXSS}\r
-{$L MXTL}\r
-{$L MXVS}\r
-{$L MXWD}\r
-{$L MXWM}\r
-{$L MXWP}\r
-{$L MXWR}\r
-\r
-(*\r
- Prints a Turbo Pascal string.\r
- Note: BP 7.0 supports ASCIIZ strings (PChar type).\r
-*)\r
-procedure mxOutStr;\r
-begin\r
- S := S + #0;\r
- mxOutText( X, Y, @S[1] );\r
-end;\r
-\r
-end.\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXBB.ASM - Bit block transfer\r
-; Copyright (c) 1993,1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-NOWARN RES\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxBitBlt\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-EXTRN subHorizontalLineInfo : NEAR\r
-\r
-EXTRN mx_VideoSegment : WORD\r
-EXTRN mx_BytesPerLine : WORD\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Moves a block of video memory.\r
-;\r
-; Input:\r
-; SX, SY = source coordinates\r
-; Width = source width\r
-; Height = source height\r
-; DX, DY = destination coordinates\r
-; Output:\r
-; none\r
-;\r
-; Note: overlapping regions are not allowed.\r
-;\r
-mxBitBlt PROC FAR\r
- ARG DestY:WORD, \\r
- DestX:WORD, \\r
- Height:WORD, \\r
- Width:WORD, \\r
- SY:WORD, \\r
- SX:WORD = ARG_SIZE\r
- LOCAL PlaneWidth:WORD:4, \\r
- SourceOffset:WORD, \\r
- DestOffset:WORD, \\r
- Count:BYTE, \\r
- ReadPlane:BYTE, \\r
- WritePlane:BYTE, \\r
- LeftMask:BYTE, \\r
- RightMask:BYTE = AUTO_SIZE\r
- .enter AUTO_SIZE\r
- .push ds, si, es, di\r
-\r
-; Exit now if null width\r
- cmp [Width], 0\r
- je @@Exit\r
-\r
-; Calls the proper procedure to handle transfer\r
- mov ax, [SX]\r
- and al, 03h ; AL = source plane\r
- mov dx, [DestX]\r
- and dl, 03h ; DL = destination plane\r
- mov bx, OFFSET subPlaneBlt\r
- cmp al, dl ; Same source and destination plane?\r
- jne @@BitBlt ; No, use slow procedure\r
- mov bx, OFFSET subMoveBlt\r
-@@BitBlt:\r
- call bx\r
-\r
-@@Exit:\r
- xor ax, ax\r
- .pop ds, si, es, di\r
- .leave ARG_SIZE\r
-\r
-;-----------------------------------------------------------\r
-; Uses write mode 1 for maximum speed. Only works if source\r
-; and destination are plane-aligned.\r
-;\r
-subMoveBlt PROC NEAR\r
-; Get horizontal line info and address of destination\r
- mov bx, [DestX]\r
- mov ax, [DestY]\r
- mov cx, [Width]\r
- call subHorizontalLineInfo\r
- mov [LeftMask], al\r
- mov [RightMask], ah\r
- mov [Width], cx\r
-\r
-; Setup segments\r
- mov ax, [mx_VideoSegment]\r
- mov ds, ax\r
- mov es, ax\r
-\r
-; Get address of source pixel\r
- mov ax, [SY]\r
- mul [mx_BytesPerLine]\r
- mov si, [SX]\r
- .shr si, 2\r
- add si, ax\r
-\r
-; Set write mode 1\r
- mov dx, GDC\r
- mov ax, 4105h\r
- out dx, ax\r
- cld\r
-\r
-; Move left block\r
-@@L0:\r
- mov ah, [LeftMask]\r
- or ah, ah\r
- jz @@C0\r
- mov dx, TS\r
- mov al, 02h\r
- out dx, ax ; Set write plane mask\r
- mov ax, [mx_BytesPerLine]\r
- dec ax\r
- mov cx, [Height]\r
- .push si, di\r
-@@L1:\r
- movsb\r
- add si, ax\r
- add di, ax\r
- dec cx\r
- jnz @@L1\r
- .pop si, di\r
- inc si\r
- inc di\r
-\r
-; Move center block\r
-@@C0:\r
- mov bx, [Width]\r
- test bx, bx\r
- jz @@R0\r
- mov dx, TS\r
- mov ax, 0F02h\r
- out dx, ax ; Enable all planes\r
- mov ax, [mx_BytesPerLine]\r
- sub ax, bx\r
- mov dx, [Height]\r
- .push si, di\r
-@@C1:\r
- mov cx, bx ; CX = image width\r
- rep movsb ; Cannot use "movsw" here!\r
- add si, ax ; Next scan line\r
- add di, ax ; Next scan line\r
- dec dx ; All lines processed?\r
- jnz @@C1 ; No, continue\r
- .pop si, di\r
- add si, bx\r
- add di, bx\r
-\r
-; Move right block\r
-@@R0:\r
- mov ah, [RightMask]\r
- or ah, ah\r
- jz @@Done\r
- mov dx, TS\r
- mov al, 02h\r
- out dx, ax ; Set write plane mask\r
- mov ax, [mx_BytesPerLine]\r
- dec ax\r
- mov cx, [Height]\r
-@@R1:\r
- movsb\r
- add si, ax\r
- add di, ax\r
- dec cx\r
- jnz @@R1\r
-\r
-@@Done:\r
- mov dx, GDC\r
- mov ax, 4005h\r
- out dx, ax ; Restore write mode 0\r
-\r
-@@Exit:\r
- ret\r
-subMoveBlt ENDP\r
-\r
-;-----------------------------------------------------------\r
-; Moves one plane at a time.\r
-;\r
-subPlaneBlt PROC NEAR\r
-; Compute extra bytes and width count for each plane\r
- mov cx, [Width]\r
- mov bx, cx\r
- shr bx, 1\r
- shr bx, 1 ; Width for each plane\r
- and cl, 03h\r
- mov al, 00001000b\r
- shr al, cl\r
- mov si, 3 SHL 1\r
-@@PatchLoop:\r
- mov PlaneWidth[si], bx\r
- shr al, 1\r
- adc bx, 0\r
- dec si\r
- dec si\r
- jge @@PatchLoop\r
-\r
-; Get pixel addresses\r
- mov ax, [mx_VideoSegment]\r
- mov ds, ax\r
- mov es, ax\r
- mov ax, [SY]\r
- mul [mx_BytesPerLine]\r
- mov si, [SX]\r
- shr si, 1\r
- shr si, 1\r
- add si, ax ; DS:SI points to source\r
- mov [SourceOffset], si\r
- mov ax, [DestY]\r
- mul [mx_BytesPerLine]\r
- mov di, [DestX]\r
- shr di, 1\r
- shr di, 1\r
- add di, ax ; ES:DI points to destination\r
- mov [DestOffset], di\r
-\r
-; Adjust plane for output to VGA registers\r
- mov ax, [SX]\r
- and al, 03h\r
- mov [ReadPlane], al\r
- mov cx, [DestX]\r
- and cl, 03h\r
- mov al, 00010001b\r
- shl al, cl\r
- mov [WritePlane], al\r
-\r
-; Ready to move now\r
- cld\r
- mov [Count], 4 ; Four planes\r
- lea bx, PlaneWidth ; SS:[BX] = width in bytes for plane\r
-@@PlaneLoop:\r
- cmp WORD PTR ss:[bx], 0\r
- je @@Done\r
- mov ah, [WritePlane]\r
- and ah, 0Fh\r
- mov al, 02h\r
- mov dx, TS\r
- out dx, ax ; Select write plane\r
- mov ah, [ReadPlane]\r
- mov al, 04h\r
- mov dx, GDC\r
- out dx, ax ; Select read plane\r
- mov dx, [Height]\r
- mov ax, [mx_BytesPerLine]\r
- sub ax, ss:[bx] ; AX = extra bytes per line\r
-@@Loop:\r
- mov cx, ss:[bx]\r
- shr cx, 1\r
- rep movsw\r
- rcl cx, 1\r
- rep movsb\r
- add si, ax\r
- add di, ax\r
- dec dx\r
- jnz @@Loop ; Repeat for all lines\r
- inc bx\r
- inc bx ; Select width for next plane\r
- inc [ReadPlane]\r
- and [ReadPlane], 03h ; Should be faster on 386 using\r
- jnz @@ReadPlaneOk ; BTR and ADC...\r
- inc [SourceOffset]\r
-@@ReadPlaneOk:\r
- rol [WritePlane], 1\r
- adc [DestOffset], 0\r
- mov si, [SourceOffset]\r
- mov di, [DestOffset]\r
- dec [Count]\r
- jnz @@PlaneLoop ; Repeat for all planes\r
-\r
-@@Done:\r
- ret\r
-subPlaneBlt ENDP\r
-\r
-mxBitBlt ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXCC.ASM - Fast clip line function\r
-; Copyright (c) 1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-NOWARN RES\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC xsubClipLine\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-EXTRN mx_BytesPerLine : WORD\r
-EXTRN mx_VideoSegment : WORD\r
-\r
-EXTRN mx_ClipX1 : WORD\r
-EXTRN mx_ClipY1 : WORD\r
-EXTRN mx_ClipX2 : WORD\r
-EXTRN mx_ClipY2 : WORD\r
-\r
-tblGroups LABEL WORD\r
- DW 10, tbl00\r
- DW 10, tbl10\r
- DW 9, tbl20\r
- DW -1, 0\r
- DW 10, tbl40\r
- DW 10, tbl50\r
- DW 9, tbl60\r
- DW -1, 0\r
- DW 6, tbl80\r
- DW 6, tbl90\r
- DW 5, tblA0\r
- DW -1, 0\r
- DW -1, 0\r
- DW -1, 0\r
- DW -1, 0\r
- DW -1, 0\r
-tbl00 DW cc00, cc01, cc02, ccFF, cc04, cc05, cc06, ccFF, cc08, cc09, cc0A\r
-tbl10 DW cc10, ccFF, cc12, ccFF, cc14, ccFF, cc16, ccFF, cc18, ccFF, cc1A\r
-tbl20 DW cc20, cc21, ccFF, ccFF, cc24, cc25, ccFF, ccFF, cc28, cc29\r
-tbl40 DW cc40, cc41, cc42, ccFF, ccFF, ccFF, ccFF, ccFF, cc48, cc49, cc4A\r
-tbl50 DW cc50, ccFF, cc52, ccFF, ccFF, ccFF, ccFF, ccFF, cc58, ccFF, cc5A\r
-tbl60 DW cc60, cc61, ccFF, ccFF, ccFF, ccFF, ccFF, ccFF, cc68, cc69\r
-tbl80 DW cc80, cc81, cc82, ccFF, cc84, cc85, cc86\r
-tbl90 DW cc90, ccFF, cc92, ccFF, cc94, ccFF, cc96\r
-tblA0 DW ccA0, ccA1, ccFF, ccFF, ccA4, ccA5\r
-\r
-ccTT: clc\r
- ret\r
-ccFF: stc\r
- ret\r
-\r
-; Group 00 -------------------------------------------------\r
-;\r
-cc00:\r
- clc\r
- ret\r
-cc01:\r
- jmp ClipQLeft\r
-cc02:\r
- jmp ClipQRight\r
-cc04:\r
- jmp ClipQTop\r
-cc05:\r
- call ClipQLeft\r
- cmp si, [mx_ClipY1]\r
- jge ccTT\r
- jmp ClipQTop\r
-cc06:\r
- call ClipQRight\r
- cmp si, [mx_ClipY1]\r
- jge ccTT\r
- jmp ClipQTop\r
-cc08:\r
- jmp ClipQBottom\r
-cc09:\r
- call ClipQLeft\r
- cmp si, [mx_ClipY2]\r
- jle ccTT\r
- jmp ClipQBottom\r
-cc0A:\r
- call ClipQRight\r
- cmp si, [mx_ClipY2]\r
- jle ccTT\r
- jmp ClipQBottom\r
-\r
-; Group 10 -------------------------------------------------\r
-;\r
-cc10FF:\r
- stc\r
- ret\r
-cc10TT:\r
- clc\r
- ret\r
-cc10:\r
- jmp ClipPLeft\r
-cc12:\r
- call ClipPLeft\r
- jmp ClipQRight\r
-cc14:\r
- call ClipPLeft\r
- cmp bx, [mx_ClipY1]\r
- jl cc10FF\r
- jmp ClipQTop\r
-cc16:\r
- call ClipPLeft\r
- cmp bx, [mx_ClipY1]\r
- jl cc10FF\r
- call ClipQTop\r
- cmp cx, [mx_ClipX2]\r
- jle cc10TT\r
- jmp ClipQRight\r
-cc18:\r
- call ClipPLeft\r
- cmp bx, [mx_ClipY2]\r
- jg cc10FF\r
- jmp ClipQBottom\r
-cc1A:\r
- call ClipPLeft\r
- cmp bx, [mx_ClipY2]\r
- jg cc10FF\r
- call ClipQBottom\r
- cmp cx, [mx_ClipX2]\r
- jle cc10TT\r
- jmp ClipQRight\r
-\r
-; Group 20 -------------------------------------------------\r
-;\r
-cc20TT:\r
- clc\r
- ret\r
-cc20FF:\r
- stc\r
- ret\r
-cc20:\r
- jmp ClipPRight\r
-cc21:\r
- call ClipPRight\r
- jmp ClipQLeft\r
-cc24:\r
- call ClipPRight\r
- cmp bx, [mx_ClipY1]\r
- jl cc20FF\r
- jmp ClipQTop\r
-cc25:\r
- call ClipPRight\r
- cmp bx, [mx_ClipY1]\r
- jl cc20FF\r
- call ClipQTop\r
- cmp cx, [mx_ClipX1]\r
- jge cc20TT\r
- jmp ClipQLeft\r
-cc28:\r
- call ClipPRight\r
- cmp bx, [mx_ClipY2]\r
- jg cc20FF\r
- jmp ClipQBottom\r
-cc29:\r
- call ClipPRight\r
- cmp bx, [mx_ClipY2]\r
- jg cc20FF\r
- call ClipQBottom\r
- cmp cx, [mx_ClipX1]\r
- jge cc20TT\r
- jmp ClipQLeft\r
-\r
-; Group 40 -------------------------------------------------\r
-;\r
-cc40TT:\r
- clc\r
- ret\r
-cc40FF:\r
- stc\r
- ret\r
-cc40:\r
- jmp ClipPTop\r
-cc41:\r
- call ClipPTop\r
- cmp di, [mx_ClipX1]\r
- jl cc40FF\r
- call ClipQLeft\r
- cmp si, [mx_ClipY1]\r
- jge cc40TT\r
- jmp ClipQTop\r
-cc42:\r
- call ClipPTop\r
- cmp di, [mx_ClipX2]\r
- jg cc40FF\r
- jmp ClipQRight\r
-cc48:\r
- call ClipPTop\r
- jmp ClipQBottom\r
-cc49:\r
- call ClipPTop\r
- cmp di, [mx_ClipX1]\r
- jl cc40FF\r
- call ClipQLeft\r
- cmp si, [mx_ClipY2]\r
- jle cc40TT\r
- jmp ClipQBottom\r
-cc4A:\r
- call ClipPTop\r
- cmp di, [mx_ClipX2]\r
- jg cc40FF\r
- call ClipQRight\r
- cmp si, [mx_ClipY2]\r
- jle cc40TT\r
- jmp ClipQBottom\r
-\r
-\r
-; Group 50 -------------------------------------------------\r
-;\r
-cc50TT:\r
- clc\r
- ret\r
-cc50FF:\r
- stc\r
- ret\r
-cc50:\r
- call ClipPLeft\r
- cmp bx, [mx_ClipY1]\r
- jge cc50TT\r
- jmp ClipPTop\r
-cc52:\r
- call ClipQRight\r
- cmp si, [mx_ClipY1]\r
- jl cc50FF\r
- call ClipPTop\r
- cmp di, [mx_ClipX1]\r
- jge cc50TT\r
- jmp ClipPLeft\r
-cc58:\r
- call ClipQBottom\r
- cmp cx, [mx_ClipX1]\r
- jl cc50FF\r
- call ClipPTop\r
- cmp di, [mx_ClipX1]\r
- jge cc50TT\r
- jmp ClipPLeft\r
-cc5A:\r
- call ClipPLeft\r
- cmp bx, [mx_ClipY2]\r
- jg cc50FF\r
- call ClipQRight\r
- cmp bx, [mx_ClipY1]\r
- jl cc50FF\r
- cmp si, [mx_ClipY2]\r
- jle cc50TT\r
- jmp ClipQBottom\r
-\r
-; Group 60 -------------------------------------------------\r
-;\r
-cc60TT:\r
- clc\r
- ret\r
-cc60FF:\r
- stc\r
- ret\r
-cc60:\r
- call ClipPRight\r
- cmp bx, [mx_ClipY1]\r
- jge cc60TT\r
- jmp ClipPTop\r
-cc61:\r
- call ClipQLeft\r
- cmp si, [mx_ClipY2]\r
- jl cc60FF\r
- call ClipPTop\r
- cmp di, [mx_ClipX2]\r
- jle cc60TT\r
- jmp ClipPRight\r
-cc68:\r
- call ClipQBottom\r
- cmp cx, [mx_ClipX2]\r
- jg cc60FF\r
- call ClipPRight\r
- cmp bx, [mx_ClipY1]\r
- jge cc60TT\r
- jmp ClipPTop\r
-cc69:\r
- call ClipQLeft\r
- cmp si, [mx_ClipY1]\r
- jl cc60FF\r
- call ClipPRight\r
- cmp bx, [mx_ClipY2]\r
- jg cc60FF\r
- cmp si, [mx_ClipY2]\r
- jle cc69_1\r
- call ClipQBottom\r
-cc69_1:\r
- cmp bx, [mx_ClipY1]\r
- jge cc60TT\r
- jmp ClipPTop\r
-\r
-; Group 80 -------------------------------------------------\r
-;\r
-cc80TT:\r
- clc\r
- ret\r
-cc80FF:\r
- stc\r
- ret\r
-cc80:\r
- jmp ClipPBottom\r
-cc81:\r
- call ClipPBottom\r
- cmp di, [mx_ClipX1]\r
- jl cc80FF\r
- jmp ClipQLeft\r
-cc82:\r
- call ClipPBottom\r
- cmp di, [mx_ClipX2]\r
- jg cc80FF\r
- jmp ClipQRight\r
-cc84:\r
- call ClipPBottom\r
- jmp ClipQTop\r
-cc85:\r
- call ClipPBottom\r
- cmp di, [mx_ClipX1]\r
- jl cc80FF\r
- call ClipQLeft\r
- cmp si, [mx_ClipY1]\r
- jge cc80FF\r
- jmp ClipQTop\r
-cc86:\r
- call ClipPBottom\r
- cmp di, [mx_ClipX2]\r
- jg cc80FF\r
- call ClipQRight\r
- cmp si, [mx_ClipY1]\r
- jge cc80TT\r
- jmp ClipQTop\r
-\r
-; Group 90 -------------------------------------------------\r
-;\r
-cc90TT:\r
- clc\r
- ret\r
-cc90FF:\r
- stc\r
- ret\r
-cc90:\r
- call ClipPLeft\r
- cmp bx, [mx_ClipY2]\r
- jle cc90TT\r
- jmp ClipPBottom\r
-cc92:\r
- call ClipQRight\r
- cmp si, [mx_ClipY2]\r
- jg cc90FF\r
- call ClipPBottom\r
- cmp di, [mx_ClipX1]\r
- jge cc90TT\r
- jmp ClipPLeft\r
-cc94:\r
- call ClipQTop\r
- cmp cx, [mx_ClipX1]\r
- jl cc90FF\r
- call ClipPLeft\r
- cmp bx, [mx_ClipY2]\r
- jle cc90TT\r
- jmp ClipPBottom\r
-cc96:\r
- call ClipPLeft\r
- cmp bx, [mx_ClipY1]\r
- jl cc90FF\r
- call ClipQRight\r
- cmp si, [mx_ClipY2]\r
- jg cc90FF\r
- cmp bx, [mx_ClipY2]\r
- jle cc96_1\r
- call ClipPBottom\r
-cc96_1:\r
- cmp si, [mx_ClipY1]\r
- jge cc90TT\r
- jmp ClipQTop\r
-\r
-; Group A0 -------------------------------------------------\r
-;\r
-ccA0TT:\r
- clc\r
- ret\r
-ccA0FF:\r
- stc\r
- ret\r
-ccA0:\r
- call ClipPRight\r
- cmp bx, [mx_ClipY2]\r
- jle ccA0TT\r
- jmp ClipPBottom\r
-ccA1:\r
- call ClipQLeft\r
- cmp si, [mx_ClipY2]\r
- jg ccA0FF\r
- call ClipPBottom\r
- cmp di, [mx_ClipX2]\r
- jle ccA0TT\r
- jmp ClipPRight\r
-ccA4:\r
- call ClipQTop\r
- cmp cx, [mx_ClipX2]\r
- jg ccA0FF\r
- call ClipPRight\r
- cmp bx, [mx_ClipY2]\r
- jle ccA0TT\r
- jmp ClipPBottom\r
-ccA5:\r
- call ClipQLeft\r
- cmp si, [mx_ClipY2]\r
- jg ccA0FF\r
- call ClipPRight\r
- cmp bx, [mx_ClipY1]\r
- jl ccA0FF\r
- cmp si, [mx_ClipY1]\r
- jge ccA5_1\r
- call ClipQTop\r
-ccA5_1:\r
- cmp bx, [mx_ClipY2]\r
- jle ccA0TT\r
- jmp ClipPBottom\r
-\r
-; Y1 = (Y2-Y1)*(mx_ClipX1-X1)/(X2-X1)+Y1 = (SI-BX)*(mx_ClipX1-DI)/(CX-DI)+BX\r
-; X1 = mx_ClipX1\r
-ClipPLeft:\r
- mov ax, si\r
- sub ax, bx\r
- mov dx, [mx_ClipX1]\r
- sub dx, di\r
- imul dx\r
- mov bp, cx\r
- sub bp, di\r
- idiv bp\r
- add bx, ax\r
- mov di, [mx_ClipX1]\r
- clc\r
- ret\r
-\r
-; Y1 = (Y2-Y1)*(mx_ClipX2-X1)/(X2-X1)+Y1 = (SI-BX)*(mx_ClipX2-DI)/(CX-DI)+BX\r
-; X1 = mx_ClipX2\r
-ClipPRight:\r
- mov ax, si\r
- sub ax, bx\r
- mov dx, [mx_ClipX2]\r
- sub dx, di\r
- imul dx\r
- mov bp, cx\r
- sub bp, di\r
- idiv bp\r
- add bx, ax\r
- mov di, [mx_ClipX2]\r
- clc\r
- ret\r
-\r
-; X1 = (X2-X1)*(mx_ClipY2-Y1)/(Y2-Y1)+X1 = (CX-DI)*(mx_ClipY2-BX)/(SI-BX)+DI\r
-; Y1 = mx_ClipY2\r
-ClipPBottom:\r
- mov ax, cx\r
- sub ax, di\r
- mov dx, [mx_ClipY2]\r
- sub dx, bx\r
- imul dx\r
- mov bp, si\r
- sub bp, bx\r
- idiv bp\r
- add di, ax\r
- mov bx, [mx_ClipY2]\r
- clc\r
- ret\r
-\r
-; X1 = (X2-X1)*(mx_ClipY1-Y1)/(Y2-Y1)+X1 = (CX-DI)*(mx_ClipY1-BX)/(SI-BX)+DI\r
-; Y1 = mx_ClipY1\r
-ClipPTop:\r
- mov ax, cx\r
- sub ax, di\r
- mov dx, [mx_ClipY1]\r
- sub dx, bx\r
- imul dx\r
- mov bp, si\r
- sub bp, bx\r
- idiv bp\r
- add di, ax\r
- mov bx, [mx_ClipY1]\r
- clc\r
- ret\r
-\r
-; Y2 = (Y1-Y2)*(mx_ClipX1-X2)/(X1-X2)+Y2 = (BX-SI)*(mx_ClipX1-CX)/(DI-CX)+SI\r
-; X2 = mx_ClipX1\r
-ClipQLeft:\r
- mov ax, bx\r
- sub ax, si\r
- mov dx, [mx_ClipX1]\r
- sub dx, cx\r
- imul dx\r
- mov bp, di\r
- sub bp, cx\r
- idiv bp\r
- add si, ax\r
- mov cx, [mx_ClipX1]\r
- clc\r
- ret\r
-\r
-; Y2 = (Y1-Y2)*(mx_ClipX2-X2)/(X1-X2)+Y2 = (BX-SI)*(mx_ClipX2-CX)/(DI-CX)+SI\r
-; X2 = mx_ClipX1\r
-ClipQRight:\r
- mov ax, bx\r
- sub ax, si\r
- mov dx, [mx_ClipX2]\r
- sub dx, cx\r
- imul dx\r
- mov bp, di\r
- sub bp, cx\r
- idiv bp\r
- add si, ax\r
- mov cx, [mx_ClipX2]\r
- clc\r
- ret\r
-\r
-; X2 = (X1-X2)*(mx_ClipY2-Y2)/(Y1-Y2)+X2 = (DI-CX)*(mx_ClipY2-SI)/(BX-SI)+CX\r
-; Y2 = mx_ClipY1\r
-ClipQBottom:\r
- mov ax, di\r
- sub ax, cx\r
- mov dx, [mx_ClipY2]\r
- sub dx, si\r
- imul dx\r
- mov bp, bx\r
- sub bp, si\r
- idiv bp\r
- add cx, ax\r
- mov si, [mx_ClipY2]\r
- clc\r
- ret\r
-\r
-; X2 = (X1-X2)*(mx_ClipY1-Y2)/(Y1-Y2)+X2 = (DI-CX)*(mx_ClipY1-SI)/(BX-SI)+CX\r
-; Y2 = mx_ClipY1\r
-ClipQTop:\r
- mov ax, di\r
- sub ax, cx\r
- mov dx, [mx_ClipY1]\r
- sub dx, si\r
- imul dx\r
- mov bp, bx\r
- sub bp, si\r
- idiv bp\r
- add cx, ax\r
- mov si, [mx_ClipY1]\r
- clc\r
- ret\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Checks the coordinates of a line against the active\r
-; clip region.\r
-; Uses the Sobkow-Pospisil-Yang (SPY) algorithm: this was\r
-; supposed to be twice as fast as Cohen-Sutherland, but my\r
-; tests show only a very small increase in speed and a noticeable\r
-; increase of the program size! Maybe this is caused by the\r
-; slow speed of VGA cards, so probably a better test should\r
-; be performed with lines drawn in RAM.\r
-;\r
-; Input:\r
-; AX, BX = X1, Y1\r
-; CX, DX = X2, Y2\r
-; Output:\r
-; CF = set if line is full clipped\r
-; AX, BX = clipped X1, Y1\r
-; CX, DX = clipped X2, Y2\r
-; Note:\r
-; destroys SI, DI\r
-;\r
-xsubClipLine PROC NEAR\r
- push bp\r
- xor si, si ; SPY code\r
-\r
- cmp dx, [mx_ClipY2]\r
- jle @@1\r
- or si, 08h\r
- jmp @@2\r
-@@1:\r
- cmp dx, [mx_ClipY1]\r
- jge @@2\r
- or si, 04h\r
-@@2:\r
-\r
- cmp cx, [mx_ClipX2]\r
- jle @@3\r
- or si, 02h\r
- jmp @@4\r
-@@3:\r
- cmp cx, [mx_ClipX1]\r
- jge @@4\r
- or si, 01h\r
-@@4:\r
-\r
- cmp bx, [mx_ClipY2]\r
- jle @@5\r
- or si, 80h\r
- jmp @@6\r
-@@5:\r
- cmp bx, [mx_ClipY1]\r
- jge @@6\r
- or si, 40h\r
-@@6:\r
-\r
- cmp ax, [mx_ClipX2]\r
- jle @@7\r
- or si, 20h\r
- jmp @@8\r
-@@7:\r
- cmp ax, [mx_ClipX1]\r
- jge @@8\r
- or si, 10h\r
-@@8:\r
-\r
- mov di, si\r
- and di, 000Fh ; Index of procedure\r
- and si, 00F0h\r
- .shr si, 2 ; Index of group (times 4)\r
- cmp di, cs:tblGroups[si] ; Is index within range?\r
- jg @@Exit ; No, line is full clipped\r
- mov si, cs:tblGroups[si+2] ; Get offset of group table\r
- shl di, 1 ; We must index word elements\r
- add si, di ; Make full offset\r
- mov di, ax ; Move X1 to DI and free AX\r
- mov si, cs:[si] ; Get subroutine address\r
- xchg dx, si ; Move Y2 to SI and free DX\r
- call dx ; Call the proper subroutine\r
- mov ax, di ; Restore AX to X1\r
- mov dx, si ; Restore DX to Y2\r
- pop bp\r
- ret\r
-\r
-@@Exit:\r
- pop bp\r
- stc\r
- ret\r
-xsubClipLine ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXCG.ASM - Color to gray conversion\r
-; Copyright (c) 1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxColorToGray\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Converts RGB colors to gray shades.\r
-;\r
-; Input:\r
-; CPal = pointer to color palette\r
-; GPal = pointer to destination (gray) palette\r
-; Count = number of colors to convert\r
-; Output:\r
-; none\r
-;\r
-; Note: CPal and GPal may point to the same buffer.\r
-;\r
-mxColorToGray PROC FAR\r
- ARG Count:WORD, \\r
- DPal:DWORD, \\r
- SPal:DWORD = ARG_SIZE\r
- ASSUME ds:NOTHING\r
- .enter 0\r
- .push ds, si, es, di\r
-\r
- mov cx, [Count]\r
- jcxz @@Exit\r
- lds si, [SPal]\r
- les di, [DPal]\r
- cld\r
-; We use the standard formula\r
-; gray=(red*30 + green*59 + blue*11)/100\r
-; in the equivalent form\r
-; gray=(red*77 + green*151 + blue*28)/256\r
-; which doesn't need the last divide.\r
- mov bx, 77 SHL 8 + 151\r
-@@Loop:\r
- lodsb ; Red\r
- mul bh\r
- mov dx, ax\r
- lodsb ; Green\r
- mul bl\r
- add dx, ax\r
- lodsb ; Blue\r
- mov ah, 28\r
- mul ah\r
- add ax, dx\r
- mov al, ah\r
- stosw ; Save new RGB\r
- stosb\r
- loop @@Loop\r
-\r
-@@Exit:\r
- .pop ds, si, es, di\r
- .leave ARG_SIZE\r
-mxColorToGray ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXCL.ASM - Bresenham circle\r
-; Copyright (c) 1993,1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-NOWARN RES\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxCircle\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-EXTRN mx_BytesPerLine : WORD\r
-EXTRN mx_VideoSegment : WORD\r
-EXTRN mx_ClipX1 : WORD\r
-EXTRN mx_ClipY1 : WORD\r
-EXTRN mx_ClipX2 : WORD\r
-EXTRN mx_ClipY2 : WORD\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Draws a circle using the Bresenham algorithm.\r
-;\r
-; Input:\r
-; XC, YC = center coordinates\r
-; Radius = circle radius\r
-; Color = circle color\r
-; Output:\r
-; none\r
-; Note:\r
-; computes only points in the first octant, all other\r
-; points are obtained by symmetry.\r
-;\r
-mxCircle PROC FAR\r
- ARG Color:BYTE:2, \\r
- Radius:WORD, \\r
- YC:WORD, \\r
- XC:WORD = ARG_SIZE\r
- LOCAL Delta:WORD = AUTO_SIZE\r
- .enter AUTO_SIZE\r
- .push ds, si, di\r
-\r
- xor si, si ; X\r
- mov di, [Radius] ; Y\r
- mov ax, 3\r
- sub ax, di\r
- sub ax, di\r
- mov [Delta], ax ; Delta = 3-R*2\r
-\r
- mov ds, [mx_VideoSegment]\r
-\r
-@@Loop:\r
- cmp si, di ;\r
- jg @@Done ; Exit when X > Y\r
-; Draw points\r
- mov ax, si\r
- mov bx, di\r
- call @@subPutPixel\r
- mov ax, si\r
- neg ax\r
- mov bx, di\r
- call @@subPutPixel\r
- mov ax, si\r
- mov bx, di\r
- neg bx\r
- call @@subPutPixel\r
- mov ax, si\r
- neg ax\r
- mov bx, di\r
- neg bx\r
- call @@subPutPixel\r
- mov ax, di\r
- mov bx, si\r
- call @@subPutPixel\r
- mov ax, di\r
- neg ax\r
- mov bx, si\r
- call @@subPutPixel\r
- mov ax, di\r
- mov bx, si\r
- neg bx\r
- call @@subPutPixel\r
- mov ax, di\r
- neg ax\r
- mov bx, si\r
- neg bx\r
- call @@subPutPixel\r
-; Moves coordinates to next point\r
- mov ax, [Delta]\r
- test ax, ax\r
- jl @@Next\r
- mov ax, di\r
- .shl ax, 2\r
- sub ax, 4\r
- sub [Delta], ax\r
- dec di\r
-@@Next:\r
- mov ax, si\r
- .shl ax, 2\r
- add ax, 6\r
- add [Delta], ax\r
- inc si\r
- jmp @@Loop\r
-\r
-@@Done:\r
- xor ax, ax\r
- .pop ds, si, di\r
- .leave ARG_SIZE\r
-\r
-;---------------------------------------\r
-; Put pixel function.\r
-; Input:\r
-; BX = X coordinate (relative to center)\r
-; AX = Y coordinate (relative to center)\r
-; DS = video segment\r
-@@subPutPixel:\r
- add bx, [XC] ; Get absolute coordinates\r
- add ax, [YC]\r
-\r
- cmp bx, [mx_ClipX1] ; Clip pixel\r
- jl @@subExit\r
- cmp bx, [mx_ClipX2]\r
- jg @@subExit\r
- cmp ax, [mx_ClipY1]\r
- jl @@subExit\r
- cmp ax, [mx_ClipY2]\r
- jg @@subExit\r
-\r
- mul [mx_BytesPerLine] ; Get pixel offset\r
- mov cx, bx ; Save X coordinate\r
- .shr bx, 2\r
- add bx, ax ; DS:BX = pixel offset\r
-\r
- and cl, 3 ; Set write plane\r
- mov ax, 0102h\r
- shl ah, cl\r
- mov dx, TS\r
- out dx, ax\r
-\r
- mov al, [Color] ; Write pixel\r
- mov ds:[bx], al\r
-\r
-@@subExit:\r
- retn\r
-mxCircle ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXCR.ASM - Clip functions\r
-; Copyright (c) 1993,1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-NOWARN RES\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxSetSysClipRegion\r
-PUBLIC mxGetClipRegion\r
-PUBLIC mxSetClipRegion\r
-PUBLIC mxSetClip\r
-PUBLIC mxGetClip\r
-\r
-PUBLIC subClipBox\r
-PUBLIC subClipImage\r
-\r
-PUBLIC mx_ClipX1\r
-PUBLIC mx_ClipY1\r
-PUBLIC mx_ClipX2\r
-PUBLIC mx_ClipY2\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-EXTRN mx_CodeSegment : WORD\r
-\r
-mx_ClipX1 DW ? ; Clip coordinates\r
-mx_ClipY1 DW ?\r
-mx_ClipX2 DW ?\r
-mx_ClipY2 DW ?\r
-\r
-mx_SysClipX1 DW ? ; System clip coordinates\r
-mx_SysClipY1 DW ? ; (active when mx_ClipStatus is FALSE)\r
-mx_SysClipX2 DW ?\r
-mx_SysClipY2 DW ?\r
-\r
-mx_UserClipX1 DW ? ; User clip coordinates\r
-mx_UserClipY1 DW ? ; (active when mx_ClipStatus is TRUE)\r
-mx_UserClipX2 DW ?\r
-mx_UserClipY2 DW ?\r
-\r
-mx_ClipStatus DB ?\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Toggles clipping between user and system regions.\r
-;\r
-; Input:\r
-; ClipStatus = TRUE (FALSE) to enable (disable) clipping\r
-; Output:\r
-; AX = old clip status\r
-;\r
-mxSetClip PROC FAR\r
- ARG ClipStatus:BYTE:2 = ARG_SIZE\r
- ASSUME ds:NOTHING\r
- .enter 0\r
- .push ds\r
- mov ds, [mx_CodeSegment]\r
- ASSUME ds:MX_TEXT\r
-\r
- mov ax, [mx_UserClipX1]\r
- mov bx, [mx_UserClipY1]\r
- mov cx, [mx_UserClipX2]\r
- mov dx, [mx_UserClipY2]\r
- cmp [ClipStatus], TRUE\r
- je @@Done\r
- mov ax, [mx_SysClipX1]\r
- mov bx, [mx_SysClipY1]\r
- mov cx, [mx_SysClipX2]\r
- mov dx, [mx_SysClipY2]\r
-@@Done:\r
- mov [mx_ClipX1], ax\r
- mov [mx_ClipY1], bx\r
- mov [mx_ClipX2], cx\r
- mov [mx_ClipY2], dx\r
-\r
- mov al, [ClipStatus]\r
- xchg al, [mx_ClipStatus]\r
- xor ah, ah\r
-\r
- .pop ds\r
- .leave ARG_SIZE\r
-mxSetClip ENDP\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Returns the current clipping status.\r
-;\r
-; Input:\r
-; none\r
-; Output:\r
-; TRUE (FALSE) if clipping enabled (disabled)\r
-;\r
-mxGetClip PROC FAR\r
- ASSUME ds:NOTHING\r
- mov al, [mx_ClipStatus]\r
- xor ah, ah\r
- ret\r
-mxGetClip ENDP\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Sets the system clip region and disables user clipping.\r
-;\r
-; Input:\r
-; Width = width in pixels of clip region\r
-; Height = height in pixels of clip region\r
-; Output:\r
-; old clip status.\r
-;\r
-mxSetSysClipRegion PROC FAR\r
- ARG Height:WORD, \\r
- Width:WORD = ARG_SIZE\r
- ASSUME ds:NOTHING\r
- .enter 0\r
- .push ds\r
- mov ds, [mx_CodeSegment]\r
- ASSUME ds:MX_TEXT\r
-\r
- xor ax, ax ; Sys clip region always starts at (0,0)\r
- mov [mx_SysClipX1], ax\r
- mov [mx_SysClipY1], ax\r
- mov ax, [Width]\r
- dec ax\r
- mov [mx_SysClipX2], ax\r
- mov ax, [Height]\r
- dec ax\r
- mov [mx_SysClipY2], ax\r
-\r
- IF USE286 EQ TRUE\r
- push FALSE\r
- ELSE\r
- mov ax, FALSE\r
- push ax\r
- ENDIF\r
- call mxSetClip\r
-\r
- .pop ds\r
- .leave ARG_SIZE\r
-mxSetSysClipRegion ENDP\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Sets the clip region.\r
-;\r
-; Input:\r
-; X, Y = coordinates of top left corner of clip region\r
-; Width = width in pixels of clip region\r
-; Height = height in pixels of clip region\r
-; Output:\r
-; none (no checking on parameters)\r
-;\r
-mxSetClipRegion PROC FAR\r
- ARG Height:WORD, \\r
- Width:WORD, \\r
- Y:WORD, \\r
- X:WORD = ARG_SIZE\r
- ASSUME ds:NOTHING\r
- .enter 0\r
- .push ds\r
- mov ds, [mx_CodeSegment]\r
- ASSUME ds:MX_TEXT\r
-\r
- mov ax, [X]\r
- mov [mx_UserClipX1], ax\r
- mov ax, [Y]\r
- mov [mx_UserClipY1], ax\r
- mov ax, [Width]\r
- add ax, [X]\r
- dec ax\r
- mov [mx_UserClipX2], ax\r
- mov ax, [Height]\r
- add ax, [Y]\r
- dec ax\r
- mov [mx_UserClipY2], ax\r
-\r
- mov al, [mx_ClipStatus]\r
- cmp al, TRUE\r
- jne @@Exit\r
- push ax\r
- call mxSetClip\r
-\r
-@@Exit:\r
- xor ax, ax\r
- .pop ds\r
- .leave ARG_SIZE\r
-mxSetClipRegion ENDP\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Returns the current user clip region.\r
-;\r
-; Input:\r
-; X, Y = pointers to integer coordinates of top left corner\r
-; Width = pointer to word width of clip region\r
-; Height = pointer to word height of clip region\r
-; Output:\r
-; AX = current clip status\r
-;\r
-mxGetClipRegion PROC FAR\r
- ARG Height:DWORD, \\r
- Width:DWORD, \\r
- Y:DWORD, \\r
- X:DWORD = ARG_SIZE\r
- ASSUME ds:NOTHING\r
- .enter 0\r
- .push es, di\r
-\r
- mov ax, [mx_UserClipX1]\r
- les di, [X]\r
- mov es:[di], ax\r
- mov ax, [mx_UserClipY1]\r
- les di, [Y]\r
- mov es:[di], ax\r
-\r
- mov ax, [mx_UserClipX2]\r
- sub ax, [mx_UserClipX1]\r
- inc ax\r
- les di, [Width]\r
- mov es:[di], ax\r
- mov ax, [mx_UserClipY2]\r
- sub ax, [mx_UserClipY1]\r
- inc ax\r
- les di, [Height]\r
- mov es:[di], ax\r
-\r
- mov al, [mx_ClipStatus]\r
- xor ah, ah\r
- .pop es, di\r
- .leave ARG_SIZE\r
-mxGetClipRegion ENDP\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Internal use: checks the coordinates of a rectangle against\r
-; the active clip region.\r
-; This function assumes that a "raw" image has to be clipped,\r
-; so it returns in SI the number of "raw" bytes to skip if\r
-; X, Y were clipped.\r
-;\r
-; Input:\r
-; BX, AX = X, Y coordinates of rectangle (signed)\r
-; CX = box width\r
-; DX = box height\r
-; Output:\r
-; CF = set if rectangle is full clipped\r
-; BX, AX = new X, Y coordinates of rectangle\r
-; CX, DX = clipped width and height\r
-; SI = number of bytes to skip before copying a buffer\r
-; DI destroyed\r
-;\r
-subClipImage PROC NEAR\r
- ASSUME ds:NOTHING\r
- xor si, si\r
-\r
-; Check clip height\r
- mov di, [mx_ClipY1]\r
- cmp ax, di\r
- jge @@CheckBottom\r
- sub di, ax ; Number of lines to clip\r
- sub dx, di ; New box height\r
- jle @@Exit\r
- mov ax, di\r
- mov di, dx ; Save box height into DI\r
- mul cx ; DX:AX = number of bytes to skip\r
- mov si, ax\r
- mov dx, di ; Restore box height\r
- mov ax, [mx_ClipY1]\r
-@@CheckBottom:\r
- mov di, [mx_ClipY2]\r
- cmp ax, di\r
- jg @@Exit\r
- inc di\r
- sub di, dx\r
- sub di, ax\r
- jge @@DoneHeight ; None, continue\r
- add dx, di ; Clip lines\r
-@@DoneHeight:\r
-\r
-; Check clip width\r
-@@CheckLeft:\r
- mov di, [mx_ClipX1]\r
- cmp bx, di\r
- jge @@CheckRight\r
- sub di, bx ; Number of columns to clip left\r
- sub cx, di\r
- jle @@Exit\r
- add si, di ; Update skip count\r
- mov bx, [mx_ClipX1]\r
-@@CheckRight:\r
- mov di, [mx_ClipX2]\r
- cmp bx, di\r
- jg @@Exit\r
- inc di\r
- sub di, bx\r
- sub di, cx\r
- jge @@DoneWidth ; None, exit\r
- add cx, di ; New box width\r
-@@DoneWidth:\r
-\r
-; Set return flag and exit\r
-@@Done:\r
- clc\r
- ret\r
-@@Exit:\r
- stc\r
- ret\r
-subClipImage ENDP\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Internal use: checks the coordinates of a rectangle against\r
-; the active clip region.\r
-;\r
-; Input:\r
-; BX, AX = X, Y coordinates of rectangle (signed)\r
-; CX = box width\r
-; DX = box height\r
-; Output:\r
-; CF = set if rectangle is full clipped\r
-; BX, AX = new X, Y coordinates of rectangle\r
-; CX, DX = clipped width and height\r
-; DI destroyed\r
-;\r
-subClipBox PROC NEAR\r
- ASSUME ds:NOTHING\r
-\r
-; Check clip height\r
- mov di, [mx_ClipY1]\r
- cmp ax, di\r
- jge @@CheckBottom\r
- sub di, ax ; Number of lines to clip\r
- sub dx, di ; New box height\r
- jle @@Exit\r
- mov ax, [mx_ClipY1]\r
-@@CheckBottom:\r
- mov di, [mx_ClipY2]\r
- cmp ax, di\r
- jg @@Exit\r
- inc di\r
- sub di, dx\r
- sub di, ax ; Clipped some point?\r
- jge @@DoneHeight ; No, continue\r
- add dx, di ; Clip lines (DI is negative)\r
-@@DoneHeight:\r
-\r
-; Check clip width\r
-@@CheckLeft:\r
- mov di, [mx_ClipX1]\r
- cmp bx, di\r
- jge @@CheckRight\r
- sub di, bx ; Number of columns to clip left\r
- sub cx, di\r
- jle @@Exit\r
- mov bx, [mx_ClipX1]\r
-@@CheckRight:\r
- mov di, [mx_ClipX2]\r
- cmp bx, di\r
- jg @@Exit\r
- inc di\r
- sub di, bx\r
- sub di, cx ; Clipped some point?\r
- jge @@DoneWidth ; No, exit\r
- add cx, di ; New box width (DI is negative)\r
-@@DoneWidth:\r
-\r
-; Set return flag and exit\r
-@@Done:\r
- clc\r
- ret\r
-@@Exit:\r
- stc\r
- ret\r
-subClipBox ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXEL.ASM - Mid-point ellipse\r
-; Copyright (c) 1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-NOWARN RES\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxEllipse\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-EXTRN mx_BytesPerLine : WORD\r
-EXTRN mx_VideoSegment : WORD\r
-EXTRN mx_ClipX1 : WORD\r
-EXTRN mx_ClipY1 : WORD\r
-EXTRN mx_ClipX2 : WORD\r
-EXTRN mx_ClipY2 : WORD\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Draws an ellipse using the mid-point algorithm.\r
-;\r
-; Input:\r
-; XC, YC = center coordinates\r
-; A = horizontal radius\r
-; B = vertical radius\r
-; Color = ellipse color\r
-; Output:\r
-; none\r
-; Note:\r
-; computes only points in the first quadrant, all other\r
-; points are obtained by symmetry.\r
-;\r
-mxEllipse PROC FAR\r
- ARG Color:BYTE:2, \\r
- B:WORD, \\r
- A:WORD, \\r
- YC:WORD, \\r
- XC:WORD = ARG_SIZE\r
- LOCAL A2:DWORD, \\r
- B2:DWORD, \\r
- CC:DWORD, \\r
- DD:DWORD, \\r
- X:DWORD, \\r
- Y:DWORD = AUTO_SIZE\r
- .enter AUTO_SIZE\r
- .push ds, si, di\r
-\r
- .chk386 mxEllipse, @@Exit\r
-\r
-; Initialize variables\r
- xor eax, eax\r
- mov [X], ax ; X = 0\r
- mov ax, [A]\r
- mul eax ; EAX = A*A\r
- mov [DD], eax ; DD = A*A\r
- shl eax, 1\r
- mov [CC], eax ; CC = 2*A*A\r
- shl eax, 1\r
- mov [A2], eax ; A2 = 4*A*A\r
- movzx edx, [B]\r
- mov [Y], edx\r
- mul edx ; EAX = 4*A*A*B\r
- sub [DD], eax ; DD = A*A - 4*A*A*B\r
- movzx eax, [B]\r
- mul eax ; EAX = B*B\r
- shl eax, 2 ; EAX = 4*B*B\r
- mov [B2], eax ; B2 = 4*B*B\r
- add [CC], eax ; CC = 2*A*A + 4*B*B\r
- add [D1], eax ; DD = A*A - 4*A*A*B + 4*B*B\r
-\r
-; Draw initial points\r
- call subPlot4\r
-\r
-; First loop\r
-@@Loop1:\r
- mov eax, [X] ; Check slope\r
- mul [B2]\r
- mov ecx, eax\r
- mov eax, [Y]\r
- mul [A2]\r
- sub eax, ecx\r
- sub eax, [CC] ; EAX = Y*A2 - X*B2 - CC\r
- jle @@Done1 ; Crossed critical point, jump to next loop\r
-\r
- mov ecx, [DD] ; Get error\r
- test ecx, ecx ; Positive?\r
- jl @@Draw1 ; No, use default step\r
-\r
- mov eax, 1\r
- sub eax, [Y]\r
- mul [A2]\r
- shl eax, 1\r
- add ecx, eax ; Bump error\r
- dec WORD PTR [Y] ; Decrement Y coordinate\r
-\r
-@@Draw1:\r
- mov eax, [X]\r
- shl eax, 1\r
- add eax, 3\r
- mul [B2]\r
- add ecx, eax ; Bump error\r
- mov [DD], ecx ; Save error\r
- inc WORD PTR [X] ; Increment X coordinate\r
-\r
- call subPlot4 ; Draw points\r
- jmp @@Loop1\r
-@@Done1:\r
-\r
-; Initialize variables\r
- shr [B2], 2\r
- mov eax, [X]\r
- mul eax\r
- add [X]\r
- shl eax, 2\r
- inc eax\r
- mul [B2]\r
- mov [DD], eax\r
- mov eax, [Y]\r
- mul eax\r
- add [Y]\r
- dec eax\r
- add [Y]\r
- sub eax, [B2]\r
- add [DD], eax\r
- shl [B2], 3\r
- inc WORD PTR [X]\r
-\r
-; Second loop\r
-@@Loop2:\r
- cmp WORD PTR [Y], 0\r
- ja @@Done2\r
-\r
- mov ecx, [DD]\r
- test ecx, ecx\r
- jge @@Draw2\r
-\r
- mov eax, [X]\r
- inc eax\r
- mul [B2]\r
- add ecx, eax\r
- inc WORD PTR [X]\r
-\r
-@@Draw2:\r
- mov eax, [Y]\r
- shl eax, 1\r
- sub eax, 3\r
- neg eax\r
- imul [A2]\r
- add ecx, eax\r
- dec WORD PTR [Y]\r
-\r
- call subPlot4\r
- jmp @@Loop2\r
-@@Done2:\r
-\r
-@@Exit:\r
- xor ax, ax\r
- .leave ARG_SIZE\r
-mxEllipse ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXFB.ASM - Fill box function\r
-; Copyright (c) 1993,1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-NOWARN RES\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxFillBox\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-EXTRN mx_BytesPerLine : WORD\r
-EXTRN mx_VideoSegment : WORD\r
-EXTRN subClipBox : NEAR\r
-EXTRN subHorizontalLineInfo : NEAR\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Raster op functions. Raster op is limited to OP_MOVE,\r
-; OP_AND, OP_OR and OP_XOR. The VGA hardware is used to\r
-; perform the selected logical functions on up to four\r
-; pixel at a time.\r
-;\r
-subRepFill PROC NEAR\r
- mov ah, al\r
- shr cx, 1\r
- rep stosw\r
- rcl cx, 1\r
- rep stosb\r
- ret\r
-subRepFill ENDP\r
-;\r
-subFill PROC NEAR\r
-@@Loop:\r
- mov ds:[bx], al\r
- add bx, dx\r
- loop @@Loop\r
- ret\r
-subFill ENDP\r
-;\r
-subRepMove PROC NEAR\r
- mov si, di\r
-@@Loop:\r
- mov ah, ds:[si] ; Dummy read to latch the data\r
- mov ds:[si], al\r
- inc si\r
- loop @@Loop\r
- ret\r
-subRepMove ENDP\r
-;\r
-subMove PROC NEAR\r
-@@Loop:\r
- mov ah, ds:[bx] ; Dummy read to latch the data\r
- mov ds:[bx], al\r
- add bx, dx\r
- loop @@Loop\r
- ret\r
-subMove ENDP\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Fills a rectangle with a specified color.\r
-;\r
-; Input:\r
-; X, Y = X, Y coordinates of rectangle\r
-; Width = width of rectangle\r
-; Height = height of rectangle\r
-; Color = fill color\r
-; Op = raster operator\r
-; Output:\r
-; none\r
-;\r
-; Note: raster op is limited to OP_MOVE, OP_AND, OP_OR and OP_XOR.\r
-;\r
-mxFillBox PROC FAR\r
- ARG Op:WORD, \\r
- Color:BYTE:2, \\r
- Height:WORD, \\r
- Width:WORD, \\r
- Y:WORD, \\r
- X:WORD = ARG_SIZE\r
- LOCAL LeftMask:BYTE, \\r
- RightMask:BYTE, \\r
- FillFunction:WORD, \\r
- RepFillFunction:WORD = AUTO_SIZE\r
- .enter AUTO_SIZE\r
- .push ds, si, es, di\r
- ASSUME ds:NOTHING\r
-\r
-; Clip rectangle\r
- mov bx, [X]\r
- mov ax, [Y]\r
- mov cx, [Width]\r
- mov dx, [Height]\r
- call subClipBox\r
- jc @@Exit ; Full clipped\r
-\r
- mov [Height], dx ; Save clipped height\r
- call subHorizontalLineInfo ; Get additional info, init DI\r
- mov [Width], cx\r
- mov [LeftMask], al\r
- mov [RightMask], ah\r
-\r
-; Initialize segments\r
- mov ax, [mx_VideoSegment]\r
- mov es, ax ; ES:DI points to pixel\r
- mov ds, ax\r
- cld ; Clear direction flag\r
-\r
-; Select fill functions\r
- mov [FillFunction], OFFSET subFill\r
- mov [RepFillFunction], OFFSET subRepFill\r
- mov ax, [Op] ; Get raster op\r
- cmp al, OP_XOR\r
- ja @@1 ; Assume it's a fill\r
- cmp al, OP_MOVE\r
- je @@1\r
- .shl al, 3\r
- mov ah, al\r
- mov al, 03h\r
- mov dx, GDC\r
- out dx, ax ; Set GDC logical function\r
- mov [FillFunction], OFFSET subMove\r
- mov [RepFillFunction], OFFSET subRepMove\r
-@@1:\r
-\r
-; Fill left block\r
-@@L0:\r
- mov ah, [LeftMask]\r
- or ah, ah\r
- jz @@C0 ; Nothing to do, go to center block\r
- mov dx, TS\r
- mov al, 02h\r
- out dx, ax ; Set write plane mask\r
- mov dx, [mx_BytesPerLine]\r
- mov cx, [Height]\r
- mov bx, di\r
- mov al, [Color]\r
- call [FillFunction] ; Fill this column\r
- inc di ; Update starting video offset\r
-\r
-; Fill center block\r
-@@C0:\r
- mov cx, [Width]\r
- jcxz @@R0 ; Nothing to do, go to right block\r
- mov dx, TS\r
- mov ax, 0F02h\r
- out dx, ax ; Write to all planes\r
- mov al, [Color]\r
- mov bx, di\r
- mov dx, [Height]\r
- push di ; Save pixel address\r
-@@C1:\r
- mov di, bx ; Update video offset\r
- call [RepFillFunction] ; Fill current scan line\r
- mov cx, [Width] ; Restore byte count\r
- add bx, [mx_BytesPerLine] ; Bump to next scan line\r
- dec dx ; Done all lines?\r
- jnz @@C1 ; No, continue\r
- pop di ; Restore pixel address\r
- add di, [Width] ; Go to right block\r
-\r
-; Fill right block\r
-@@R0:\r
- mov ah, [RightMask]\r
- or ah, ah\r
- jz @@Done ; Nothing to do, exit\r
- mov dx, TS\r
- mov al, 02h\r
- out dx, ax ; Set write plane mask\r
- mov dx, [mx_BytesPerLine]\r
- mov cx, [Height]\r
- mov bx, di\r
- mov al, [Color]\r
- call [FillFunction] ; Fill this column\r
-\r
-; Restore VGA registers\r
-@@Done:\r
- mov dx, GDC\r
- mov ax, 0003h\r
- out dx, ax ; Set logical function to "move"\r
-\r
-@@Exit:\r
- xor ax, ax\r
- .pop ds, si, es, di\r
- .leave ARG_SIZE\r
-mxFillBox ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXFP.ASM - Fade palette function\r
-; Copyright (c) 1992-1994 ARTIS s.r.l.\r
-; Author: Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxFadePalette\r
-\r
-MAXCOLOR EQU 256\r
-FADE_IN EQU 0\r
-FADE_OUT EQU 1\r
-\r
-; The actual speed of fading depends on the number of passes (FADE_SPEED) and\r
-; the delay between two consecutive passes (FADE_DELAY). Below are the\r
-; default values, used when no parameters are specified.\r
-;\r
-FADE_DELAY EQU 1 ; Vert. retraces between video updates\r
-FADE_SPEED EQU 48 ; Speed of effect (max 127)\r
-\r
-; Bit field record for fade commands\r
-;\r
-FADE_COMMAND RECORD fpDELAY:8,fpSPEED:7,fpDIRECTION:1\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-DB 'Copyright (c) 1992-1994 ARTIS s.r.l. All rights reserved.'\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Fades a VGA palette.\r
-;\r
-; Input:\r
-; Buffer = pointer to source/destination palette\r
-; Command = fading direction and optional parameters\r
-; Start = index of first color to fade\r
-; Count = number of color to fade\r
-; Red = destination red\r
-; Green = destination green\r
-; Blue = destination blue\r
-; Output:\r
-; none\r
-; Notes:\r
-; - about 1.5 Kbytes of stack space are needed for internal buffers;\r
-; - the Command argument usually is 0 to fade in and 1 to fade out,\r
-; however additional parameters may be specified. To set the effect\r
-; speed, i.e. the number of iterations needed to completely fade a\r
-; palette, shift the value one bit left and "or" it with the\r
-; direction bit (range is 0..127). To set the delay between two\r
-; consecutive passes, shift it eight bits left (range is 0..255).\r
-;\r
-mxFadePalette PROC FAR\r
- ARG bBlue:WORD, \\r
- bGreen:WORD, \\r
- bRed:WORD, \\r
- wCount:WORD, \\r
- wStartIdx:WORD, \\r
- wCommand:WORD, \\r
- vfpPalette:DWORD = ARG_SIZE\r
- LOCAL bSPalette:BYTE:MAXCOLOR*3, \\r
- bDPalette:BYTE:MAXCOLOR*3, \\r
- bLoopIndex:BYTE, \\r
- bLoopStep:BYTE, \\r
- bLoopCount:BYTE, \\r
- wDelay:WORD, \\r
- wSpeed:WORD = AUTO_SIZE\r
- ASSUME ds:NOTHING\r
- .enter AUTO_SIZE\r
- .push si, di, ds, es ; Save registers\r
-;\r
-; Check parameters and setup variables\r
-;\r
-@@GetDelay:\r
- mov [wDelay], FADE_DELAY ; Set default delay\r
- mov ax, [wCommand] ; Get command word\r
- and ax, MASK fpDELAY ; Mask delay command\r
- jz @@GetSpeed ; No command, get speed\r
- IF USE286 EQ TRUE\r
- shr ax, fpDELAY\r
- ELSE\r
- mov cl, fpDELAY ; Get size of delay field\r
- shr ax, cl ; Right justify the field\r
- ENDIF\r
- mov [wDelay], ax ; Set new delay\r
-\r
-@@GetSpeed:\r
- mov ax, [wCommand] ; Get command\r
- and ax, MASK fpSPEED ; Mask speed\r
- IF USE286 EQ TRUE\r
- shr ax, fpSPEED\r
- ELSE\r
- mov cl, fpSPEED ; Get size of speed field\r
- shr ax, cl ; Right justify the field\r
- ENDIF\r
- or ax, ax ; Any speed specified?\r
- jnz @@SetVariables ; Yes, set variables\r
- mov ax, FADE_SPEED ; Set default speed\r
-\r
-@@SetVariables:\r
- mov [wSpeed], ax ; Set speed\r
- inc ax ; Number of iterations\r
- mov [bLoopCount], al ; Set loop count\r
- mov [bLoopStep], 1 ; Assume we're fading in\r
- mov [bLoopIndex], 0\r
-;\r
-; Check bounds for bad values\r
-;\r
- mov ax, [wStartIdx] ; Get first index\r
- cmp ax, MAXCOLOR ; Is in the valid range?\r
- jae @@Exit ; No, exit\r
- add ax, [wCount] ; Get last index\r
- cmp ax, MAXCOLOR ; Is in the valid range?\r
- jbe @@BoundsOk ; Yes, continue\r
- mov ax, MAXCOLOR\r
- sub ax, [wStartIdx]\r
- mov [wCount], ax ; Set count to maximum value\r
- or ax, ax\r
- jz @@Exit ; Nothing to do, exit\r
-@@BoundsOk:\r
-;\r
-; Copy the source palette in a local array: if we fade in it's ready to\r
-; use, otherwise we'll overwrite it later\r
-;\r
- mov cx, [wCount]\r
- mov ax, cx\r
- shl ax, 1\r
- add cx, ax ; CX = wCount * 3\r
- mov ax, ss\r
- mov es, ax\r
- lea di, [bSPalette] ; ES:DI points to local palette\r
- mov ax, [wStartIdx]\r
- mov si, ax\r
- shl ax, 1\r
- add ax, si\r
- lds si, [vfpPalette] ; DS:SI points to user palette\r
- add si, ax ; Skip unused entries\r
- cld\r
- shr cx, 1\r
- rep movsw\r
- rcl cx, 1\r
- rep movsb\r
-;\r
-; Check direction\r
-;\r
- test [wCommand], MASK fpDIRECTION ; Are we fading in?\r
- jz @@Main ; Yes, ok to continue\r
- mov ax, [wSpeed] ; Get speed\r
- mov [bLoopIndex], al ; Exchange first and last index\r
- mov [bLoopStep], -1 ; Move backward\r
- mov ax, ss ; Overwrite our copy of\r
- mov ds, ax ; user palette with the\r
- mov es, ax ; current active palette\r
- lea di, [bSPalette]\r
- mov ax, [wStartIdx]\r
- mov cx, [wCount]\r
- call ReadPalette ; Read current palette\r
-;\r
-; Prepare variables and registers for fading\r
-;\r
-@@Main:\r
- mov bh, BYTE PTR [bRed] ; Destination red\r
- and bh, 00111111b ; Be sure it's a valid VGA value\r
- mov bl, BYTE PTR [bGreen] ; Destination green\r
- and bl, 00111111b ; Be sure it's a valid VGA value\r
- mov dh, BYTE PTR [bBlue] ; Destination blue\r
- and dh, 00111111b ; Be sure it's a valid VGA value\r
- mov dl, [bLoopIndex] ; Loop index\r
- mov ax, ss ; All tables are stored\r
- mov ds, ax ; in the stack segment,\r
- mov es, ax ; set DS and ES\r
-;\r
-; Main loop\r
-;\r
-@@Loop:\r
- mov ax, [wCount] ; Store count in AX\r
- mov cx, [wSpeed] ; Set maximum speed in CX\r
- lea si, [bSPalette] ; DS:SI points to source palette\r
- lea di, [bDPalette] ; ES:DI points to dest. palette\r
- call RecalcPalette ; Build a faded palette\r
-\r
- .push bx, dx ; Save registers we need\r
- lea si, [bDPalette] ; DS:SI points to palette\r
- mov ax, [wStartIdx] ; First index to write\r
- mov bx, [wCount] ; Total entries to write\r
- mov cx, [wDelay] ; Fade delay between updates\r
- call WritePalette ; Write palette\r
- .pop bx, dx ; Restore BX and DX\r
-\r
- add dl, [bLoopStep] ; Change fade intensity\r
- dec [bLoopCount] ; Done?\r
- jnz @@Loop ; No, loop again\r
-\r
-@@Exit:\r
- .pop si, di, ds, es ; Restore registers\r
- .leave ARG_SIZE\r
-mxFadePalette ENDP\r
-\r
-;------- INTERNAL USE ONLY ------------------------------------------------\r
-;\r
-; Calculates a partially faded palette.\r
-;\r
-; Input:\r
-; AX = number of entries in palette\r
-; CX = maximum fade intensity (same as fade speed)\r
-; DS:SI = pointer to source palette\r
-; ES:DI = pointer to destination palette\r
-; BH = destination red\r
-; BL = destination green\r
-; DH = destination blue\r
-; DL = relative intensity of destination palette\r
-; Note:\r
-; it's important that a new palette can be calculated in less\r
-; than 1/70th of second. Fading to any RGB value requires use\r
-; of "imul" instructions: "idiv" may be replaced with faster\r
-; "sar", but only when the number of passes is a power of two,\r
-; thus reducing the range of selectable speeds.\r
-; In both cases an extimate of CPU cycles required by this\r
-; procedure shows that it's too slow to run on a 4.77 Mhz 8086\r
-; CPU and a 256 color palette, so we keep "idiv" and hope\r
-; the target machine to be at least a 6 Mhz 80286 (that's not\r
-; asking too much...).\r
-;\r
-RecalcPalette PROC NEAR\r
- cld\r
- push bp ; Save BP\r
- mov bp, ax ; Copy counter in BP\r
-@@Loop:\r
- lodsb ; Red: read value\r
- sub al, bh ; Subtract destination value\r
- imul dl ; Scale to desired weight\r
- idiv cl ; Put value in AL\r
- add al, bh ; Add destination value...\r
- stosb ; ...and store it\r
- lodsb ; Green: read value\r
- sub al, bl ; Subtract destination value\r
- imul dl ; Scale to desired weight\r
- idiv cl ; Put value in AL\r
- add al, bl ; Add destination value...\r
- stosb ; ...and store it\r
- lodsb ; Blue: read value\r
- sub al, dh ; Subtract destination value\r
- imul dl ; Scale to desired weight\r
- idiv cl ; Put value in AL\r
- add al, dh ; Add destination value...\r
- stosb ; ...and store it\r
- dec bp\r
- jnz @@Loop\r
- pop bp ; Restore BP\r
- ret\r
-RecalcPalette ENDP\r
-\r
-;------- INTERNAL USE ONLY ------------------------------------------------\r
-;\r
-; Writes a 256 color palette.\r
-;\r
-; Input:\r
-; AX = index of first color to write\r
-; BX = number of colors to write (each color is an RGB triplet)\r
-; CX = number of vertical retraces to wait before writing to DACs\r
-; DS:SI = pointer to first entry of palette\r
-;\r
-WritePalette PROC NEAR\r
- ASSUME ds:NOTHING\r
- mov ah, al ; Save index\r
- mov dx, 03DAh ; Input status register\r
-@@Delay1:\r
- in al, dx\r
- test al, 08h\r
- jnz @@Delay1 ; Wait for display mode\r
-@@Delay2:\r
- in al, dx\r
- test al, 08h\r
- jz @@Delay2 ; Wait for vertical retrace mode\r
- loop @@Delay1 ; Repeat CX times\r
-@@Write:\r
- mov cx, bx ; Get number of colors\r
- mov dx, 03C8h ; PEL write address register\r
- mov al, ah ; Restore index\r
- out dx, al ; Select index of first color\r
- inc dx ; PEL data register\r
- cld ; Move forward\r
- cli ; Disable interrupts\r
-@@Loop:\r
- lodsb\r
- out dx, al ; Red\r
- lodsb\r
- out dx, al ; Green\r
- lodsb\r
- out dx, al ; Blue\r
- loop @@Loop ; Loop until done\r
- sti ; Enable interrupts\r
- ret\r
-WritePalette ENDP\r
-\r
-;------- INTERNAL USE ONLY ------------------------------------------------\r
-;\r
-; Reads the current palette.\r
-;\r
-; Input:\r
-; AX = index of first color to read\r
-; CX = number of colors\r
-; ES:DI = pointer to destination buffer\r
-;\r
-ReadPalette PROC NEAR\r
- mov dx, 03C7h\r
- out dx, al\r
- inc dx\r
- inc dx\r
- cld\r
-@@Loop:\r
- in al, dx\r
- stosb\r
- in al, dx\r
- stosb\r
- in al, dx\r
- stosb\r
- loop @@Loop\r
- ret\r
-ReadPalette ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXGC.ASM - Get color function\r
-; Copyright (c) 1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxGetColor\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Returns the current setting of the selected DAC register.\r
-;\r
-; Input:\r
-; Index = color index (0-255)\r
-; R, G, B = byte pointers to red, green and blue\r
-; Output:\r
-; none\r
-;\r
-mxGetColor PROC FAR\r
- ARG B:DWORD, \\r
- G:DWORD, \\r
- R:DWORD, \\r
- Index:WORD = ARG_SIZE\r
- .enter 0\r
- .push ds, si\r
-\r
- mov ax, [Index]\r
- mov dx, 3C7h ; PEL read address register\r
- out dx, al\r
- inc dx\r
- inc dx\r
-\r
- lds si, [R]\r
- in al, dx\r
- mov ds:[si], al\r
- lds si, [G]\r
- in al, dx\r
- mov ds:[si], al\r
- lds si, [B]\r
- in al, dx\r
- mov ds:[si], al\r
-\r
- .pop ds, si\r
- .leave ARG_SIZE\r
-mxGetColor ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXGI.ASM - Get image\r
-; Copyright (c) 1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-NOWARN RES\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxGetImage\r
-\r
-EXTRN subClipImage : NEAR\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-EXTRN mx_VideoSegment : WORD\r
-EXTRN mx_BytesPerLine : WORD\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Copies an image from screen to memory.\r
-;\r
-; Input:\r
-; Image = pointer to buffer for image\r
-; X, Y = coordinates of image on screen\r
-; Width = width of image in pixels\r
-; Height = height of image in pixels\r
-; Output:\r
-; none\r
-;\r
-mxGetImage PROC FAR\r
- ARG Height:WORD, \\r
- Width:WORD, \\r
- Y:WORD, \\r
- X:WORD, \\r
- Image:DWORD = ARG_SIZE\r
- LOCAL PlaneWidth:WORD:4, \\r
- PixelOffset:WORD, \\r
- MoveFunction:WORD, \\r
- ReadPlane:BYTE, \\r
- Count:BYTE = AUTO_SIZE\r
- ASSUME ds:NOTHING\r
- .enter AUTO_SIZE\r
- .push ds, si, es, di\r
-\r
-; Clip image\r
- mov bx, [X]\r
- mov ax, [Y]\r
- mov cx, [Width]\r
- mov dx, [Height]\r
- call subClipImage\r
- jc @@Exit ; Full clipped\r
- mov [Height], dx\r
- add WORD PTR Image[0], si ; Skip clipped pixels\r
-\r
-; Get pixel address\r
- mul [mx_BytesPerLine]\r
- mov si, bx\r
- shr si, 1\r
- shr si, 1\r
- add si, ax\r
- mov [PixelOffset], si\r
- mov ds, [mx_VideoSegment] ; DS:SI points to pixel\r
- and bl, 03h\r
- mov [ReadPlane], bl\r
-\r
-; Compute extra bytes and width count for each plane\r
- mov bx, cx\r
- shr bx, 1\r
- shr bx, 1 ; Width for each plane\r
- and cl, 03h\r
- mov al, 00001000b\r
- shr al, cl\r
- mov di, 3 SHL 1\r
-@@PatchLoop:\r
- mov PlaneWidth[di], bx\r
- shr al, 1\r
- adc bx, 0\r
- dec di\r
- dec di\r
- jge @@PatchLoop\r
-\r
-; Get image\r
- cld\r
- mov [Count], 4 ; Four planes\r
- lea bx, PlaneWidth ; SS:[BX] = width in bytes for plane\r
- mov es, WORD PTR Image[2] ; ES:DI will point to image\r
- mov ah, [ReadPlane]\r
-@@PlaneLoop:\r
- cmp WORD PTR ss:[bx], 0 ; Exit if nothing more to do\r
- je @@Exit ; (also, never try to move zero bytes!)\r
- mov di, WORD PTR Image[0]\r
- mov al, 04h\r
- mov dx, GDC\r
- out dx, ax ; Select read plane\r
- mov dx, [Height]\r
- mov si, [PixelOffset] ; DS:SI points to video memory\r
-@@Loop:\r
- .push si, di\r
- mov cx, WORD PTR ss:[bx] ; Number of bytes to move\r
-@@MoveLoop:\r
- movsb\r
- add di, 3\r
- dec cx\r
- jnz @@MoveLoop\r
- .pop si, di\r
- add di, [Width] ; Go to next image line\r
- add si, [mx_BytesPerLine] ; Go to next screen row\r
- dec dx\r
- jnz @@Loop ; Repeat for all lines\r
- inc bx\r
- inc bx ; Select width for next plane\r
- inc ah\r
- test ah, 04h ; Plane wraparound?\r
- jz @@PlaneOk ; No\r
- inc [PixelOffset] ; Yes, bump video pointer\r
- and ah, 03h\r
-@@PlaneOk:\r
- inc WORD PTR Image[0]\r
- dec [Count]\r
- jnz @@PlaneLoop ; Repeat for all planes\r
-\r
-@@Exit:\r
- xor ax, ax\r
- .pop ds, si, es, di\r
- .leave ARG_SIZE\r
-mxGetImage ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXGM.ASM - Gamma correction\r
-; Copyright (c) 1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxGammaCorrect\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-mx_tblGamma LABEL BYTE\r
- DB 00, 10, 14, 17, 19, 21, 23, 24, 26, 27, 28, 29, 31, 32, 33, 34\r
- DB 35, 36, 37, 37, 38, 39, 40, 41, 41, 42, 43, 44, 44, 45, 46, 46\r
- DB 47, 48, 48, 49, 49, 50, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55\r
- DB 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 61, 61, 62, 62, 63, 63\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Correct palette colors (gamma is 2.3).\r
-;\r
-; Input:\r
-; CPal = pointer to color palette\r
-; GPal = pointer to destination (gamma corrected) palette\r
-; Count = number of colors to convert\r
-; Output:\r
-; none\r
-;\r
-; Note: CPal and GPal may point to the same buffer.\r
-;\r
-mxGammaCorrect PROC FAR\r
- ARG Count:WORD, \\r
- DPal:DWORD, \\r
- SPal:DWORD = ARG_SIZE\r
- ASSUME ds:NOTHING\r
- .enter 0\r
- .push ds, si, es, di\r
-\r
- mov cx, [Count]\r
- jcxz @@Exit ; Exit now if nothing to do\r
- lds si, [SPal]\r
- les di, [DPal]\r
- mov bx, OFFSET mx_tblGamma ; Setup BX for XLAT instruction\r
- cld\r
- mov ax, cx ; AX = Count\r
- add cx, cx ; CX = Count*2\r
- add cx, ax ; CX = Count*3\r
-@@Loop:\r
- lodsb\r
- xlat mx_tblGamma\r
- stosb\r
- loop @@Loop\r
-\r
-@@Exit:\r
- .pop ds, si, es, di\r
- .leave ARG_SIZE\r
-mxGammaCorrect ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXGP.ASM - Get palette function\r
-; Copyright (c) 1993,1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxGetPalette\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Returns the current setting of the VGA palette.\r
-;\r
-; Input:\r
-; Buffer = pointer to palette data (R,G,B)\r
-; Start = index of first color to get\r
-; Count = number of color to get\r
-; Output:\r
-; none\r
-;\r
-mxGetPalette PROC FAR\r
- ARG Count:WORD, \\r
- Start:WORD, \\r
- Buffer:DWORD = ARG_SIZE\r
- ASSUME ds:NOTHING\r
- .enter 0\r
- .push es, di\r
-\r
- les di, [Buffer]\r
- mov cx, [Count]\r
- mov ax, [Start]\r
- mov dx, 3C7h ; PEL read address register\r
- out dx, al\r
- inc dx\r
- inc dx\r
- cld\r
-@@Loop:\r
- in al, dx\r
- stosb\r
- in al, dx\r
- stosb\r
- in al, dx\r
- stosb\r
- loop @@Loop ; Loop until done\r
-\r
- .pop es, di\r
- .leave ARG_SIZE\r
-mxGetPalette ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXGV.ASM - Get version function\r
-; Copyright (c) 1993,1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxGetVersion\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Returns the library version.\r
-;\r
-mxGetVersion PROC FAR\r
- mov ax, MXVERSION\r
- ret\r
-mxGetVersion ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXHL.ASM - Horizontal line mask utility\r
-; Copyright (c) 1993,1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC subHorizontalLineInfo\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-EXTRN mx_BytesPerLine : WORD\r
-\r
-tblLeftSize DW 00h, 03h, 02h, 01h\r
-tblLeftMask DB 00h, 0Eh, 0Ch, 08h\r
-tblRightMask DB 00h, 01h, 03h, 07h\r
-tblPatchMask DB 02h, 06h\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Prepares register for fast horizontal line drawing.\r
-;\r
-; Input:\r
-; BX, AX = X, Y address of left pixel\r
-; CX = line width\r
-; Output:\r
-; DI = left pixel offset in video memory\r
-; AL = left block write plane mask (0 = none)\r
-; AH = right block write plane mask (0 = none)\r
-; CX = center block width in 4-pixel blocks\r
-;\r
-subHorizontalLineInfo PROC NEAR\r
- ASSUME ds:NOTHING\r
-\r
- mul [mx_BytesPerLine]\r
- mov di, bx\r
- shr di, 1\r
- shr di, 1\r
- add di, ax ; Offset of left pixel\r
-\r
- and bx, 03h\r
- mov al, tblLeftMask[bx]\r
- shl bx, 1\r
- sub cx, tblLeftSize[bx]\r
- jge @@1 ; Ok to continue\r
-\r
-; Special case: start and end in the middle of a 4-pixel block.\r
-; There are only three cases:\r
-; Pixels Left mask CX CX+2 Patch mask Result\r
-; 1) ..o. ..xx -1 1 .xx. ..x.\r
-; 2) .oo. .xxx -1 1 .xx. .xx.\r
-; 3) .o.. .xxx -2 0 .x.. .x..\r
-; All other cases are automatically handled with the standard masks.\r
- mov bx, cx\r
- inc bx\r
- inc bx\r
- and al, tblPatchMask[bx] ; Combine masks\r
- xor ah, ah ; No right block\r
- xor cx, cx ; No center block\r
- jmp @@Exit\r
-\r
-@@1:\r
- mov bx, cx\r
- and bx, 03h\r
- mov ah, tblRightMask[bx]\r
- shr cx, 2\r
-\r
-@@Exit:\r
- ret\r
-subHorizontalLineInfo ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXIT.ASM - Initialization/termination functions\r
-; Copyright (c) 1993,1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxInit\r
-PUBLIC mxTerm\r
-\r
-PUBLIC mx_VideoSegment\r
-PUBLIC mx_CodeSegment\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-DB 'MODEX library - Copyright (c) 1992-1994 Alessandro Scotti'\r
-\r
-mx_VideoSegment DW 0A000h\r
-mx_CodeSegment DW SEG MX_TEXT\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Initialization.\r
-;\r
-; Input:\r
-; none\r
-; Output:\r
-; AX = 0 on success\r
-;\r
-mxInit PROC FAR\r
- LOCAL Result:WORD, \\r
- VideoSeg:WORD, \\r
- CStoDSalias:WORD = AUTO_SIZE\r
- ASSUME ds:NOTHING\r
- .enter AUTO_SIZE\r
- .push ds, si, es, di\r
-\r
- mov [Result], -1 ; Assume an error\r
- mov [VideoSeg], 0A000h ; Real mode video segment\r
- mov [CStoDSalias], cs ; Real mode data alias for CS\r
-\r
-; Check if running in protected mode under DPMI\r
- mov ax, 1686h\r
- int 2Fh\r
- or ax, ax\r
- jnz @@1 ; DPMI not found, continue in real mode\r
-\r
-; Get a data alias for CS\r
- mov ax, 000Ah ; DMPI: create data alias\r
- mov bx, cs\r
- int 31h\r
- jc @@Exit ; Exit if service failed\r
- mov [CStoDSalias], ax ; Save data alias for CS\r
-; Get a protected-mode selector for the video segment\r
- mov ax, 0002h\r
- mov bx, 0A000h ; Real mode segment of video\r
- int 31h ; DPMI: get segment selector\r
- jc @@Exit ; Exit if service failed\r
- mov [VideoSeg], ax ; Save protected mode video selector\r
-\r
-; Initialize variables\r
-@@1:\r
- mov ds, [CStoDSalias]\r
- ASSUME ds:MX_TEXT\r
- mov [mx_CodeSegment], ds\r
- mov ax, [VideoSeg]\r
- mov [mx_VideoSegment], ax\r
-\r
-; Don't bother with VGA check for now...\r
-\r
- mov [Result], 0\r
-\r
-@@Exit:\r
- mov ax, [Result]\r
- .pop ds, si, es, di\r
- .leave\r
-mxInit ENDP\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Termination.\r
-;\r
-; Input:\r
-; none\r
-; Output:\r
-; always 0.\r
-;\r
-mxTerm PROC FAR\r
- ASSUME ds:NOTHING\r
- xor ax, ax\r
- ret\r
-mxTerm ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXLL.ASM - Load latches\r
-; Copyright (c) 1993,1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxLoadLatches\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-EXTRN mx_VideoSegment : WORD\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Loads the specified value into the VGA latches.\r
-;\r
-; Input:\r
-; BL = value to load into latches\r
-; Output:\r
-; none\r
-; Changes:\r
-; bit mask register to FFh;\r
-; function select register to "move";\r
-; write mode to 00h.\r
-; Note:\r
-; this is for internal use only.\r
-;\r
-mxLoadLatches PROC NEAR\r
- ASSUME ds:NOTHING\r
-\r
- .push ds, si\r
- mov dx, GDC\r
- mov ax, 0FF08h\r
- out dx, ax ; Set bit mask to FFh\r
- mov ax, 0003h\r
- out dx, ax ; Set function to "move"\r
- mov ax, 0005h\r
- out dx, ax ; Set write mode\r
- mov ax, [mx_VideoSegment]\r
- mov ds, ax\r
- mov si, 0FFFFh\r
- mov bh, 8 ; BH = write plane mask\r
- mov cx, 3 ; CX = count = read plane\r
-; Saves old values and force BL into latches\r
-@@SetLoop:\r
- mov dx, GDC\r
- mov al, 04h\r
- mov ah, cl\r
- out dx, ax ; Select read plane\r
- mov dx, TS\r
- mov al, 02h\r
- mov ah, bh\r
- out dx, ax ; Select write plane\r
- mov al, ds:[si]\r
- push ax\r
- mov ds:[si], bl\r
- mov al, ds:[di] ; Force value into latch\r
- shr bh, 1 ; Next write plane\r
- loop @@SetLoop\r
-; Restore previous values\r
- mov cx, 3\r
- mov bh, 8\r
- mov dx, TS\r
-@@ResetLoop:\r
- mov al, 02h\r
- mov ah, bh\r
- out dx, ax ; Select write plane\r
- pop ax\r
- mov ds:[si], al\r
- shr bh, 1 ; Next write plane\r
- loop @@ResetLoop\r
-; Exit\r
- .pop ds, si\r
- ret\r
-mxLoadLatches ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXLN.ASM - Line function\r
-; Copyright (c) 1993,1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-NOWARN RES\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxLine\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-EXTRN mx_BytesPerLine : WORD\r
-EXTRN mx_VideoSegment : WORD\r
-\r
-EXTRN mx_ClipX1 : WORD\r
-EXTRN mx_ClipY1 : WORD\r
-EXTRN mx_ClipX2 : WORD\r
-EXTRN mx_ClipY2 : WORD\r
-\r
-tblDrawFunc LABEL WORD\r
- DW subWidthMove\r
- DW subHeightMove\r
- DW subWidthOp\r
- DW subHeightOp\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Draws a line from (X1,Y1) to (X2,Y2) using the Bresenham\r
-; algorithm.\r
-;\r
-; Input:\r
-; X1, Y1 = start point\r
-; X2, Y2 = end point\r
-; Color = line color\r
-; Op = raster operator\r
-; Output:\r
-; none\r
-;\r
-; Note: the end point (X2,Y2) *IS* drawed. I don't like this very much\r
-; but clipping is much simpler.\r
-;\r
-mxLine PROC FAR\r
- ARG Op:WORD, \\r
- Color:WORD, \\r
- Y2:WORD, \\r
- X2:WORD, \\r
- Y1:WORD, \\r
- X1:WORD = ARG_SIZE\r
- LOCAL Width:WORD, \\r
- Height:WORD, \\r
- ErrorAdd:WORD, \\r
- ErrorSub:WORD, \\r
- DeltaX:WORD, \\r
- DeltaY:WORD, \\r
- P1:BYTE, \\r
- P2:BYTE, \\r
- WritePlane:BYTE = AUTO_SIZE\r
- .enter AUTO_SIZE\r
- .push ds, si, di\r
- ASSUME ds:NOTHING\r
-\r
- mov ax, [X1]\r
- mov bx, [Y1]\r
- mov cx, [X2]\r
- mov dx, [Y2]\r
- call subClipLine\r
- jc @@Exit ; Line is full clipped\r
-\r
-; Get width\r
- mov si, cx\r
- xchg ax, si ; SI = X1, AX = X2\r
- sub ax, si\r
- jge @@1\r
-; Swap points, we want X1 < X2\r
- xchg si, cx ; Swap X1 and X2\r
- xchg bx, dx ; Swap Y1 and Y2\r
- neg ax\r
-@@1:\r
- mov [Width], ax\r
-\r
-; Get height\r
- mov cx, [mx_BytesPerLine] ; We don't need X2 anymore\r
- mov ax, dx\r
- sub ax, bx\r
- jge @@2\r
- neg cx ; Move from bottom to top\r
- neg ax ; Get absolute value of AX\r
-@@2:\r
- mov [Height], ax\r
- mov [DeltaY], cx\r
-\r
-; Get pixel address and write plane\r
- mov ax, bx\r
- mul [mx_BytesPerLine]\r
- mov cx, si ; CX = X1\r
- shr si, 1\r
- shr si, 1\r
- add si, ax ; SI = pixel offset\r
- and cl, 03h\r
- mov ax, 1102h\r
- shl ah, cl\r
- mov [WritePlane], ah\r
- mov dx, TS\r
- out dx, ax ; Set write plane\r
- mov ax, [mx_VideoSegment]\r
- mov ds, ax ; DS:SI points to (X1,Y1)\r
-\r
-; Select the function to handle the drawing loop\r
- xor bx, bx\r
- mov al, BYTE PTR [Op]\r
- cmp al, OP_MOVE\r
- je @@3\r
- and al, 03h\r
- shl al, 1\r
- shl al, 1\r
- shl al, 1\r
- mov ah, al\r
- mov al, 03h\r
- mov dx, GDC\r
- out dx, ax ; Set logical function\r
- inc bx\r
- inc bx\r
-@@3:\r
- mov ax, [Width]\r
- mov cx, [Height]\r
-; Horizontal, vertical and diagonal lines are not optimized yet\r
- cmp ax, cx\r
- jae @@4\r
- inc bx\r
-@@4:\r
- shl bx, 1\r
- call tblDrawFunc[bx]\r
-\r
-; Reset logical function if needed\r
- cmp BYTE PTR [Op], OP_MOVE\r
- je @@Exit\r
- mov ax, 0003h\r
- mov dx, GDC\r
- out dx, ax\r
-\r
-@@Exit:\r
- xor ax, ax\r
- .pop ds, si, di\r
- .leave ARG_SIZE\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Checks the coordinates of a line against the active\r
-; clip region.\r
-; Uses a variation of the Cohen-Sutherland algorithm developed\r
-; by Victor Duvanenko.\r
-;\r
-; Input:\r
-; AX, BX = X1, Y1\r
-; CX, DX = X2, Y2\r
-; Output:\r
-; CF = set if line is full clipped\r
-; AX, BX = clipped X1, Y1\r
-; CX, DX = clipped X2, Y2\r
-; Note:\r
-; destroys SI, DI\r
-;\r
-subClipLine PROC NEAR\r
- mov di, ax ; Copy X1 to DI and free AX\r
- mov si, dx ; Copy Y2 to SI and free DX\r
-; Compute clip codes for point (X2,Y2)=(CX,SI)\r
- xor al, al\r
-@@P2X1: cmp cx, [mx_ClipX1]\r
- jge @@P2X2\r
- or al, 1\r
-@@P2X2: cmp cx, [mx_ClipX2]\r
- jle @@P2Y1\r
- or al, 2\r
-@@P2Y1: cmp si, [mx_ClipY1]\r
- jge @@P2Y2\r
- or al, 4\r
-@@P2Y2: cmp si, [mx_ClipY2]\r
- jle @@P2XY\r
- or al, 8\r
-@@P2XY: mov [P2], al\r
-; Compute clip codes for point (X1,Y1)=(DI,BX)\r
- xor al, al\r
-@@P1X1: cmp di, [mx_ClipX1]\r
- jge @@P1X2\r
- or al, 1\r
-@@P1X2: cmp di, [mx_ClipX2]\r
- jle @@P1Y1\r
- or al, 2\r
-@@P1Y1: cmp bx, [mx_ClipY1]\r
- jge @@P1Y2\r
- or al, 4\r
-@@P1Y2: cmp bx, [mx_ClipY2]\r
- jle @@P1XY\r
- or al, 8\r
-@@P1XY: mov [P1], al\r
-; Check codes for trivial cases\r
- mov ah, [P2]\r
- test al, ah ; Is line invisible?\r
- jnz @@FullClip ; Yes, exit\r
- or ah, al ; Both points clipped?\r
- jz @@Done ; Yes, exit\r
-; Calculate deltas\r
- mov ax, cx\r
- sub ax, di\r
- mov [DeltaX], ax\r
- mov ax, si\r
- sub ax, bx\r
- mov [DeltaY], ax\r
- mov al, [P1] ; Init clipping code\r
-; Clipping loop\r
-@@ClipLoop:\r
- test al, al ; Is first point clipped?\r
- jnz @@ClipX1 ; No, continue\r
- xchg cx, di ; Swap points...\r
- xchg bx, si\r
- xchg al, [P2] ; ...and codes\r
-; Clip left: Y1 = Y1 + DeltaY*(mx_ClipX1-X1)/DeltaX\r
-@@ClipX1:\r
- test al, 1\r
- jz @@ClipX2\r
- mov ax, [mx_ClipX1]\r
- sub ax, di\r
- mov di, [mx_ClipX1]\r
- jmp @@ClipX1X2\r
-; Clip right: Y1 = Y1 + DeltaY*(mx_ClipX2-X1)/DeltaX\r
-@@ClipX2:\r
- test al, 2\r
- jz @@ClipY1\r
- mov ax, [mx_ClipX2]\r
- sub ax, di\r
- mov di, [mx_ClipX2]\r
-@@ClipX1X2:\r
- imul [DeltaY]\r
- idiv [DeltaX]\r
- add bx, ax\r
- mov al, 8\r
- cmp bx, [mx_ClipY2]\r
- jg @@CheckLoop\r
- mov al, 4\r
- cmp bx, [mx_ClipY1]\r
- jl @@CheckLoop\r
- xor al, al\r
- jmp @@CheckLoop\r
-; Clip top: X1 = X1 + DeltaX*(mx_ClipY1-Y1)/DeltaY\r
-@@ClipY1:\r
- test al, 4\r
- jz @@ClipY2\r
- mov ax, [mx_ClipY1]\r
- sub ax, bx\r
- mov bx, [mx_ClipY1]\r
- jmp @@ClipY1Y2\r
-; Clip bottom: X1 = X1 + DeltaX*(mx_ClipY2-Y1)/DeltaY\r
-@@ClipY2:\r
- mov ax, [mx_ClipY2]\r
- sub ax, bx\r
- mov bx, [mx_ClipY2]\r
-@@ClipY1Y2:\r
- imul [DeltaX]\r
- idiv [DeltaY]\r
- add di, ax\r
- mov al, 1\r
- cmp di, [mx_ClipX1]\r
- jl @@CheckLoop\r
- mov al, 2\r
- cmp di, [mx_ClipX2]\r
- jg @@CheckLoop\r
- xor al, al\r
-@@CheckLoop:\r
- mov ah, [P2]\r
- test al, ah\r
- jnz @@FullClip\r
- or ah, al\r
- jnz @@ClipLoop\r
-\r
-@@Done:\r
- mov ax, di\r
- mov dx, si\r
- clc\r
- ret\r
-@@FullClip:\r
- stc\r
- ret\r
-subClipLine ENDP\r
-\r
-; Called when Width >= Height and Op = OP_MOVE\r
-subWidthMove PROC NEAR\r
- mov di, ax\r
- neg di ; Initialize error term\r
- shl cx, 1\r
- mov [ErrorAdd], cx\r
- mov cx, ax\r
- shl ax, 1\r
- mov [ErrorSub], ax\r
- mov al, 02h\r
- mov ah, [WritePlane]\r
- mov bl, BYTE PTR [Color]\r
- mov dx, TS\r
- inc cx\r
-@@Loop:\r
- mov ds:[si], bl\r
- dec cx\r
- jz @@Exit\r
- rol ah, 1\r
- adc si, 0\r
- out dx, ax\r
- add di, [ErrorAdd]\r
- jl @@Loop\r
- add si, [DeltaY]\r
- sub di, [ErrorSub]\r
- jmp @@Loop\r
-@@Exit:\r
- ret\r
-subWidthMove ENDP\r
-\r
-; Called when Width < Height and Op = OP_MOVE\r
-subHeightMove PROC NEAR\r
- mov di, cx\r
- neg di ; Initialize error term\r
- shl ax, 1\r
- mov [ErrorAdd], ax\r
- mov ax, cx\r
- shl ax, 1\r
- mov [ErrorSub], ax\r
- mov bl, BYTE PTR [Color]\r
- mov ah, [WritePlane]\r
- mov al, 02h\r
- mov dx, TS\r
- inc cx\r
-@@Loop:\r
- mov ds:[si], bl\r
- dec cx\r
- jz @@Exit\r
- add si, [DeltaY]\r
- add di, [ErrorAdd]\r
- jl @@Loop\r
- rol ah, 1 ; Next write plane\r
- adc si, 0 ; Bump video offset if plane overflows\r
- out dx, ax\r
- sub di, [ErrorSub] ; Adjust error down\r
- jmp @@Loop\r
-@@Exit:\r
- ret\r
-subHeightMove ENDP\r
-\r
-; Called when Width >= Height and Op <> OP_MOVE\r
-subWidthOp PROC NEAR\r
- mov di, ax\r
- neg di ; Initialize error term\r
- shl cx, 1\r
- mov [ErrorAdd], cx\r
- mov cx, ax\r
- shl ax, 1\r
- mov [ErrorSub], ax\r
- mov al, 02h\r
- mov ah, [WritePlane]\r
- mov bl, BYTE PTR [Color]\r
- mov dx, TS\r
- inc cx\r
-@@Loop:\r
- mov bh, ds:[si] ; Latch data\r
- mov ds:[si], bl\r
- dec cx\r
- jz @@Exit\r
- rol ah, 1\r
- adc si, 0\r
- out dx, ax\r
- add di, [ErrorAdd]\r
- jl @@Loop\r
- add si, [DeltaY]\r
- sub di, [ErrorSub]\r
- jmp @@Loop\r
-@@Exit:\r
- ret\r
-subWidthOp ENDP\r
-\r
-; Called when Width < Height and Op <> OP_MOVE\r
-subHeightOp PROC NEAR\r
- mov di, cx\r
- neg di ; Initialize error term\r
- shl ax, 1\r
- mov [ErrorAdd], ax\r
- mov ax, cx\r
- shl ax, 1\r
- mov [ErrorSub], ax\r
- mov bl, BYTE PTR [Color]\r
- mov ah, [WritePlane]\r
- mov al, 02h\r
- mov dx, TS\r
- inc cx\r
-@@Loop:\r
- mov bh, ds:[si]\r
- mov ds:[si], bl\r
- dec cx\r
- jz @@Exit\r
- add si, [DeltaY]\r
- add di, [ErrorAdd]\r
- jl @@Loop\r
- rol ah, 1 ; Next write plane\r
- adc si, 0 ; Bump video offset if plane overflows\r
- out dx, ax\r
- sub di, [ErrorSub] ; Adjust error down\r
- jmp @@Loop\r
-@@Exit:\r
- ret\r
-subHeightOp ENDP\r
-\r
-mxLine ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXOT.ASM - Text functions\r
-; Copyright (c) 1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-NOWARN RES ; We use the reserved name 'WIDTH'\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxOutChar\r
-PUBLIC mxOutText\r
-PUBLIC mxSetFont\r
-PUBLIC mxSetTextColor\r
-PUBLIC mxGetTextStep\r
-PUBLIC mxSetTextStep\r
-\r
-MAX_WIDTH EQU 16 ; Must be <= 16\r
-MAX_HEIGHT EQU 32\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-EXTRN mx_CodeSegment : WORD\r
-EXTRN mxPutImage : FAR\r
-\r
-; Default 8x8 font\r
-fnt_Default LABEL\r
- INCLUDE DEFAULT.FNT\r
-\r
-; Table of system fonts\r
-tbl_SystemFont LABEL WORD\r
- DW fnt_Default, 8, 8\r
-\r
-MX_MAXSYSFONT EQU ($-OFFSET tbl_SystemFont) SHR 2\r
-\r
-mx_FontPtr DW OFFSET fnt_Default, SEG MX_TEXT\r
-mx_FontWidth DW 8 ; Font width in pixels\r
-mx_FontHeight DW 8 ; Font height in pixels\r
-mx_FontCharSize DW 8 ; Size in bytes of a font character\r
-mx_FontColor DW 00FFh ; Color: foreground + background*256\r
-mx_FontOp DW OP_MOVE ; Raster op\r
-mx_DeltaX DW 8 ; Horizontal step\r
-mx_DeltaY DW 0 ; Vertical step\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Sets the current font.\r
-;\r
-; Input:\r
-; Font = pointer to font data\r
-; Width = width of font character in pixels\r
-; Height = height of font character in pixels\r
-; Output:\r
-; AX = 0 on success, else invalid parameters\r
-;\r
-; Note: when the high word of Font (i.e. the segment) is zero, the low\r
-; word is used to select one of the system fonts.\r
-;\r
-mxSetFont PROC FAR\r
- ARG Height:WORD, \\r
- Width:WORD, \\r
- Font:DWORD = ARG_SIZE\r
- .enter 0\r
- .push ds\r
-\r
- mov ds, [mx_CodeSegment]\r
- ASSUME ds:MX_TEXT\r
-\r
- mov ax, WORD PTR Font[2] ; Get font segment\r
- test ax, ax ; Null segment?\r
- jnz @@UserFont ; No, install user font\r
-\r
-; Install system font\r
- mov ax, WORD PTR Font[0] ; Get font number\r
- cmp ax, MX_MAXSYSFONT ; Check range\r
- jb @@SystemFont\r
- xor ax, ax ; Out of range, use default font\r
-@@SystemFont:\r
- shl ax, 1\r
- shl ax, 1\r
- mov bx, ax\r
- mov ax, tbl_SystemFont[bx] ; Get font offset\r
- mov WORD PTR mx_FontPtr[0], ax\r
- mov WORD PTR mx_FontPtr[2], cs\r
- mov al, BYTE PTR tbl_SystemFont[bx+2]\r
- xor ah, ah\r
- mov [mx_FontWidth], ax\r
- mov [mx_DeltaX], ax\r
- mov dl, BYTE PTR tbl_SystemFont[bx+3]\r
- xor dh, dh\r
- mov [mx_FontHeight], dx\r
- mul dx\r
- mov [mx_FontCharSize], ax\r
- mov [mx_DeltaX], ax\r
- xor ax, ax\r
- mov [mx_DeltaY], ax\r
- jmp @@Exit\r
-\r
-; Install user font\r
-@@UserFont:\r
- mov ax, -1 ; Assume an error\r
- mov bx, [Width]\r
- cmp bx, MAX_WIDTH\r
- ja @@Exit ; Invalid character width\r
- mov dx, [Height]\r
- cmp dx, MAX_HEIGHT\r
- ja @@Exit ; Invalid character height\r
- mov [mx_FontWidth], bx\r
- mov [mx_FontHeight], dx\r
- mov ax, bx\r
- add ax, 7\r
- .shr ax, 3\r
- mul dx\r
- mov [mx_FontCharSize], ax\r
- mov ax, WORD PTR Font[0]\r
- mov WORD PTR mx_FontPtr[0], ax\r
- mov ax, WORD PTR Font[2]\r
- mov WORD PTR mx_FontPtr[2], ax\r
- xor ax, ax\r
-\r
-@@Exit:\r
- .pop ds\r
- ASSUME ds:NOTHING\r
- .leave ARG_SIZE\r
-mxSetFont ENDP\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Sets the text color and raster op.\r
-;\r
-; Input:\r
-; Color = text color (foreground + background*256)\r
-; Op = raster op\r
-; Output:\r
-; none\r
-;\r
-mxSetTextColor PROC FAR\r
- ARG Op:WORD, \\r
- Color:WORD = ARG_SIZE\r
- .enter 0\r
- .push ds\r
-\r
- mov ds, [mx_CodeSegment]\r
- ASSUME ds:MX_TEXT\r
-\r
- mov ax, [Color]\r
- mov [mx_FontColor], ax\r
- mov ax, [Op]\r
- mov [mx_FontOp], ax\r
-\r
- xor ax, ax\r
- .pop ds\r
- ASSUME ds:NOTHING\r
- .leave ARG_SIZE\r
-mxSetTextColor ENDP\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Writes a character using the current font and attributes.\r
-;\r
-; Input:\r
-; X, Y = video coordinates\r
-; C = character to print\r
-; Output:\r
-; none\r
-;\r
-mxOutChar PROC FAR\r
- ARG C:BYTE:2, \\r
- Y:WORD, \\r
- X:WORD = ARG_SIZE\r
- LOCAL Image:BYTE:MAX_WIDTH*MAX_HEIGHT, \\r
- Count:WORD = AUTO_SIZE\r
- .enter AUTO_SIZE\r
- .push ds, si, es, di\r
- ASSUME ds:NOTHING\r
-\r
-; Gets the pointer to font data for the selected character\r
- lds si, DWORD PTR [mx_FontPtr]\r
- mov al, [C]\r
- xor ah, ah\r
- mul [mx_FontCharSize] ; Offset into font\r
- add si, ax ; DS:SI -> font data for character\r
-\r
-; Converts font data into a 256-color linear image\r
- mov ax, ss\r
- mov es, ax\r
- lea di, [Image]\r
- mov dx, [mx_FontColor]\r
- mov ax, [mx_FontHeight]\r
- mov [Count], ax\r
-@@HeightLoop:\r
- mov cx, [mx_FontWidth]\r
- mov bh, ds:[si]\r
- inc si ; Get a byte from font data\r
- cmp cx, 8\r
- jbe @@WidthLoop ; Ok for width <= 8\r
- mov bl, ds:[si] ; Get another byte\r
- inc si\r
-@@WidthLoop:\r
- mov al, dl ; Assume foreground color\r
- shl bx, 1 ; Is font bit set?\r
- jc @@1 ; Yes, foreground is just great\r
- mov al, dh ; Get background color\r
-@@1:\r
- mov es:[di], al ; Put pixel into image\r
- inc di\r
- dec cx\r
- jnz @@WidthLoop\r
- dec [Count]\r
- jnz @@HeightLoop\r
-\r
-; Now pass image to mx_PutImage\r
- lea ax, [Image]\r
- push es\r
- push ax ; Pointer to image\r
- push [X]\r
- push [Y] ; Image coordinates\r
- push [mx_FontWidth]\r
- push [mx_FontHeight] ; Image size\r
- push [mx_FontOp] ; Raster op\r
- call mxPutImage ; Write character\r
-\r
- xor ax, ax\r
- .pop ds, si, es, di\r
- .leave ARG_SIZE\r
-mxOutChar ENDP\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Writes a string at the coordinates specified.\r
-;\r
-; Input:\r
-; X, Y = text coordinates\r
-; S = pointer to ASCIIZ string\r
-; Output:\r
-; none\r
-;\r
-mxOutText PROC FAR\r
- ARG S:DWORD, \\r
- Y:WORD, \\r
- X:WORD = ARG_SIZE\r
- .enter 0\r
- .push ds, si\r
- ASSUME ds:NOTHING\r
-\r
- lds si, [S]\r
-@@Loop:\r
- mov al, ds:[si]\r
- test al, al ; End of string?\r
- jz @@Exit ; Yes, exit\r
- inc si\r
- push [X] ; Display character\r
- push [Y]\r
- push ax\r
- call mxOutChar\r
- mov ax, [mx_DeltaX]\r
- add [X], ax ; Bump X coordinate\r
- mov ax, [mx_DeltaY]\r
- add [Y], ax ; Bump Y coordinate\r
- dec [Count]\r
- jnz @@Loop\r
-\r
-@@Exit:\r
- xor ax, ax\r
- .pop ds, si\r
- .leave ARG_SIZE\r
- ret\r
-mxOutText ENDP\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Sets the distance between characters.\r
-;\r
-; Input:\r
-; DeltaX = horizontal distance in pixels\r
-; DeltaY = vertical distance in pixels\r
-; Output:\r
-; none\r
-;\r
-; Note: this function may be used to set the text direction.\r
-;\r
-mxSetTextStep PROC FAR\r
- ARG DeltaY:WORD, \\r
- DeltaX:WORD = ARG_SIZE\r
- .enter 0\r
- .push ds\r
-\r
- mov ds, [mx_CodeSegment]\r
- ASSUME ds:MX_TEXT\r
-\r
- mov ax, [DeltaX]\r
- mov [mx_DeltaX], ax\r
- mov ax, [DeltaY]\r
- mov [mx_DeltaY], ax\r
-\r
- .pop ds\r
- .leave ARG_SIZE\r
-mxSetTextStep ENDP\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Gets the current distance between characters.\r
-;\r
-; Input:\r
-; DeltaX = pointer to horizontal distance in pixels (integer)\r
-; DeltaY = pointer to vertical distance in pixels (integer)\r
-; Output:\r
-; none\r
-;\r
-mxGetTextStep PROC FAR\r
- ARG DeltaY:DWORD, \\r
- DeltaX:DWORD = ARG_SIZE\r
- .enter 0\r
- .push ds, si\r
- ASSUME ds:NOTHING\r
-\r
- mov ax, [mx_DeltaX]\r
- lds si, [DeltaX]\r
- mov ds:[si], ax\r
- mov ax, [mx_DeltaY]\r
- lds si, [DeltaY]\r
- mov ds:[si], ax\r
-\r
- .pop ds, si\r
- .leave ARG_SIZE\r
-mxGetTextStep ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXPB.ASM - Scan buffer for convex polygon fills\r
-; Copyright (c) 1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-NOWARN RES\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mx_ScanBuffer\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-ALIGN 4\r
-\r
-mx_ScanBuffer LABEL\r
- DW POLYSCANBUFSIZE DUP(?)\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXPG.ASM - Convex polygon fill\r
-; Copyright (c) 1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-NOWARN RES\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxFillPoly\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; "Local" definitions\r
-;\r
-TPOINT STRUC\r
- X DW ?\r
- Y DW ?\r
-TPOINT ENDS\r
-\r
-; Do NOT change order!\r
-TSCAN STRUC\r
- Y1 DW ?\r
- Y2 DW ?\r
-TSCAN ENDS\r
-\r
-MAXSCANCOLUMNS EQU POLYSCANBUFSIZE / SIZE TSCAN\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-EXTRN mx_VideoSegment : WORD\r
-EXTRN mx_CodeSegment : WORD\r
-EXTRN mx_BytesPerLine : WORD\r
-EXTRN mx_ClipX1 : WORD\r
-EXTRN mx_ClipY1 : WORD\r
-EXTRN mx_ClipX2 : WORD\r
-EXTRN mx_ClipY2 : WORD\r
-EXTRN mx_ScanBuffer : NEAR\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Scans an edge using the DDA (digital differential analyzer) algorithm.\r
-;\r
-; Input:\r
-; DS:BX = pointer to start point (X1, Y1)\r
-; DS:SI = pointer to end point (X2, Y2)\r
-; ES:DI = pointer to edge buffer\r
-; Output:\r
-; ES:DI = updated pointer to edge buffer\r
-; Notes:\r
-; must preserve DS:SI.\r
-;\r
-subScan PROC NEAR\r
- mov cx, ds:[si].X\r
- sub cx, ds:[bx].X ; Get width\r
- jg @@1\r
- ret\r
-@@1:\r
- push bp ; Save BP\r
-\r
- mov ax, ds:[si].Y\r
- mov bx, ds:[bx].Y\r
- sub ax, bx ; Get height\r
- jg @@T2B ; Scan top to bottom\r
- jl @@B2T ; Scan bottom to top\r
-\r
-; Special case: vertical line\r
- mov ax, bx\r
-@@V:\r
- mov es:[di].Y1, ax\r
- add di, SIZE TSCAN\r
- dec cx\r
- jnz @@V\r
- jmp @@Exit\r
-\r
-; Scan top to bottom\r
-@@T2B:\r
- cwd\r
- div cx\r
- mov bp, ax\r
- xor ax, ax\r
- div cx\r
- xchg ax, bx ; BP:BX = fixed 16:16 step\r
- mov dx, 8000h\r
-@@T2BLoop:\r
- mov es:[di].Y1, ax\r
- add di, SIZE TSCAN\r
- add dx, bx\r
- adc ax, bp\r
- dec cx\r
- jnz @@T2BLoop\r
- jmp @@Exit\r
-\r
-; Scan bottom to top\r
-@@B2T:\r
- neg ax\r
- cwd\r
- div cx\r
- mov bp, ax\r
- xor ax, ax\r
- div cx\r
- xchg ax, bx\r
- mov dx, 8000h\r
-@@B2TLoop:\r
- mov es:[di].Y1, ax\r
- add di, SIZE TSCAN\r
- sub dx, bx\r
- sbb ax, bp\r
- dec cx\r
- jnz @@B2TLoop\r
-\r
-@@Exit:\r
- pop bp ; Restore BP\r
- ret\r
-subScan ENDP\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Fills a convex polygon with the specified color.\r
-;\r
-; Input:\r
-; Count = number of vertexes\r
-; Map = indexes of points and colors (integer)\r
-; Points = array of points (integer X, Y coordinates)\r
-; Color = base color\r
-; Output:\r
-; none\r
-; Notes:\r
-; vertexes must be in counterclockwise order, arrays are 0-based.\r
-;\r
-mxFillPoly PROC FAR\r
- ARG Color:WORD, \\r
- Points:DWORD, \\r
- Map:DWORD, \\r
- Count:WORD = ARG_SIZE\r
- LOCAL WritePlane:BYTE:2, \\r
- ScanOffsetT:WORD, \\r
- ScanOffsetB:WORD, \\r
- ScanCount:WORD, \\r
- Holder:WORD, \\r
- Height:WORD, \\r
- MinIdxT:WORD, \\r
- MinIdxB:WORD, \\r
- MaxIdx:WORD, \\r
- Width:WORD, \\r
- BoxX1:WORD, \\r
- BoxY1:WORD, \\r
- BoxX2:WORD, \\r
- BoxY2::WORD = AUTO_SIZE\r
- .enter AUTO_SIZE\r
- .push ds, si, es, di\r
- ASSUME ds:NOTHING\r
-\r
-; Check that at least three vertexes are specified\r
- mov cx, [Count]\r
- cmp cx, 3\r
- jb @@Exit\r
-\r
-;------------------------------\r
-; Find bounding box for polygon\r
- les di, [Map]\r
- lds si, [Points] ; Pointer to vertex array\r
- mov [BoxX1], 32767\r
- mov [BoxX2], -32768\r
- mov [BoxY1], 32767\r
- mov [BoxY2], -32768\r
-\r
- xor dx, dx\r
-@@MinMaxLoop:\r
- mov bx, es:[di] ; Get index of vertex\r
- .shl bx, 2 ; Get offset in point array\r
- add bx, si\r
-\r
-; Check X range\r
-@@CheckMinX:\r
- mov ax, ds:[bx].X ; Get X coordinate\r
- cmp ax, [BoxX1]\r
- jge @@CheckMaxX\r
- mov [BoxX1], ax\r
- mov [MinIdxT], dx\r
- mov [MinIdxB], dx\r
-@@CheckMaxX:\r
- cmp ax, [BoxX2]\r
- jle @@CheckMinY\r
- mov [BoxX2], ax\r
- mov [MaxIdx], dx\r
-\r
-; Check Y range\r
-@@CheckMinY:\r
- mov ax, ds:[bx].Y\r
- cmp ax, [BoxY1]\r
- jge @@CheckMaxY\r
- mov [BoxY1], ax\r
-@@CheckMaxY:\r
- cmp ax, [BoxY2]\r
- jle @@CheckDone\r
- mov [BoxY2], ax\r
-\r
-; Repeat thru all points\r
-@@CheckDone:\r
- inc di ; Next map entry\r
- inc dx\r
- inc di\r
- inc dx\r
- dec cx\r
- jnz @@MinMaxLoop\r
-\r
-;---------------------------------\r
-; Check if polygon is full clipped\r
- mov ax, [BoxX2]\r
- cmp ax, [mx_ClipX1] ; Is poly full clipped?\r
- jl @@Exit\r
- mov bx, [BoxX1]\r
- cmp bx, [mx_ClipX2] ; Is poly full clipped?\r
- jg @@Exit\r
- sub ax, bx ; Get width\r
- jle @@Exit ; Exit if not positive\r
- mov ax, [BoxY2]\r
- cmp ax, [mx_ClipY1] ; Is poly full clipped?\r
- jl @@Exit\r
- mov bx, [BoxY1]\r
- cmp bx, [mx_ClipY2] ; Is poly full clipped?\r
- jg @@Exit\r
- sub ax, bx ; Get height\r
- jle @@Exit ; Exit if not positive\r
-\r
- dec [Count]\r
- shl [Count], 1 ; We'll work with word offsets\r
- mov es, [mx_CodeSegment]\r
-\r
-;--------------\r
-; Scan top edge\r
- mov ax, OFFSET mx_ScanBuffer\r
- mov [ScanOffsetT], ax\r
- mov si, [MinIdxT] ; Offset of bottom point index\r
-@@STLoop:\r
- lds bx, [Map] ; DS:BX -> map table\r
- mov di, ds:[bx+si] ; Index of top point #1\r
- dec si ; Next point\r
- dec si\r
- test si, si\r
- jnl @@ST1\r
- mov si, [Count]\r
-@@ST1:\r
- mov [MinIdxT], si ; Save new index of top point\r
- mov si, ds:[bx+si] ; Get index of top point #2\r
- .shl di, 2 ; Convert indexes to offsets\r
- .shl si, 2\r
- lds bx, [Points] ; DS:BX -> point array\r
- add si, bx ; DS:SI -> top point #2\r
- add bx, di ; DS:BX -> top point #1\r
- mov di, [ScanOffsetT]\r
- call subScan ; Scan edge\r
- mov [ScanOffsetT], di\r
- mov si, [MinIdxT]\r
- cmp si, [MaxIdx] ; End of edge?\r
- jne @@STLoop ; No, continue\r
-\r
-;-----------------\r
-; Scan bottom edge\r
- mov ax, OFFSET mx_ScanBuffer + OFFSET Y2\r
- mov [ScanOffsetB], ax\r
- mov si, [MinIdxB] ; Offset of bottom point index\r
-@@SBLoop:\r
- lds bx, [Map] ; DS:BX -> map table\r
- mov di, ds:[bx+si] ; Index of bottom point #1\r
- inc si ; Next bottom point\r
- inc si\r
- cmp si, [Count]\r
- jbe @@SB1\r
- xor si, si\r
-@@SB1:\r
- mov [MinIdxB], si ; Save new index of bottom point\r
- mov si, ds:[bx+si] ; Get index of bottom point #2\r
- .shl di, 2 ; Convert indexes to offsets\r
- .shl si, 2\r
- lds bx, [Points] ; DS:BX -> point array\r
- add si, bx ; DS:SI -> top point #2\r
- add bx, di ; DS:BX -> top point #1\r
- mov di, [ScanOffsetB]\r
- call subScan ; Scan edge\r
- mov [ScanOffsetB], di\r
- mov si, [MinIdxB]\r
- cmp si, [MaxIdx] ; End of edge?\r
- jne @@SBLoop ; No, continue\r
-\r
-;--------------------\r
-; Clip left and right\r
- mov si, OFFSET mx_ScanBuffer\r
- mov ax, [BoxX1]\r
- mov cx, [BoxX2]\r
- sub cx, ax ; CX = bounding box width\r
- mov bx, [mx_ClipX1]\r
- sub bx, ax\r
- jle @@ClipL1 ; No need to clip left\r
- sub cx, bx ; Update width\r
- add ax, bx ; BoxX1 = mx_ClipX1\r
- mov [BoxX1], ax\r
- .shl bx, 2 ; Warning!!! This is an hand-coded\r
- add si, bx ; multiply by the size of TSCAN\r
-@@ClipL1:\r
- mov bx, ax\r
- add bx, cx ; Last scan column\r
- sub bx, [mx_ClipX2]\r
- jle @@ClipL2 ; No need to clip right\r
- sub cx, bx ; Clip right\r
-@@ClipL2:\r
- test cx, cx ; Is clipped width positive?\r
- jle @@Exit ; No, exit\r
- mov [ScanCount], cx ; Save number of columns to draw\r
- mov [ScanOffsetT], si ; Remember offset of (clipped) buffer\r
- mov ds, [mx_CodeSegment] ; DS:SI -> scan buffer\r
-\r
-;------------------------------\r
-; Check if Y clipping is needed\r
- mov ax, [BoxY1]\r
- cmp ax, [mx_ClipY1]\r
- jl @@ClipTB ; Need to clip top\r
- mov ax, [BoxY2]\r
- cmp ax, [mx_ClipY2]\r
- jg @@ClipTB ; Need to clip bottom\r
- jmp @@ClipYExit ; Skip Y clipping\r
-\r
-;--------------------\r
-; Clip top and bottom\r
-@@ClipTB:\r
- mov di, cx ; DI = scan count\r
- inc di ; Increment count for pre-loop test\r
- sub si, SIZE TSCAN\r
-@@ClipYLoop:\r
- dec di ; Any column left?\r
- jz @@ClipYExit ; No, exit\r
- add si, SIZE TSCAN\r
- mov ax, ds:[si].Y1 ; Y1\r
- mov cx, ds:[si].Y2 ; Y2\r
- mov dx, [mx_ClipY2]\r
- cmp ax, dx ; Full clipped?\r
- jg @@ClipYClip ; Yes, skip this column\r
- cmp cx, dx ; Need to clip bottom?\r
- jle @@ClipY1 ; No, continue\r
-; Clip bottom\r
- mov ds:[si].Y2, dx\r
- mov bx, cx\r
- sub bx, dx ; Clip distance\r
- sub cx, ax ; Height\r
- jle @@ClipYClip\r
- mov cx, ds:[si].Y2\r
-@@ClipY1:\r
- mov dx, [mx_ClipY1]\r
- cmp cx, dx ; Full top clipped?\r
- jl @@ClipYClip ; Yes, skip\r
- sub cx, ax ; Get height\r
- jle @@ClipYClip ; Skip if not positive\r
- cmp ax, dx ; Need to clip top?\r
- jge @@ClipYLoop ; No, continue\r
-; Clip top\r
- mov ds:[si].Y1, dx ; Y1 = mx_ClipY1\r
- sub dx, ax ; DX = number of pixels clipped\r
- cmp cx, dx\r
- ja @@ClipYLoop ; Not clipped, continue\r
-@@ClipYClip:\r
- mov ds:[si].Y1, -1 ; Mark column as clipped\r
- jmp @@ClipYLoop\r
-@@ClipYExit:\r
-\r
-;-------------\r
-; Draw columns\r
- mov es, [mx_VideoSegment]\r
- mov si, [ScanOffsetT]\r
- mov cl, BYTE PTR [BoxX1] ; Init write plane\r
- and cl, 03h\r
- mov al, 11h\r
- shl al, cl\r
- mov [WritePlane], al\r
- .shr [BoxX1], 2\r
-@@DrawLoop:\r
- mov ax, ds:[si].Y1\r
- test ax, ax ; Was column clipped?\r
- js @@DrawNext ; Yes, skip\r
- mov cx, ds:[si].Y2\r
- sub cx, ax ; CX = height\r
- jle @@DrawNext\r
- mul [mx_BytesPerLine] ; Get pixel address\r
- add ax, [BoxX1]\r
- mov di, ax\r
- mov ah, [WritePlane]\r
- mov dx, TS\r
- mov al, 02h\r
- out dx, ax\r
- mov ax, [Color]\r
- mov dx, [mx_BytesPerLine]\r
- shr cx, 1\r
- jnc @@FillScan\r
- mov es:[di], al\r
- add di, dx\r
- jcxz @@DrawNext\r
-@@FillScan:\r
- mov es:[di], al\r
- add di, dx\r
- mov es:[di], al\r
- add di, dx\r
- dec cx\r
- jnz @@FillScan\r
-@@DrawNext:\r
- rol [WritePlane], 1\r
- adc [BoxX1], 0 ; Bump pointer to video memory if needed\r
- add si, SIZE TSCAN\r
- dec [ScanCount]\r
- jnz @@DrawLoop\r
-\r
-@@Exit:\r
- xor ax, ax\r
- .pop ds, si, es, di\r
- .leave ARG_SIZE\r
-mxFillPoly ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXPG.ASM - Convex polygon fill with Gouraud shading\r
-; Copyright (c) 1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-NOWARN RES\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxGouraudPoly\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; "Local" definitions\r
-;\r
-TPOINT STRUC\r
- X DW ?\r
- Y DW ?\r
-TPOINT ENDS\r
-\r
-; Do NOT change order!\r
-TSCAN STRUC\r
- Y1 DW ?\r
- E1 DB ?\r
- C1 DB ?\r
- Y2 DW ?\r
- E2 DB ?\r
- C2 DB ?\r
-TSCAN ENDS\r
-\r
-MAXSCANCOLUMNS EQU POLYSCANBUFSIZE / SIZE TSCAN\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-EXTRN mx_VideoSegment : WORD\r
-EXTRN mx_CodeSegment : WORD\r
-EXTRN mx_BytesPerLine : WORD\r
-EXTRN mx_ClipX1 : WORD\r
-EXTRN mx_ClipY1 : WORD\r
-EXTRN mx_ClipX2 : WORD\r
-EXTRN mx_ClipY2 : WORD\r
-EXTRN mx_ScanBuffer : NEAR\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Scans an edge using the DDA (digital differential analyzer) algorithm.\r
-; Also interpolates color for shading.\r
-;\r
-; Input:\r
-; DS:BX = pointer to start point (X1, Y1)\r
-; DS:SI = pointer to end point (X2, Y2)\r
-; ES:DI = pointer to edge buffer\r
-; DX = start color\r
-; AX = end color\r
-; Output:\r
-; ES:DI = updated pointer to edge buffer\r
-; Notes:\r
-; must preserve DS:SI.\r
-;\r
-subScan PROC NEAR\r
- mov cx, ds:[si].X\r
- sub cx, ds:[bx].X ; Get width\r
- jg @@1\r
- ret\r
-@@1:\r
- push bp ; Save BP\r
- push di ; Save scan info offset\r
- push cx ; Save height\r
- push ax ; Save colors\r
- push dx\r
-\r
- mov ax, ds:[si].Y\r
- mov bx, ds:[bx].Y\r
- sub ax, bx ; Get height\r
- jg @@T2B ; Scan top to bottom\r
- jl @@B2T ; Scan bottom to top\r
-\r
-; Special case: vertical line\r
- mov ax, bx\r
-@@V:\r
- mov es:[di].Y1, ax\r
- add di, SIZE TSCAN\r
- dec cx\r
- jnz @@V\r
- jmp @@GetColorInfo\r
-\r
-; Scan top to bottom\r
-@@T2B:\r
- cwd\r
- div cx\r
- mov bp, ax\r
- xor ax, ax\r
- div cx\r
- xchg ax, bx ; BP:BX = fixed 16:16 step\r
- mov dx, 8000h\r
-@@T2BLoop:\r
- mov es:[di].Y1, ax\r
- add di, SIZE TSCAN\r
- add dx, bx\r
- adc ax, bp\r
- dec cx\r
- jnz @@T2BLoop\r
- jmp @@GetColorInfo\r
-\r
-; Scan bottom to top\r
-@@B2T:\r
- neg ax\r
- cwd\r
- div cx\r
- mov bp, ax\r
- xor ax, ax\r
- div cx\r
- xchg ax, bx\r
- mov dx, 8000h\r
-@@B2TLoop:\r
- mov es:[di].Y1, ax\r
- add di, SIZE TSCAN\r
- sub dx, bx\r
- sbb ax, bp\r
- dec cx\r
- jnz @@B2TLoop\r
-\r
-; Now get the color info\r
-@@GetColorInfo:\r
- pop bx ; Restore colors\r
- pop ax\r
- pop cx ; Height\r
- pop di ; ES:DI -> scan info\r
-\r
- sub ax, bx ; Get color range\r
- jg @@CL2R\r
- jl @@CR2L\r
-\r
-; Special case: same color\r
- mov ah, bl\r
- mov al, 80h\r
-@@CV:\r
- mov WORD PTR es:[di].E1, ax\r
- add di, SIZE TSCAN\r
- dec cx\r
- jnz @@CV\r
- jmp @@Exit\r
-\r
-; Scan left to right\r
-@@CL2R:\r
- cwd\r
- div cx\r
- mov bp, ax\r
- xor ax, ax\r
- div cx\r
- xchg ax, bx ; BP:BX = fixed 16:16 step\r
- mov dx, 8000h\r
-@@CL2RLoop:\r
- mov es:[di].C1, al\r
- mov es:[di].E1, dh\r
- add di, SIZE TSCAN\r
- add dx, bx\r
- adc ax, bp\r
- dec cx\r
- jnz @@CL2RLoop\r
- jmp @@Exit\r
-\r
-; Scan right to left\r
-@@CR2L:\r
- neg ax\r
- cwd\r
- div cx\r
- mov bp, ax\r
- xor ax, ax\r
- div cx\r
- xchg ax, bx\r
- mov dx, 8000h\r
-\r
-@@CR2LLoop:\r
- mov es:[di].C1, al\r
- mov es:[di].E1, dh\r
- add di, SIZE TSCAN\r
- sub dx, bx\r
- sbb ax, bp\r
- dec cx\r
- jnz @@CR2LLoop\r
-\r
-@@Exit:\r
- pop bp\r
- ret\r
-subScan ENDP\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Fills a scan column.\r
-;\r
-; Input:\r
-; DS:SI = current TSCAN\r
-; ES:DI = address of top pixel\r
-; CX = number of pixels to write\r
-; DX = base color\r
-; Output:\r
-; none\r
-;\r
-subFillScan PROC NEAR\r
- mov ax, WORD PTR ds:[si].E2\r
- mov bx, WORD PTR ds:[si].E1\r
- cmp ah, bh\r
- jg @@L2R ; Color increases\r
- jl @@R2L ; Color decreases\r
-\r
-; Special case: color doesn't change\r
- add ax, dx\r
- mov dx, [mx_BytesPerLine]\r
-@@V:\r
- mov es:[di], ah\r
- add di, dx\r
- dec cx\r
- jnz @@V\r
- ret\r
-\r
-; Color increases\r
-@@L2R:\r
- .push bp, si\r
- mov si, bx\r
- add si, dx ; Relocate color\r
- sub ax, bx\r
- xor dx, dx\r
- div cx\r
- mov bp, ax ; BP = color step, integer part\r
- xor ax, ax\r
- div cx\r
- mov bx, ax ; BX = color step, fractional part\r
- mov dx, 8000h\r
- mov ax, [mx_BytesPerLine]\r
- xchg si, ax\r
-@@L2RLoop:\r
- mov es:[di], ah\r
- add dx, bx\r
- adc ax, bp\r
- add di, si\r
- dec cx\r
- jnz @@L2RLoop\r
- .pop bp, si\r
- ret\r
-\r
-; Color decreases\r
-@@R2L:\r
- .push bp, si\r
- mov si, bx\r
- add si, dx ; Relocate color\r
- sub ax, bx\r
- neg ax\r
- xor dx, dx\r
- div cx\r
- mov bp, ax ; BP = color step, integer part\r
- xor ax, ax\r
- div cx\r
- mov bx, ax ; BX = color step, fractional part\r
- mov dx, 8000h\r
- mov ax, [mx_BytesPerLine]\r
- xchg si, ax\r
-@@R2LLoop:\r
- mov es:[di], ah\r
- sub dx, bx\r
- sbb ax, bp\r
- add di, si\r
- dec cx\r
- jnz @@R2LLoop\r
- .pop bp, si\r
- ret\r
-subFillScan ENDP\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Fills a convex polygon with the specified color.\r
-; Interpolates pixel colors using the Gouraud algorithm.\r
-;\r
-; Input:\r
-; Count = number of vertexes\r
-; Map = indexes of points and colors (integer)\r
-; Points = array of points (integer X, Y coordinates)\r
-; Colors = array of colors (integer)\r
-; Color = base color\r
-; Output:\r
-; none\r
-; Notes:\r
-; vertexes must be in counterclockwise order, arrays are 0-based.\r
-;\r
-mxGouraudPoly PROC FAR\r
- ARG Color:WORD, \\r
- Colors:DWORD, \\r
- Points:DWORD, \\r
- Map:DWORD, \\r
- Count:WORD = ARG_SIZE\r
- LOCAL WritePlane:BYTE:2, \\r
- ScanOffsetT:WORD, \\r
- ScanOffsetB:WORD, \\r
- ScanCount:WORD, \\r
- Holder:WORD, \\r
- Height:WORD, \\r
- MinIdxT:WORD, \\r
- MinIdxB:WORD, \\r
- MaxIdx:WORD, \\r
- Width:WORD, \\r
- BoxX1:WORD, \\r
- BoxY1:WORD, \\r
- BoxX2:WORD, \\r
- BoxY2::WORD = AUTO_SIZE\r
- .enter AUTO_SIZE\r
- .push ds, si, es, di\r
- ASSUME ds:NOTHING\r
-\r
-; Check that at least three vertexes are specified\r
- mov cx, [Count]\r
- cmp cx, 3\r
- jb @@Exit\r
-\r
-;------------------------------\r
-; Find bounding box for polygon\r
- les di, [Map]\r
- lds si, [Points] ; Pointer to vertex array\r
- mov [BoxX1], 32767\r
- mov [BoxX2], -32768\r
- mov [BoxY1], 32767\r
- mov [BoxY2], -32768\r
-\r
- xor dx, dx\r
-@@MinMaxLoop:\r
- mov bx, es:[di] ; Get index of vertex\r
- .shl bx, 2 ; Get offset in point array\r
- add bx, si\r
-\r
-; Check X range\r
-@@CheckMinX:\r
- mov ax, ds:[bx].X ; Get X coordinate\r
- cmp ax, [BoxX1]\r
- jge @@CheckMaxX\r
- mov [BoxX1], ax\r
- mov [MinIdxT], dx\r
- mov [MinIdxB], dx\r
-@@CheckMaxX:\r
- cmp ax, [BoxX2]\r
- jle @@CheckMinY\r
- mov [BoxX2], ax\r
- mov [MaxIdx], dx\r
-\r
-; Check Y range\r
-@@CheckMinY:\r
- mov ax, ds:[bx].Y\r
- cmp ax, [BoxY1]\r
- jge @@CheckMaxY\r
- mov [BoxY1], ax\r
-@@CheckMaxY:\r
- cmp ax, [BoxY2]\r
- jle @@CheckDone\r
- mov [BoxY2], ax\r
-\r
-; Repeat thru all points\r
-@@CheckDone:\r
- inc di ; Next map entry\r
- inc di\r
- inc dx\r
- inc dx\r
- dec cx\r
- jnz @@MinMaxLoop\r
-\r
-;---------------------------------\r
-; Check if polygon is full clipped\r
- mov ax, [BoxX2]\r
- cmp ax, [mx_ClipX1] ; Is poly full clipped?\r
- jl @@Exit\r
- mov bx, [BoxX1]\r
- cmp bx, [mx_ClipX2] ; Is poly full clipped?\r
- jg @@Exit\r
- sub ax, bx ; Get width\r
- jle @@Exit ; Exit if not positive\r
- mov ax, [BoxY2]\r
- cmp ax, [mx_ClipY1] ; Is poly full clipped?\r
- jl @@Exit\r
- mov bx, [BoxY1]\r
- cmp bx, [mx_ClipY2] ; Is poly full clipped?\r
- jg @@Exit\r
- sub ax, bx ; Get height\r
- jle @@Exit ; Exit if not positive\r
-\r
- dec [Count]\r
- shl [Count], 1 ; We'll work with word offsets\r
- mov es, [mx_CodeSegment]\r
-\r
-;--------------\r
-; Scan top edge\r
- mov ax, OFFSET mx_ScanBuffer\r
- mov [ScanOffsetT], ax\r
- mov si, [MinIdxT] ; Offset of bottom point index\r
-@@STLoop:\r
- lds bx, [Map] ; DS:BX -> map table\r
- mov di, ds:[bx+si] ; Index of top point #1\r
- dec si ; Next point\r
- dec si\r
- test si, si\r
- jnl @@ST1\r
- mov si, [Count]\r
-@@ST1:\r
- mov [MinIdxT], si ; Save new index of top point\r
- mov si, ds:[bx+si] ; Get index of top point #2\r
- lds bx, [Colors] ; Get pointer to color array\r
- shl di, 1 ; Convert indexes to offsets\r
- shl si, 1\r
- mov ax, ds:[bx+si] ; Get colors\r
- mov dx, ds:[bx+di]\r
- lds bx, [Points] ; DS:BX -> point array\r
- shl si, 1\r
- shl di, 1\r
- add si, bx ; DS:SI -> top point #2\r
- add bx, di ; DS:BX -> top point #1\r
- mov di, [ScanOffsetT]\r
- call subScan ; Scan edge\r
- mov [ScanOffsetT], di\r
- mov si, [MinIdxT]\r
- cmp si, [MaxIdx] ; End of edge?\r
- jne @@STLoop ; No, continue\r
-\r
-;-----------------\r
-; Scan bottom edge\r
- mov ax, OFFSET mx_ScanBuffer + OFFSET Y2\r
- mov [ScanOffsetB], ax\r
- mov si, [MinIdxB] ; Offset of bottom point index\r
-@@SBLoop:\r
- lds bx, [Map] ; DS:BX -> map table\r
- mov di, ds:[bx+si] ; Index of bottom point #1\r
- inc si ; Next bottom point\r
- inc si\r
- cmp si, [Count]\r
- jbe @@SB1\r
- xor si, si\r
-@@SB1:\r
- mov [MinIdxB], si ; Save new index of bottom point\r
- mov si, ds:[bx+si] ; Get index of bottom point #2\r
- lds bx, [Colors] ; Get pointer to color array\r
- shl di, 1 ; Convert indexes to offsets\r
- shl si, 1\r
- mov ax, ds:[bx+si] ; Get colors\r
- mov dx, ds:[bx+di]\r
- lds bx, [Points] ; DS:BX -> point array\r
- shl si, 1\r
- shl di, 1\r
- add si, bx ; DS:SI -> top point #2\r
- add bx, di ; DS:BX -> top point #1\r
- mov di, [ScanOffsetB]\r
- call subScan ; Scan edge\r
- mov [ScanOffsetB], di\r
- mov si, [MinIdxB]\r
- cmp si, [MaxIdx] ; End of edge?\r
- jne @@SBLoop ; No, continue\r
-\r
-;--------------------\r
-; Clip left and right\r
- mov si, OFFSET mx_ScanBuffer\r
- mov ax, [BoxX1]\r
- mov cx, [BoxX2]\r
- sub cx, ax ; CX = bounding box width\r
- mov bx, [mx_ClipX1]\r
- sub bx, ax\r
- jle @@ClipL1 ; No need to clip left\r
- sub cx, bx ; Update width\r
- add ax, bx ; BoxX1 = mx_ClipX1\r
- mov [BoxX1], ax\r
- .shl bx, 3 ; Warning!!! This is an hand-coded\r
- add si, bx ; multiply by the size of TSCAN\r
-@@ClipL1:\r
- mov bx, ax\r
- add bx, cx ; Last scan column\r
- sub bx, [mx_ClipX2]\r
- jle @@ClipL2 ; No need to clip right\r
- sub cx, bx ; Clip right\r
-@@ClipL2:\r
- test cx, cx ; Is clipped width positive?\r
- jle @@Exit ; No, exit\r
- mov [ScanCount], cx ; Save number of columns to draw\r
- mov [ScanOffsetT], si ; Remember offset of (clipped) buffer\r
- mov ds, [mx_CodeSegment] ; DS:SI -> scan buffer\r
-\r
-;------------------------------\r
-; Check if Y clipping is needed\r
- mov ax, [BoxY1]\r
- cmp ax, [mx_ClipY1]\r
- jl @@ClipTB ; Need to clip top\r
- mov ax, [BoxY2]\r
- cmp ax, [mx_ClipY2]\r
- jg @@ClipTB ; Need to clip bottom\r
- jmp @@ClipYExit ; Skip Y clipping\r
-\r
-;--------------------\r
-; Clip top and bottom\r
-@@ClipTB:\r
- mov di, cx ; DI = scan count\r
- inc di ; Increment count for pre-loop test\r
- sub si, SIZE TSCAN\r
-@@ClipYLoop:\r
- dec di ; Any column left?\r
- jz @@ClipYExit ; No, exit\r
- add si, SIZE TSCAN\r
- mov ax, ds:[si].Y1 ; Y1\r
- mov cx, ds:[si].Y2 ; Y2\r
- mov dx, [mx_ClipY2]\r
- cmp ax, dx ; Full clipped?\r
- jg @@ClipYClip ; Yes, skip this column\r
- cmp cx, dx ; Need to clip bottom?\r
- jle @@ClipY1 ; No, continue\r
-; Clip bottom, need to scale colors too\r
- mov ds:[si].Y2, dx\r
- mov bx, cx\r
- sub bx, dx ; Clip distance\r
- sub cx, ax ; Height\r
- jle @@ClipYClip\r
- mov ax, WORD PTR ds:[si].E1\r
- sub ax, WORD PTR ds:[si].E2\r
- imul bx\r
- idiv cx\r
- add WORD PTR ds:[si].E2, ax\r
- mov ax, ds:[si].Y1 ; Restore AX and CX\r
- mov cx, ds:[si].Y2\r
-@@ClipY1:\r
- mov dx, [mx_ClipY1]\r
- cmp cx, dx ; Full top clipped?\r
- jl @@ClipYClip ; Yes, skip\r
- sub cx, ax ; Get height\r
- jle @@ClipYClip ; Skip if not positive\r
- cmp ax, dx ; Need to clip top?\r
- jge @@ClipYLoop ; No, continue\r
-; Clip top, need to scale colors too\r
- mov ds:[si].Y1, dx ; Y1 = mx_ClipY1\r
- sub dx, ax ; DX = number of pixels clipped\r
- cmp cx, dx\r
- jbe @@ClipYClip ; Full clipped, skip\r
- mov ax, WORD PTR ds:[si].E2\r
- sub ax, WORD PTR ds:[si].E1 ; AX = color distance\r
- imul dx\r
- idiv cx\r
- add WORD PTR ds:[si].E1, ax ; Update starting color\r
- jmp @@ClipYLoop\r
-@@ClipYClip:\r
- mov ds:[si].Y1, -1 ; Mark column as clipped\r
- jmp @@ClipYLoop\r
-@@ClipYExit:\r
-\r
-;-------------\r
-; Draw columns\r
- mov es, [mx_VideoSegment]\r
- mov si, [ScanOffsetT]\r
- mov cl, BYTE PTR [BoxX1] ; Init write plane\r
- and cl, 03h\r
- mov al, 11h\r
- shl al, cl\r
- mov [WritePlane], al\r
- .shr [BoxX1], 2\r
- mov ax, [Color] ; Make 8:8 fixed color\r
- mov ah, al\r
- xor al, al\r
- mov [Color], ax\r
-@@DrawLoop:\r
- mov ax, ds:[si].Y1\r
- test ax, ax ; Was column clipped?\r
- js @@DrawNext ; Yes, skip\r
- mov cx, ds:[si].Y2\r
- sub cx, ax ; CX = height\r
- jle @@DrawNext\r
- mul [mx_BytesPerLine] ; Get pixel address\r
- add ax, [BoxX1]\r
- mov di, ax\r
- mov ah, [WritePlane]\r
- mov al, 02h\r
- mov dx, TS\r
- out dx, ax\r
- mov dx, [Color]\r
- call subFillScan\r
-@@DrawNext:\r
- rol [WritePlane], 1\r
- adc [BoxX1], 0 ; Bump pointer to video memory if needed\r
- add si, SIZE TSCAN\r
- dec [ScanCount]\r
- jnz @@DrawLoop\r
-\r
-@@Exit:\r
- xor ax, ax\r
- .pop ds, si, es, di\r
- .leave ARG_SIZE\r
-mxGouraudPoly ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXPI.ASM - Put image\r
-; Copyright (c) 1993,1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-NOWARN RES\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxPutImage\r
-\r
-EXTRN subClipImage : NEAR\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-EXTRN mx_VideoSegment : WORD\r
-EXTRN mx_BytesPerLine : WORD\r
-\r
-mxTable LABEL WORD ; Raster ops\r
- DW subMove\r
- DW subAnd\r
- DW subOr\r
- DW subXor\r
- DW subTrans\r
- DW subAdd\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Move functions.\r
-; Note: loops unrolled and optimized for CX even, no check for CX = 0.\r
-;\r
-subMove PROC NEAR\r
- shr cx, 1 ; Make CX even\r
- jc @@Odd ; Special case if odd byte\r
-@@Loop: movsb\r
- add si, 3\r
- movsb\r
- add si, 3\r
- dec cx\r
- jnz @@Loop\r
-@@Exit: ret\r
-@@Odd: movsb\r
- add si, 3\r
- jcxz @@Exit\r
- jmp @@Loop\r
-subMove ENDP\r
-;\r
-subAnd PROC NEAR\r
- shr cx, 1\r
- jc @@Odd\r
-@@Loop: mov al, ds:[si]\r
- mov ah, ds:[si+4]\r
- and es:[di], ax\r
- inc di\r
- inc di\r
- add si, 8\r
- dec cx\r
- jnz @@Loop\r
-@@Exit: ret\r
-@@Odd: lodsb\r
- and es:[di], al\r
- inc di\r
- add si, 3\r
- jcxz @@Exit\r
- jmp @@Loop\r
-subAnd ENDP\r
-;\r
-subOr PROC NEAR\r
- shr cx, 1\r
- jc @@Odd\r
-@@Loop: mov al, ds:[si]\r
- mov ah, ds:[si+4]\r
- or es:[di], ax\r
- inc di\r
- inc di\r
- add si, 8\r
- dec cx\r
- jnz @@Loop\r
-@@Exit: ret\r
-@@Odd: lodsb\r
- or es:[di], al\r
- inc di\r
- add si, 3\r
- jcxz @@Exit\r
- jmp @@Loop\r
-subOr ENDP\r
-;\r
-subXor PROC NEAR\r
- shr cx, 1\r
- jc @@Odd\r
-@@Loop: mov al, ds:[si]\r
- mov ah, ds:[si+4]\r
- xor es:[di], ax\r
- inc di\r
- inc di\r
- add si, 8\r
- dec cx\r
- jnz @@Loop\r
-@@Exit: ret\r
-@@Odd: lodsb\r
- xor es:[di], al\r
- inc di\r
- add si, 3\r
- jcxz @@Exit\r
- jmp @@Loop\r
-subXor ENDP\r
-;\r
-subTrans PROC NEAR\r
-@@Loop: mov al, ds:[si]\r
- cmp al, ah\r
- je @@Skip\r
- mov es:[di], al\r
-@@Skip: inc di\r
- add si, 4\r
- dec cx\r
- jnz @@Loop\r
-@@Exit: ret\r
-subTrans ENDP\r
-;\r
-subAdd PROC NEAR\r
-@@Loop: mov al, ds:[si]\r
- add es:[di], al\r
- inc di\r
- add si, 4\r
- dec cx\r
- jnz @@Loop\r
- ret\r
-subAdd ENDP\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Copies a "raw" image from memory to screen.\r
-;\r
-; Input:\r
-; Image = pointer to image\r
-; X, Y = coordinates of destination\r
-; Width = width of image in pixels\r
-; Height = height of image in pixels\r
-; Op = raster op (OP_xxx)\r
-; Output:\r
-; none\r
-;\r
-mxPutImage PROC FAR\r
- ARG Op:WORD, \\r
- Height:WORD, \\r
- Width:WORD, \\r
- Y:WORD, \\r
- X:WORD, \\r
- Image:DWORD = ARG_SIZE\r
- LOCAL PlaneWidth:WORD:4, \\r
- PixelOffset:WORD, \\r
- MoveFunction:WORD, \\r
- Count:BYTE, \\r
- ReadPlane:BYTE, \\r
- OpInfo:BYTE, \\r
- WritePlane:BYTE = AUTO_SIZE\r
- ASSUME ds:NOTHING\r
- .enter AUTO_SIZE\r
- .push ds, si, es, di\r
-\r
-; Clip image\r
- mov bx, [X]\r
- mov ax, [Y]\r
- mov cx, [Width]\r
- mov dx, [Height]\r
- call subClipImage\r
- jc @@Exit ; Full clipped\r
- mov [Height], dx\r
- add WORD PTR Image[0], si ; Skip clipped pixels\r
-\r
-; Get pixel address\r
- mul [mx_BytesPerLine]\r
- mov di, bx\r
- shr di, 1\r
- shr di, 1\r
- add di, ax\r
- mov [PixelOffset], di\r
- mov es, [mx_VideoSegment] ; ES:DI points to pixel\r
- and bl, 03h\r
- mov [ReadPlane], bl\r
-\r
-; Compute extra bytes and width count for each plane\r
- mov bx, cx\r
- shr bx, 1\r
- shr bx, 1 ; Width for each plane\r
- and cl, 03h\r
- mov al, 00001000b\r
- shr al, cl\r
- mov si, 3 SHL 1\r
-@@PatchLoop:\r
- mov PlaneWidth[si], bx\r
- shr al, 1\r
- adc bx, 0\r
- dec si\r
- dec si\r
- jge @@PatchLoop\r
-\r
-; Setup planes for output to VGA registers\r
- mov cl, [ReadPlane]\r
- mov al, 00010001b\r
- shl al, cl\r
- mov [WritePlane], al\r
-\r
-; Install move function\r
- mov bx, [Op]\r
- mov [OpInfo], bh ; Remember additional info if needed\r
- xor bh, bh\r
- cmp bl, OP_ADD\r
- jbe @@SetMoveFunction\r
- xor bl, bl\r
-@@SetMoveFunction:\r
- shl bx, 1\r
- mov ax, mxTable[bx]\r
- mov [MoveFunction], ax\r
-\r
-; Put image\r
- cld\r
- mov [Count], 4 ; Four planes\r
- lea bx, PlaneWidth ; SS:[BX] = width in bytes for plane\r
- mov ds, WORD PTR Image[2]\r
-@@PlaneLoop:\r
- cmp WORD PTR ss:[bx], 0 ; Exit if nothing more to do\r
- je @@Exit ; (also, never try to move zero bytes!)\r
- mov si, WORD PTR Image[0]\r
- mov ah, [WritePlane]\r
- and ah, 0Fh\r
- mov al, 02h\r
- mov dx, TS\r
- out dx, ax ; Select write plane\r
- mov ah, [ReadPlane]\r
- and ah, 03h\r
- mov al, 04h\r
- mov dx, GDC\r
- out dx, ax ; Select read plane\r
- mov dx, [Height]\r
- mov di, [PixelOffset]\r
-@@Loop:\r
- push si\r
- push di\r
- mov cx, WORD PTR ss:[bx] ; Number of bytes to move\r
- mov ah, [OpInfo] ; Transparent color for subTrans\r
- call [MoveFunction]\r
- pop di\r
- pop si\r
- add si, [Width] ; Go to next image line\r
- add di, [mx_BytesPerLine] ; Go to next screen row\r
- dec dx\r
- jnz @@Loop ; Repeat for all lines\r
- inc bx\r
- inc bx ; Select width for next plane\r
- inc [ReadPlane]\r
- rol [WritePlane], 1\r
- adc [PixelOffset], 0\r
- inc WORD PTR Image[0]\r
- dec [Count]\r
- jnz @@PlaneLoop ; Repeat for all planes\r
-\r
-@@Exit:\r
- xor ax, ax\r
- .pop ds, si, es, di\r
- .leave ARG_SIZE\r
-mxPutImage ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXPN.ASM - Panning function\r
-; Copyright (c) 1993,1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxPan\r
-\r
-EXTRN mxWaitDisplay : FAR\r
-EXTRN mxStartAddress : FAR\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-EXTRN mx_BytesPerLine : WORD\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Moves the screen.\r
-;\r
-; Input:\r
-; X, Y = new X, Y coordinates of view screen\r
-; Output:\r
-; none\r
-;\r
-mxPan PROC FAR\r
- ARG Y:WORD, \\r
- X:WORD = ARG_SIZE\r
- ASSUME ds:NOTHING\r
- .enter 0\r
-\r
- mov ax, [Y]\r
- mul [mx_BytesPerLine]\r
- mov dx, [X]\r
- shr dx, 1\r
- shr dx, 1\r
- add ax, dx\r
- push ax ; Push the start address\r
- call mxWaitDisplay\r
- call mxStartAddress\r
-\r
- mov dx, 03DAh ; Set the pixel pan register\r
- in al, dx\r
- mov dx, 03C0h\r
- mov al, 33h\r
- out dx, al\r
- mov al, BYTE PTR [X]\r
- and al, 3\r
- shl al, 1\r
- out dx, al\r
-\r
- xor ax, ax\r
- .leave ARG_SIZE\r
-mxPan ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXPP.ASM - Get/put pixel functions\r
-; Copyright (c) 1993,1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxGetPixel\r
-PUBLIC mxPutPixel\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-EXTRN mx_BytesPerLine : WORD\r
-EXTRN mx_VideoSegment : WORD\r
-EXTRN mx_ClipX1 : WORD\r
-EXTRN mx_ClipY1 : WORD\r
-EXTRN mx_ClipX2 : WORD\r
-EXTRN mx_ClipY2 : WORD\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Gets a pixel.\r
-;\r
-; Input:\r
-; X, Y = pixel coordinates\r
-; Output:\r
-; pixel color\r
-;\r
-mxGetPixel PROC FAR\r
- ARG Y:WORD, \\r
- X:WORD = ARG_SIZE\r
- ASSUME ds:NOTHING\r
- .enter 0\r
- .push ds, si\r
-\r
- xor ax, ax\r
- mov si, [X]\r
- cmp si, [mx_ClipX1]\r
- jl @@Exit\r
- cmp si, [mx_ClipX2]\r
- jg @@Exit\r
- mov bx, [Y]\r
- cmp bx, [mx_ClipY1]\r
- jl @@Exit\r
- cmp bx, [mx_ClipY2]\r
- jg @@Exit\r
-\r
- mov al, 04h ; Set read plane\r
- mov ah, BYTE PTR [X]\r
- and ah, 3\r
- mov dx, GDC\r
- out dx, ax\r
-\r
- mov ds, [mx_VideoSegment]\r
- mov ax, bx\r
- mul [mx_BytesPerLine]\r
- .shr si, 2\r
- add si, ax\r
-\r
- mov al, ds:[si] ; Get pixel value\r
- xor ah, ah\r
-\r
-@@Exit:\r
- .pop ds, si\r
- .leave ARG_SIZE\r
-mxGetPixel ENDP\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Puts a pixel of the specified color.\r
-;\r
-; Input:\r
-; X, Y = pixel coordinates\r
-; Color = pixel color\r
-; Output:\r
-; none\r
-;\r
-mxPutPixel PROC FAR\r
- ARG Color:BYTE:2, \\r
- Y:WORD, \\r
- X:WORD = ARG_SIZE\r
- .enter 0\r
- .push ds, si\r
-\r
- mov si, [X]\r
- cmp si, [mx_ClipX1]\r
- jl @@Exit\r
- cmp si, [mx_ClipX2]\r
- jg @@Exit\r
- mov ax, [Y]\r
- cmp ax, [mx_ClipY1]\r
- jl @@Exit\r
- cmp ax, [mx_ClipY2]\r
- jg @@Exit\r
-\r
- mov ds, [mx_VideoSegment]\r
- mul [mx_BytesPerLine]\r
- .shr si, 2\r
- add si, ax\r
-\r
- mov cl, BYTE PTR [X] ; Set write plane\r
- and cl, 3\r
- mov ax, 0102h\r
- shl ah, cl\r
- mov dx, TS\r
- out dx, ax\r
-\r
- mov al, [Color] ; Write pixel\r
- mov ds:[si], al\r
-\r
-@@Exit:\r
- xor ax, ax\r
- .pop ds, si\r
- .leave ARG_SIZE\r
-mxPutPixel ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXRA.ASM - Row address\r
-; Copyright (c) 1993,1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxRowAddress\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Sets the row address register.\r
-;\r
-; Input:\r
-; RowAddress = row size in words\r
-; Output:\r
-; none\r
-;\r
-mxRowAddress PROC FAR\r
- ARG RowAddress:BYTE:2 = ARG_SIZE\r
- ASSUME ds:NOTHING\r
- .enter 0\r
- mov dx, CRTC\r
- mov al, 13h\r
- mov ah, [RowAddress]\r
- out dx, ax\r
- xor ax, ax\r
- .leave ARG_SIZE\r
-mxRowAddress ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXRP.ASM - Rotate palette function\r
-; Copyright (c) 1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxRotatePalette\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Rotates the palette of the specified number of colors.\r
-;\r
-; Input:\r
-; Palette = pointer to palette\r
-; Count = number of colors to rotate\r
-; Step = step size\r
-; Output:\r
-; none\r
-;\r
-; Note: if Step is positive palette is rotated left to right, otherwise\r
-; right to left.\r
-;\r
-mxRotatePalette PROC FAR\r
- ARG Step:WORD, \\r
- Count:WORD, \\r
- Palette:DWORD = ARG_SIZE\r
- LOCAL Holder:BYTE:768 = AUTO_SIZE\r
- ASSUME ds:NOTHING\r
- .enter AUTO_SIZE\r
- .push ds, si, es, di\r
-\r
- mov bx, [Count]\r
- add bx, bx\r
- add bx, [Count] ; BX = Count*3\r
-\r
- lds si, [Palette] ; DS:SI -> palette\r
- push ss\r
- pop es\r
- lea di, Holder ; ES:DI -> local space\r
- cld\r
-\r
- mov ax, [Step]\r
- mov dx, ax\r
- test ax, ax\r
- jz @@Exit ; Nothing to do, exit\r
- jl @@RightToLeft\r
-\r
-@@LeftToRight:\r
- add ax, ax\r
- add dx, ax ; DX = Step*3\r
- sub bx, dx ; BX = (Count-Step)*3\r
- add si, bx\r
- push si\r
- mov cx, dx\r
- rep movsb\r
- mov es, WORD PTR Palette[2]\r
- mov di, si\r
- dec di ; ES:DI -> last byte of palette\r
- pop si\r
- dec si\r
- mov cx, bx\r
- std\r
- rep movsb\r
- push ss\r
- pop ds\r
- lea si, Holder\r
- les di, [Palette]\r
- mov cx, dx\r
- cld\r
- rep movsb\r
- jmp @@Exit\r
-\r
-@@RightToLeft:\r
- add ax, ax\r
- add dx, ax\r
- neg dx ; DX = Step*3\r
- sub bx, dx ; BX = (Count-Step)*3\r
- mov cx, dx\r
- rep movsb\r
- les di, [Palette]\r
- mov cx, bx\r
- rep movsb\r
- push ss\r
- pop ds\r
- lea si, Holder\r
- mov cx, dx\r
- rep movsb\r
-\r
-@@Exit:\r
- .pop ds, si, es, di\r
- .leave ARG_SIZE\r
-mxRotatePalette ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXSA.ASM - Start address function\r
-; Copyright (c) 1993,1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxStartAddress\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Modifies the starting address of video memory.\r
-;\r
-; Input:\r
-; StartAddr = new start address of video memory\r
-; Output:\r
-; none\r
-;\r
-mxStartAddress PROC FAR\r
- ARG StartAddr:WORD = ARG_SIZE\r
- ASSUME ds:NOTHING\r
- .enter 0\r
-\r
- mov bx, [StartAddr]\r
- mov dx, CRTC\r
- mov al, 0Ch ; Linear Starting Address high\r
- mov ah, bh\r
- cli\r
- out dx, ax\r
- mov al, 0Dh ; Linear Starting Address low\r
- mov ah, bl\r
- out dx, ax\r
- sti\r
-\r
- .leave ARG_SIZE\r
-mxStartAddress ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXSC.ASM - Set color function\r
-; Copyright (c) 1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxSetColor\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Updates the selected DAC register.\r
-;\r
-; Input:\r
-; Index = index of color to set\r
-; R, G, B = color components\r
-; Output:\r
-; none\r
-;\r
-mxSetColor PROC FAR\r
- ARG B:BYTE:2, \\r
- G:BYTE:2, \\r
- R:BYTE:2, \\r
- Index:WORD = ARG_SIZE\r
- .enter 0\r
- .push ds, si\r
-\r
- mov ax, [Index]\r
- mov dx, 3C8h ; PEL write address register\r
- out dx, al\r
- inc dx\r
-\r
- mov al, [R]\r
- out dx, al\r
- mov al, [G]\r
- out dx, al\r
- mov al, [B]\r
- out dx, al\r
-\r
- .pop ds, si\r
- .leave ARG_SIZE\r
-mxSetColor ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXPI.ASM - Stretch image\r
-; Copyright (c) 1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-NOWARN RES\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxStretchImage\r
-\r
-EXTRN subClipBox : NEAR\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-EXTRN mx_VideoSegment : WORD\r
-EXTRN mx_BytesPerLine : WORD\r
-\r
-mxTable LABEL WORD ; Raster ops\r
- DW subMove\r
- DW subAnd\r
- DW subOr\r
- DW subXor\r
- DW subTrans\r
- DW subAdd\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Stretches and copies a "raw" image from memory to screen.\r
-;\r
-; Input:\r
-; Image = pointer to image\r
-; X, Y = coordinates of destination\r
-; Width = width of image in pixels\r
-; Height = height of image in pixels\r
-; NewWidth = new width of image in pixels\r
-; NewHeight = new height of image in pixels\r
-; Op = raster op (OP_xxx)\r
-; Output:\r
-; none\r
-;\r
-mxStretchImage PROC FAR\r
- ARG Op:WORD, \\r
- NewHeight:WORD, \\r
- NewWidth:WORD, \\r
- Height:WORD, \\r
- Width:WORD, \\r
- Y:WORD, \\r
- X:WORD, \\r
- Image:DWORD = ARG_SIZE\r
- LOCAL PixelOffset:WORD, \\r
- MoveFunction:WORD, \\r
- ReadPlane:BYTE, \\r
- OpInfo:BYTE, \\r
- WidthStep:DWORD, \\r
- HeightStep:DWORD, \\r
- ImageLo:WORD, \\r
- WritePlane:BYTE = AUTO_SIZE\r
- ASSUME ds:NOTHING\r
- .enter AUTO_SIZE\r
- .push ds, si, es, di\r
-\r
-; Get width stretch factor\r
- IF USE386 EQ TRUE\r
- movzx edx, [Width]\r
- xor eax, eax\r
- movzx ebx, [NewWidth]\r
- shl ebx, 16\r
- idiv ebx\r
- mov [WidthStep], eax\r
- ELSE\r
- xor dx, dx ; Width stretch factor\r
- mov ax, [Width]\r
- mov bx, [NewWidth]\r
- div bx\r
- mov WORD PTR WidthStep[2], ax\r
- xor ax, ax\r
- div bx\r
- mov WORD PTR WidthStep[0], ax\r
- ENDIF\r
-; Get height stretch factor\r
- IF USE386 EQ TRUE\r
- movzx edx, [Height]\r
- xor eax, eax\r
- movzx ebx, [NewHeight]\r
- shl ebx, 16\r
- idiv ebx\r
- mov [HeightStep], eax\r
- ELSE\r
- xor dx, dx\r
- mov ax, [Height]\r
- mov bx, [NewHeight]\r
- div bx\r
- mov WORD PTR HeightStep[2], ax\r
- xor ax, ax\r
- div bx\r
- mov WORD PTR HeightStep[0], ax\r
- ENDIF\r
-\r
-; Clip image\r
- mov bx, [X]\r
- mov ax, [Y]\r
- mov cx, [NewWidth]\r
- mov dx, [NewHeight]\r
- call subClipBox\r
- jc @@Exit ; Full clipped\r
- mov [NewWidth], cx\r
- mov [NewHeight], dx\r
- sub [X], bx\r
- sub [Y], ax\r
-\r
-; Get pixel address\r
- mul [mx_BytesPerLine]\r
- mov di, bx\r
- shr di, 1\r
- shr di, 1\r
- add di, ax\r
- mov [PixelOffset], di\r
- mov es, [mx_VideoSegment] ; ES:DI points to pixel\r
- and bl, 03h\r
- mov [ReadPlane], bl ; Set read plane\r
- mov cl, bl\r
- mov al, 00010001b\r
- shl al, cl\r
- mov [WritePlane], al ; Set write plane\r
-\r
-; Relocate image origin if previously clipped\r
- mov ax, [Y]\r
- test ax, ax\r
- jz @@OriginYDone\r
- IF USE386 EQ TRUE\r
- shl eax, 16\r
- imul [HeightStep]\r
- mov ax, [Width]\r
- mul dx\r
- ELSE\r
- mov bx, ax\r
- mul WORD PTR HeightStep[0]\r
- mov cx, dx\r
- mov ax, bx\r
- mul WORD PTR HeightStep[2]\r
- add ax, cx\r
- mul [Width]\r
- ENDIF\r
- add WORD PTR [Image], ax\r
-@@OriginYDone:\r
- mov ax, [X]\r
- test ax, ax\r
- jz @@OriginXDone\r
- IF USE386 EQ TRUE\r
- shl eax, 16\r
- imul [WidthStep]\r
- add WORD PTR [Image], dx\r
- ELSE\r
- mov bx, ax\r
- mul WORD PTR WidthStep[0]\r
- mov cx, dx\r
- mov ax, bx\r
- mul WORD PTR WidthStep[2]\r
- add ax, cx\r
- add WORD PTR [Image], ax\r
- ENDIF\r
-@@OriginXDone:\r
- mov ax, WORD PTR HeightStep[2]\r
- mul [Width]\r
- mov WORD PTR HeightStep[2], ax\r
-\r
-; Install move function\r
- mov bx, [Op]\r
- mov [OpInfo], bh ; Remember additional info if needed\r
- xor bh, bh\r
- cmp bl, OP_ADD\r
- jbe @@SetMoveFunction\r
- xor bl, bl\r
-@@SetMoveFunction:\r
- shl bx, 1\r
- mov ax, mxTable[bx]\r
- mov [MoveFunction], ax\r
-\r
-; Put image\r
- mov ds, WORD PTR Image[2]\r
- xor ax, ax\r
- mov [ImageLo], ax\r
-@@Loop:\r
- mov si, WORD PTR Image[0] ; Get pointer to image\r
- mov ah, [WritePlane]\r
- and ah, 0Fh\r
- mov al, 02h\r
- mov dx, TS\r
- out dx, ax ; Select write plane\r
- mov ah, [ReadPlane]\r
- and ah, 03h\r
- mov al, 04h\r
- mov dx, GDC\r
- out dx, ax ; Select read plane\r
- mov cx, [NewHeight]\r
- mov di, [PixelOffset] ; ES:DI points to video memory\r
- mov ah, [OpInfo] ; Additional raster op info\r
- xor bx, bx\r
- mov dx, [mx_BytesPerLine]\r
- call [MoveFunction] ; Draw column\r
- inc [ReadPlane] ; Next read plane\r
- rol [WritePlane], 1 ; Next write plane\r
- adc [PixelOffset], 0 ; Update video offset if needed\r
- mov dx, WORD PTR WidthStep[0]\r
- mov ax, WORD PTR WidthStep[2]\r
- add [ImageLo], dx\r
- adc WORD PTR Image[0], ax ; Next image column\r
- dec [NewWidth]\r
- jnz @@Loop ; Repeat for all columns\r
-\r
-@@Exit:\r
- xor ax, ax\r
- .pop ds, si, es, di\r
- .leave ARG_SIZE\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Move functions, on entry:\r
-; AH = additional raster op info (e.g. transparent color)\r
-; BX = 0,\r
-; CX = pixel count,\r
-; DX = mx_BytesPerLine.\r
-;\r
-subMove PROC NEAR\r
-@@Loop: mov al, ds:[si]\r
- mov es:[di], al\r
- add di, dx\r
- dec cx\r
- jz @@Exit\r
- add si, WORD PTR HeightStep[2]\r
- add bx, WORD PTR HeightStep[0]\r
- jnc @@Loop\r
- add si, [Width]\r
- jmp @@Loop\r
-@@Exit: ret\r
-subMove ENDP\r
-;\r
-subAnd PROC NEAR\r
-@@Loop: mov al, ds:[si]\r
- and es:[di], al\r
- add di, dx\r
- dec cx\r
- jz @@Exit\r
- add si, WORD PTR HeightStep[2]\r
- add bx, WORD PTR HeightStep[0]\r
- jnc @@Loop\r
- add si, [Width]\r
- jmp @@Loop\r
-@@Exit: ret\r
-subAnd ENDP\r
-;\r
-subOr PROC NEAR\r
-@@Loop: mov al, ds:[si]\r
- or es:[di], al\r
- add di, dx\r
- dec cx\r
- jz @@Exit\r
- add si, WORD PTR HeightStep[2]\r
- add bx, WORD PTR HeightStep[0]\r
- jnc @@Loop\r
- add si, [Width]\r
- jmp @@Loop\r
-@@Exit: ret\r
-subOr ENDP\r
-;\r
-subXor PROC NEAR\r
-@@Loop: mov al, ds:[si]\r
- xor es:[di], al\r
- add di, dx\r
- dec cx\r
- jz @@Exit\r
- add si, WORD PTR HeightStep[2]\r
- add bx, WORD PTR HeightStep[0]\r
- jnc @@Loop\r
- add si, [Width]\r
- jmp @@Loop\r
-@@Exit: ret\r
-subXor ENDP\r
-;\r
-subTrans PROC NEAR\r
-@@Loop: mov al, ds:[si]\r
- cmp al, ah\r
- je @@Skip\r
- mov es:[di], al\r
-@@Skip:\r
- add di, dx\r
- dec cx\r
- jz @@Exit\r
- add si, WORD PTR HeightStep[2]\r
- add bx, WORD PTR HeightStep[0]\r
- jnc @@Loop\r
- add si, [Width]\r
- jmp @@Loop\r
-@@Exit: ret\r
-subTrans ENDP\r
-;\r
-subAdd PROC NEAR\r
-@@Loop: mov al, ds:[si]\r
- add es:[di], al\r
- add di, dx\r
- dec cx\r
- jz @@Exit\r
- add si, WORD PTR HeightStep[2]\r
- add bx, WORD PTR HeightStep[0]\r
- jnc @@Loop\r
- add si, [Width]\r
- jmp @@Loop\r
-@@Exit: ret\r
-subAdd ENDP\r
-\r
-mxStretchImage ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXLN.ASM - Start line function\r
-; Copyright (c) 1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-NOWARN RES\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxStartLine\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-EXTRN mx_BytesPerLine : WORD\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Changes the video start address to the specified line.\r
-;\r
-; Input:\r
-; Line = new start line\r
-; Output:\r
-; none\r
-;\r
-mxStartLine PROC FAR\r
- ARG Line:WORD = ARG_SIZE\r
- .enter 0\r
- ASSUME ds:NOTHING\r
-\r
- mov ax, [Line] ; Get video offset\r
- mul [mx_BytesPerLine]\r
- xchg ax, bx ; Copy it into BX\r
-\r
-; Wait display\r
- mov dx, STATUS\r
-@@1: in al, dx\r
- test al, 08h\r
- jnz @@1\r
-\r
-; Set starting address\r
- mov dx, CRTC\r
- mov al, 0Ch ; Linear Starting Address high\r
- mov ah, bh\r
- cli\r
- out dx, ax\r
- mov al, 0Dh ; Linear Starting Address low\r
- mov ah, bl\r
- out dx, ax\r
- sti\r
-\r
-; Wait retrace\r
- mov dx, STATUS\r
-@@2: in al,dx\r
- test al, 08h\r
- jz @@2\r
-\r
- xor ax, ax\r
- .leave ARG_SIZE\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXSM.ASM - Set/change mode functions\r
-; Copyright (c) 1993,1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxChangeMode\r
-PUBLIC mxGetAspect\r
-PUBLIC mxGetScreenSize\r
-PUBLIC mxSetMode\r
-\r
-PUBLIC mx_ScreenWidth\r
-PUBLIC mx_ScreenHeight\r
-PUBLIC mx_BytesPerLine\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-EXTRN mxSetSysClipRegion : FAR\r
-\r
-EXTRN mx_VideoSegment : WORD\r
-EXTRN mx_CodeSegment : WORD\r
-\r
-mx_ScreenWidth DW ? ; Current screen width\r
-mx_ScreenHeight DW ?\r
-mx_AspectX DW ? ; Aspect ratio for current mode\r
-mx_AspectY DW ?\r
-mx_BytesPerLine DW 0 ; Bytes per line\r
-\r
-;\r
-; Tables for setting video modes, sources:\r
-; - MODEX.ASM, Matt Pritchard\r
-; - Dr. Dobb's Journal, Michael Abrash\r
-; - Fractint VIDEO.ASM module\r
-;\r
-TBL_SingleLine LABEL WORD ; CRTC\r
- DW 04009h ; Cell height: 1 scan line\r
- DW 00014h ; Double word mode off\r
- DW 0E317h ; Byte mode on\r
- DW 0\r
-TBL_DoubleLine LABEL WORD ; CRTC\r
- DW 04109h ; Cell height: 2 scan lines\r
- DW 00014h\r
- DW 0E317h\r
- DW 0\r
-TBL_Width320 LABEL WORD ; CRTC\r
- DW 05F00h ; Horizontal total\r
- DW 04F01h ; Horizontal displayed\r
- DW 05002h ; Start horizontal blanking\r
- DW 08203h ; End horizontal blanking\r
- DW 05404h ; Start horizontal sync\r
- DW 08005h ; End horizontal sync\r
- DW 02813h ; Row address\r
- DW 0\r
-TBL_Width360 LABEL WORD ; CRTC\r
- DW 06B00h ; Horizontal total\r
- DW 05901h ; Horizontal displayed\r
- DW 05A02h ; Start horizontal blanking\r
- DW 08E03h ; End horizontal blanking\r
- DW 05E04h ; Start horizontal sync\r
- DW 08A05h ; End horizontal sync\r
- DW 02D13h ; Row address\r
- DW 0\r
-TBL_Height175 LABEL WORD ; CRTC\r
- DW 0BF06h ; Vertical total\r
- DW 01F07h ; Overflow\r
- DW 08310h ; Start vertical sync\r
- DW 08511h ; End vertical sync\r
- DW 05D12h ; Vertical displayed\r
- DW 06315h ; Start vertical blanking\r
- DW 0BA16h ; End vertical blanking\r
- DW 0\r
-TBL_Height200 LABEL WORD ; CRTC\r
- DW 0BF06h ; Vertical total\r
- DW 01F07h ; Overflow\r
- DW 09C10h ; Start vertical sync\r
- DW 08E11h ; End vertical sync\r
- DW 08F12h ; Vertical displayed\r
- DW 09615h ; Start vertical blanking\r
- DW 0B916h ; End vertical blanking\r
- DW 0\r
-TBL_Height240 LABEL WORD ; CRTC\r
- DW 00D06h ; Vertical total\r
- DW 03E07h ; Overflow\r
- DW 0EA10h ; Start vertical sync\r
- DW 08C11h ; End vertical sync\r
- DW 0DF12h ; Vertical displayed\r
- DW 0E715h ; Start vertical blanking\r
- DW 00616h ; End vertical blanking\r
- DW 0\r
-TBL_Tweak400x600:\r
- DW 07400h\r
- DW 06301h\r
- DW 06402h\r
- DW 09703h\r
- DW 06804h\r
- DW 09505h\r
- DW 08606h\r
- DW 0F007h\r
- DW 06009h\r
- DW 0310Fh\r
- DW 05B10h\r
- DW 08D11h\r
- DW 05712h\r
- DW 03213h\r
- DW 00014h\r
- DW 06015h\r
- DW 08016h\r
- DW 0E317h\r
- DW 0\r
-\r
-TBL_320x200:\r
- DB 63h ; 400 scan lines, 25 MHz clock\r
- DW 6, 5 ; Aspect: 6/5 = 1.2:1\r
- DW 320, 200 ; Size\r
- DW TBL_Width320, TBL_Height200, TBL_DoubleLine, 0\r
- DW 819 ; Max height\r
-TBL_320x240:\r
- DB 0E3h ; 400 scan lines, 25 MHz clock\r
- DW 1, 1 ; Aspect: 1/1 = 1:1\r
- DW 320, 240 ; Size\r
- DW TBL_Width320, TBL_Height240, TBL_DoubleLine, 0\r
- DW 819 ; Max height\r
-TBL_320x400:\r
- DB 63h ; 480 scan lines, 25 MHz clock\r
- DW 6, 10 ; Aspect: 6/10 = 0.6:1\r
- DW 320, 400 ; Size\r
- DW TBL_Width320, TBL_Height200, TBL_SingleLine, 0\r
- DW 819 ; Max height\r
-TBL_320x480:\r
- DB 0E3h ; 480 scan lines, 25 MHz clock\r
- DW 1, 2 ; Aspect: 1/2 = 0.5:1\r
- DW 320, 480 ; Size\r
- DW TBL_Width320, TBL_Height240, TBL_SingleLine, 0\r
- DW 819 ; Max height\r
-TBL_360x200:\r
- DB 067h ; 400 scan lines, 28 MHz clock\r
- DW 27, 20 ; Aspect: 27/20 = 1.35:1\r
- DW 360, 200 ; Size\r
- DW TBL_Width360, TBL_Height200, TBL_DoubleLine, 0\r
- DW 728 ; Max height\r
-TBL_360x240:\r
- DB 0E7h ; 480 scan lines, 28 MHz clock\r
- DW 9, 8 ; Aspect: 9/8 = 1.125:1\r
- DW 360, 240 ; Size\r
- DW TBL_Width360, TBL_Height240, TBL_DoubleLine, 0\r
- DW 728 ; Max height\r
-TBL_360x400:\r
- DB 067h ; 400 scan lines, 28 MHz clock\r
- DW 27, 40 ; Aspect: 27/40 = 0.675:1\r
- DW 360, 400 ; Size\r
- DW TBL_Width360, TBL_Height200, TBL_SingleLine, 0\r
- DW 728 ; Max height\r
-TBL_360x480:\r
- DB 0E7h ; 480 scan lines, 28 MHz clock\r
- DW 9, 16 ; Aspect: 9/16 = 0.5625:1\r
- DW 360, 480 ; Size\r
- DW TBL_Width360, TBL_Height240, TBL_SingleLine, 0\r
- DW 728 ; Max height\r
-TBL_320x175:\r
- DB 0A3h\r
- DW 0, 0 ; Aspect:\r
- DW 320, 175\r
- DW TBL_Width320, TBL_Height175, TBL_DoubleLine, 0\r
- DW 819\r
-TBL_320x350:\r
- DB 0A3h\r
- DW 0, 0 ; Aspect:\r
- DW 320, 175\r
- DW TBL_Width320, TBL_Height175, TBL_SingleLine, 0\r
- DW 819\r
-TBL_360x175:\r
- DB 0A7h\r
- DW 0, 0 ; Aspect:\r
- DW 360, 480 ; Size\r
- DW TBL_Width360, TBL_Height175, TBL_DoubleLine, 0\r
- DW 728 ; Max height\r
-TBL_360x350:\r
- DB 0A7h\r
- DW 0, 0 ; Aspect:\r
- DW 360, 480 ; Size\r
- DW TBL_Width360, TBL_Height175, TBL_SingleLine, 0\r
- DW 728 ; Max height\r
-TBL_400x600:\r
- DB 0E7h ; 28 MHz clock\r
- DW 1, 2 ; Aspect: 1/2 = 0.5:1\r
- DW 400, 600 ; Size\r
- DW TBL_Tweak400x600, 0\r
- DW 655 ; Max height\r
-\r
-TBL_Mode LABEL WORD\r
- DW TBL_320x175\r
- DW TBL_320x200\r
- DW TBL_320x240\r
- DW TBL_320x350\r
- DW TBL_320x400\r
- DW TBL_320x480\r
- DW TBL_360x175\r
- DW TBL_360x200\r
- DW TBL_360x240\r
- DW TBL_360x350\r
- DW TBL_360x400\r
- DW TBL_360x480\r
- DW TBL_400x600\r
-\r
-MAXVMODE EQU ($-OFFSET TBL_Mode) / 2\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Enables 80x25 color text mode\r
-;\r
-subText PROC NEAR\r
- ASSUME ds:MX_TEXT\r
- mov ax, 0003h\r
- int 10h ; Call BIOS set mode\r
-\r
- mov [mx_ScreenHeight], 0\r
- mov [mx_BytesPerLine], 0\r
- ret\r
-subText ENDP\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Enables the selected graphics mode.\r
-;\r
-; Input:\r
-; Mode = mode to select (MX_???x???)\r
-; Output:\r
-; none\r
-;\r
-mxSetMode PROC FAR\r
- ARG Mode:WORD = ARG_SIZE\r
- ASSUME ds:NOTHING\r
- .enter 0\r
- .push ds, si, es, di\r
-\r
-; Set DS to code segment alias\r
- mov ds, [mx_CodeSegment]\r
- ASSUME ds:MX_TEXT\r
-\r
- mov si, [Mode]\r
- cmp si, MAXVMODE ; Is it a valid mode?\r
- ja @@Exit ; No, exit\r
- test si, si ; Text mode?\r
- jnz @@Set ; No, handle it\r
-\r
- call subText ; Back to text mode\r
- jmp @@Exit ; Exit now\r
-\r
-; Set video mode\r
-@@Set:\r
- dec si ; Skip text mode\r
- shl si, 1\r
- mov si, TBL_Mode[si]\r
- cld\r
-\r
-; Use BIOS to set 320x200x256 linear mode\r
- push si ; Save SI\r
- mov ax, 0013h\r
- int 10h ; Use BIOS to set 320x200 linear mode\r
- pop si ; Restore SI\r
-\r
- mov dx, TS\r
- mov ax, 0604h\r
- out dx, ax ; Disable chain-4 mode\r
- mov ax, 0100h\r
- out dx, ax ; Reset\r
- mov dx, MISC\r
- lodsb\r
- out dx, al ; New timing/size\r
- mov dx, TS\r
- mov ax, 0300h\r
- out dx, ax ; Restart sequencer\r
-\r
-; Unlock CRTC registers 0-7\r
- mov dx, CRTC\r
- mov al, 11h\r
- out dx, al ; Vertical sync end register\r
- inc dx\r
- in al, dx\r
- and al, 7Fh ; Clear write protect bit\r
- out dx, al\r
-\r
- lodsw ; Get X aspect\r
- mov [mx_AspectX], ax\r
- lodsw ; Get Y aspect\r
- mov [mx_AspectY], ax\r
- lodsw ; Get screen width\r
- mov [mx_ScreenWidth], ax\r
- shr ax, 1\r
- shr ax, 1 ; Divide by four to get bytes per line\r
- mov [mx_BytesPerLine], ax\r
- lodsw ; Get screen height\r
- mov [mx_ScreenHeight], ax\r
-\r
-; Set CRTC registers\r
- mov bx, si\r
- mov dx, CRTC\r
-@@TableLoop:\r
- mov si, ds:[bx] ; DS:SI -> table of CRTC registers\r
- inc bx\r
- inc bx ; DS:BX -> offset of next table\r
- test si, si ; Last table?\r
- jz @@EndLoop ; Yes, exit loop\r
-@@Loop:\r
- lodsw ; Get CRTC register index and value\r
- test ax, ax ; End of table?\r
- jz @@TableLoop ; Yes, go to next table\r
- out dx, ax ; Set register AL to value AH\r
- jmp @@Loop ; Get next register/value\r
-@@EndLoop:\r
-\r
-; Set virtual screen and system clip region\r
- push [mx_ScreenWidth]\r
- push WORD PTR ds:[bx]\r
- call mxSetSysClipRegion\r
-\r
-; Clear video memory\r
- mov dx, TS\r
- mov ax, 0F02h\r
- out dx, ax ; Enable all planes\r
- mov es, [mx_VideoSegment]\r
- xor di, di\r
- mov cx, 8000h\r
- xor ax, ax\r
- rep stosw\r
-\r
-@@Done:\r
-; Lock CRTC registers 0-7 (some cards need this)\r
- mov dx, CRTC\r
- mov al, 11h\r
- out dx, al ; Vertical sync end register\r
- inc dx\r
- in al, dx\r
- or al, 80h ; Set write protect bit\r
- out dx, al\r
-\r
-@@Exit:\r
- xor ax, ax\r
- mov ax, [mx_ScreenWidth]\r
- .pop ds, si, es, di\r
- .leave ARG_SIZE\r
-mxSetMode ENDP\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Changes from the current mode the selected graphics mode.\r
-;\r
-; Input:\r
-; Mode = mode to select (MX_???x???)\r
-; Output:\r
-; none\r
-; Notes:\r
-; this function assumes that mxSetMode and mxSetVirtualScreen\r
-; have been called first. View size is rearranged to match the\r
-; specified mode, but video memory is not cleared.\r
-; Differences from mxSetMode:\r
-; - video BIOS is not called to initialize graphics;\r
-; - row address register is not modified;\r
-; - video memory is not cleared;\r
-; - mx_BytesPerLine is not modified;\r
-; - system clip region is not modified.\r
-;\r
-mxChangeMode PROC FAR\r
- ARG Mode:WORD = ARG_SIZE\r
- ASSUME ds:NOTHING\r
- .enter 0\r
- .push ds, si, es, di\r
-\r
-; Set DS to code segment alias\r
- mov ds, [mx_CodeSegment]\r
- ASSUME ds:MX_TEXT\r
-\r
- mov si, [Mode]\r
- cmp si, MAXVMODE ; Is it a valid mode?\r
- ja @@Exit ; No, exit\r
- test si, si ; Text mode?\r
- jz @@Exit ; Yes, exit\r
-\r
- dec si ; Skip text mode\r
- shl si, 1\r
- mov si, TBL_Mode[si]\r
- cld\r
-\r
- mov dx, TS\r
- mov ax, 0604h\r
- out dx, ax ; Disable chain-4 mode\r
- mov ax, 0100h\r
- out dx, ax ; Reset\r
- mov dx, MISC\r
- lodsb\r
- out dx, al ; New timing/size\r
- mov dx, TS\r
- mov ax, 0300h\r
- out dx, ax ; Restart sequencer\r
-\r
-; Unlock CRTC registers 0-7\r
- mov dx, CRTC\r
- mov al, 11h\r
- out dx, al ; Vertical sync end register\r
- inc dx\r
- in al, dx\r
- and al, 7Fh ; Clear write protect bit\r
- out dx, al\r
-\r
- lodsw ; Get X aspect\r
- mov [mx_AspectX], ax\r
- lodsw ; Get Y aspect\r
- mov [mx_AspectY], ax\r
- lodsw ; Get screen width\r
- mov [mx_ScreenWidth], ax\r
- lodsw ; Get screen height\r
- mov [mx_ScreenHeight], ax\r
-\r
-; Set CRTC registers\r
- mov bx, si\r
- mov dx, CRTC\r
-@@TableLoop:\r
- mov si, ds:[bx] ; DS:SI -> table of CRTC registers\r
- inc bx\r
- inc bx ; DS:BX -> offset of next table\r
- test si, si ; Last table?\r
- jz @@EndLoop ; Yes, exit loop\r
-@@Loop:\r
- lodsw ; Get CRTC register index and value\r
- test ax, ax ; End of table?\r
- jz @@TableLoop ; Yes, go to next table\r
- cmp al, 13h ; Row address register?\r
- je @@Loop ; Yes, ignore it\r
- out dx, ax ; Set register AL to value AH\r
- jmp @@Loop ; Get next register/value\r
-@@EndLoop:\r
-\r
-; Lock CRTC registers 0-7 (some cards need this)\r
- mov dx, CRTC\r
- mov al, 11h\r
- out dx, al ; Vertical sync end register\r
- inc dx\r
- in al, dx\r
- or al, 80h ; Set write protect bit\r
- out dx, al\r
-\r
-@@Exit:\r
- xor ax, ax\r
- mov ax, [mx_ScreenWidth]\r
- .pop ds, si, es, di\r
- .leave ARG_SIZE\r
-mxChangeMode ENDP\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Returns the aspect ratio for the current mode.\r
-;\r
-; Input:\r
-; AspectX = pointer to aspect X\r
-; AspectY = pointer to aspect Y\r
-;\r
-; A rectangle of width AspectX and height AspectY looks like a square.\r
-;\r
-mxGetAspect PROC FAR\r
- ARG AspectY:DWORD, \\r
- AspectX:DWORD = ARG_SIZE\r
- .enter 0\r
- .push ds, si\r
- ASSUME ds:NOTHING\r
-\r
- lds si, [AspectX]\r
- mov ax, [mx_AspectX]\r
- mov ds:[si], ax\r
- lds si, [AspectY]\r
- mov ax, [mx_AspectY]\r
- mov ds:[si], ax\r
-\r
- .pop ds, si\r
- .leave ARG_SIZE\r
-mxGetAspect ENDP\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Returns the current screen size.\r
-;\r
-; Input:\r
-; Width = pointer to screen width\r
-; Height = pointer to screen height\r
-;\r
-mxGetScreenSize PROC FAR\r
- ARG SizeY:DWORD, \\r
- SizeX:DWORD = ARG_SIZE\r
- .enter 0\r
- .push ds, si\r
- ASSUME ds:NOTHING\r
-\r
- lds si, [SizeX]\r
- mov ax, [mx_ScreenWidth]\r
- mov ds:[si], ax\r
- lds si, [SizeY]\r
- mov ax, [mx_ScreenHeight]\r
- mov ds:[si], ax\r
-\r
- .pop ds, si\r
- .leave ARG_SIZE\r
-mxGetScreenSize ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXSP.ASM - Set palette function\r
-; Copyright (c) 1993,1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxSetPalette\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Updates the VGA palette.\r
-;\r
-; Input:\r
-; Buffer = pointer to palette data (R,G,B)\r
-; Start = index of first color to set\r
-; Count = number of color to set\r
-; Output:\r
-; none\r
-;\r
-mxSetPalette PROC FAR\r
- ARG Count:WORD, \\r
- Start:WORD, \\r
- Buffer:DWORD = ARG_SIZE\r
- ASSUME ds:NOTHING\r
- .enter 0\r
- .push ds, si\r
-\r
- lds si, [Buffer]\r
- mov cx, [Count]\r
- mov ax, [Start]\r
- mov dx, 3C8h ; PEL write address register\r
- out dx, al\r
- inc dx\r
- cld\r
- cli ; Disable interrupts\r
-@@Loop:\r
- lodsb\r
- out dx, al ; Red\r
- lodsb\r
- out dx, al ; Green\r
- lodsb\r
- out dx, al ; Blue\r
- loop @@Loop ; Loop until done\r
- sti ; Enable interrupts\r
-\r
- .pop ds, si\r
- .leave ARG_SIZE\r
-mxSetPalette ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXSS.ASM - Split screen function\r
-; Copyright (c) 1993,1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxSplitScreen\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Splits the screen.\r
-;\r
-; Input:\r
-; Line = scan line at which screen has to be splitted\r
-; Output:\r
-; none\r
-;\r
-mxSplitScreen PROC FAR\r
- ARG Line:WORD = ARG_SIZE\r
- ASSUME ds:NOTHING\r
- .enter 0\r
-\r
-; Modify the line compare value: bits 0-7 are in the Line Compare\r
-; register (CRTC #18), bit 8 is in the Overflow Low register (CRTC #7)\r
-; and bit 9 is in the Maximum Row Address register (CRTC #9)\r
- mov ax, [Line]\r
- shl ax, 1 ; Adjust line for mode "X"\r
- mov bh, ah\r
- mov bl, ah\r
- and bx, 0201h\r
- mov cl, 4\r
- shl bx, cl\r
- shl bh, 1\r
- mov dx, CRTC\r
-; Write bits 0-7 to line compare register\r
- mov ah, al\r
- mov al, 18h\r
- out dx, ax\r
-; Write bit 8 to overflow register\r
- mov al, 07h\r
- out dx, al\r
- inc dx\r
- in al, dx\r
- dec dx\r
- mov ah, al\r
- and ah, 11101111b\r
- or ah, bl\r
- mov al, 07h\r
- out dx, ax\r
-; Write bit 9 to maximum row address register\r
- mov al, 09h\r
- out dx, al\r
- inc dx\r
- in al, dx\r
- dec dx\r
- mov ah, al\r
- and ah, 10111111b\r
- or ah, bh\r
- mov al, 09h\r
- out dx, ax\r
-\r
- .leave ARG_SIZE\r
-mxSplitScreen ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXTL.ASM - Put tile\r
-; Copyright (c) 1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-NOWARN RES\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxPutTile\r
-PUBLIC mxTransPutTile\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-EXTRN mx_VideoSegment : WORD\r
-EXTRN mx_BytesPerLine : WORD\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Copies a "mode-x" tile from memory to screen.\r
-;\r
-; Input:\r
-; Image = pointer to tile\r
-; X, Y = coordinates of destination\r
-; Width = width of image in pixels (Width and 3 = 0)\r
-; Height = height of image in pixels\r
-; Output:\r
-; none\r
-; Note:\r
-; no clipping is performed on tiles!\r
-;\r
-mxPutTile PROC FAR\r
- ARG Height:WORD, \\r
- Width:WORD, \\r
- Y:WORD, \\r
- X:WORD, \\r
- Image:DWORD = ARG_SIZE\r
- ASSUME ds:NOTHING\r
- .enter 0\r
- .push ds, si, es, di\r
-\r
- mov ax, [Y] ; Get pixel address\r
- mul [mx_BytesPerLine]\r
- mov di, [X]\r
- .shr di, 2\r
- add di, ax\r
- mov es, [mx_VideoSegment]\r
-\r
- lds si, [Image] ; Get tile address\r
- .shr [Width], 2 ; Number of bytes per plane\r
- mov cl, BYTE PTR [X]\r
- and cl, 3\r
- mov ah, 11h ; AH = plane mask\r
- shl ah, cl ; Align mask to first plane\r
-\r
- mov [Y], 4 ; Number of planes\r
- mov bx, [mx_BytesPerLine]\r
- sub bx, [Width] ; Extra bytes per line\r
-@@Loop:\r
- mov al, 02h\r
- mov dx, TS\r
- out dx, ax ; Set write plane\r
- mov [X], di ; Save video offset\r
- mov dx, [Height]\r
-@@Loop2:\r
- mov cx, [Width] ; Number of bytes to move\r
-\r
- shr cx, 1 ; Move line\r
- rep movsw\r
- rcl cx, 1\r
- rep movsb\r
-\r
- add di, bx ; Move video offset to next line\r
- dec dx ; Done all lines?\r
- jnz @@Loop2 ; No, continue\r
- mov di, [X] ; Restore video offset\r
- rol ah, 1 ; Next plane\r
- adc di, 0 ; Bump video offset if needed\r
- dec [Y] ; Any plane left?\r
- jnz @@Loop ; Yes, keep looping\r
-\r
- xor ax, ax\r
- .pop ds, si, es, di\r
- .leave ARG_SIZE\r
-mxPutTile ENDP\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Copies a "mode-x" tile from memory to screen.\r
-; Skips over color 0.\r
-;\r
-; Input:\r
-; Image = pointer to tile\r
-; X, Y = coordinates of destination\r
-; Width = width of image in pixels (Width and 3 = 0)\r
-; Height = height of image in pixels\r
-; Output:\r
-; none\r
-; Note:\r
-; no clipping is performed on tiles!\r
-;\r
-mxTransPutTile PROC FAR\r
- ARG Height:WORD, \\r
- Width:WORD, \\r
- Y:WORD, \\r
- X:WORD, \\r
- Image:DWORD = ARG_SIZE\r
- ASSUME ds:NOTHING\r
- .enter 0\r
- .push ds, si, es, di\r
-\r
- mov ax, [Y] ; Get pixel address\r
- mul [mx_BytesPerLine]\r
- mov di, [X]\r
- .shr di, 2\r
- add di, ax\r
- mov es, [mx_VideoSegment]\r
-\r
- lds si, [Image] ; Get tile address\r
- .shr [Width], 2 ; Number of bytes per plane\r
- mov cl, BYTE PTR [X]\r
- and cl, 3\r
- mov ah, 11h ; AH = plane mask\r
- shl ah, cl ; Align mask to first plane\r
-\r
- mov [Y], 4 ; Number of planes\r
- mov bx, [mx_BytesPerLine]\r
- sub bx, [Width] ; Extra bytes per line\r
-@@Loop:\r
- mov al, 02h\r
- mov dx, TS\r
- out dx, ax ; Set write plane\r
- mov [X], di ; Save video offset\r
- mov dx, [Height]\r
-@@Loop2:\r
- mov cx, [Width] ; Number of bytes to move\r
-\r
-; Move one line\r
- jcxz @@MoveLineDone\r
-@@MoveLineLoop:\r
- mov al, ds:[si]\r
- test al, al\r
- jz @@MoveLineNext\r
- mov es:[di], al\r
-@@MoveLineNext:\r
- inc si\r
- inc di\r
- dec cx\r
- jnz @@MoveLineLoop\r
-@@MoveLineDone:\r
-\r
- add di, bx ; Move video offset to next line\r
- dec dx ; Done all lines?\r
- jnz @@Loop2 ; No, continue\r
- mov di, [X] ; Restore video offset\r
- rol ah, 1 ; Next plane\r
- adc di, 0 ; Bump video offset if needed\r
- dec [Y] ; Any plane left?\r
- jnz @@Loop ; Yes, keep looping\r
-\r
- xor ax, ax\r
- .pop ds, si, es, di\r
- .leave ARG_SIZE\r
-mxTransPutTile ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXVS.ASM - Set/get virtual screen\r
-; Copyright (c) 1993,1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-NOWARN RES\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxSetVirtualScreen\r
-PUBLIC mxGetVirtualScreen\r
-\r
-EXTRN mxRowAddress : FAR\r
-EXTRN mxSetSysClipRegion : FAR\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-EXTRN mx_BytesPerLine : WORD\r
-EXTRN mx_CodeSegment : WORD\r
-\r
-mx_VirtualWidth DW ? ; Virtual screen size\r
-mx_VirtualHeight DW ?\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Sets the virtual screen.\r
-;\r
-; Input:\r
-; Width = virtual screen width\r
-; Height = virtual screen height\r
-; Output:\r
-; 0 on success, else invalid parameters\r
-;\r
-mxSetVirtualScreen PROC FAR\r
- ARG Height:WORD, \\r
- Width:WORD = ARG_SIZE\r
- ASSUME ds:NOTHING\r
- .enter 0\r
- .push ds\r
-\r
-; Set DS to code segment\r
- mov ds, [mx_CodeSegment]\r
- ASSUME ds:MX_TEXT\r
-\r
- mov ax, 1 ; Assume an error\r
- cmp [Width], 320 ; Check width\r
- jb @@Exit\r
- push ax ; Save return code\r
- mov dx, 0004h\r
- xor ax, ax ; DX:AX = 256K\r
- div [Width] ; Max height in AX\r
- cmp [Height], ax\r
- pop ax ; Restore return code\r
- ja @@Exit ; Exit if bad heigth\r
-\r
- mov ax, [Width]\r
- and ax, 0FFF8h ; Align to byte\r
- mov [mx_VirtualWidth], ax\r
- shr ax, 1\r
- shr ax, 1\r
- mov [mx_BytesPerLine], ax\r
- shr ax, 1\r
- push ax\r
- call mxRowAddress ; Set row address\r
- mov ax, [Height]\r
- mov [mx_VirtualHeight], ax\r
-\r
- push [Width]\r
- push [Height]\r
- call mxSetSysClipRegion\r
- xor ax, ax\r
-\r
-@@Exit:\r
- .pop ds\r
- .leave ARG_SIZE\r
-mxSetVirtualScreen ENDP\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Returns the current virtual screen size.\r
-;\r
-; Input:\r
-; Width = pointer to virtual screen width\r
-; Height = pointer to virtual screen height\r
-; Output:\r
-; none\r
-;\r
-mxGetVirtualScreen PROC FAR\r
- ARG Height:DWORD, \\r
- Width:DWORD = ARG_SIZE\r
- ASSUME ds:NOTHING\r
- .enter 0\r
- .push ds, si\r
-\r
- mov ax, [mx_VirtualWidth]\r
- lds si, [Width]\r
- mov ds:[si], ax\r
- mov ax, [mx_VirtualHeight]\r
- lds si, [Height]\r
- mov ds:[si], ax\r
-\r
- xor ax, ax\r
- .pop ds, si\r
- .leave ARG_SIZE\r
-mxGetVirtualScreen ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXWD.ASM - Wait display function\r
-; Copyright (c) 1993,1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxWaitDisplay\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Waits for display start.\r
-;\r
-mxWaitDisplay PROC FAR\r
- mov dx, STATUS\r
-@@1: in al, dx\r
- test al, 08h\r
- jnz @@1\r
- ret\r
-mxWaitDisplay ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXWM.ASM - Set write mode function\r
-; Copyright (c) 1993,1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxWriteMode\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Sets the write mode.\r
-;\r
-; Input:\r
-; Mode = write mode (0,1,2,3)\r
-; Output:\r
-; none\r
-;\r
-mxWriteMode PROC FAR\r
- ARG Mode:BYTE:2 = ARG_SIZE\r
- .enter 0\r
-\r
- mov dx, GDC\r
- mov ah, [Mode]\r
- and ah, 00000011b\r
- or ah, 01000000b\r
- mov al, 05h\r
- out dx, ax\r
-\r
- .leave ARG_SIZE\r
-mxWriteMode ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXWP.ASM - Set write/read plane functions\r
-; Copyright (c) 1993,1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxWritePlane\r
-PUBLIC mxReadPlane\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Sets the write plane(s).\r
-;\r
-; Input:\r
-; Plane = write plane(s) to set (bit 0 enables plane 0,\r
-; bit 1 enables plane 1 and so on, different planes\r
-; may be selected at the same time)\r
-; Output:\r
-; none\r
-;\r
-mxWritePlane PROC FAR\r
- ARG Plane:BYTE:2 = ARG_SIZE\r
- .enter 0\r
-\r
- mov ah, [Plane]\r
- and ah, 00001111b ; Mask off unused bits\r
- mov al, 02h\r
- mov dx, TS\r
- out dx, ax\r
-\r
- .leave ARG_SIZE\r
-mxWritePlane ENDP\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Sets the read plane.\r
-;\r
-; Input:\r
-; Plane = read plane to set (0,1,2,3)\r
-; Output:\r
-; none\r
-;\r
-mxReadPlane PROC FAR\r
- ARG Plane:BYTE:2 = ARG_SIZE\r
- ASSUME ds:NOTHING\r
- .enter 0\r
- mov al, 04h\r
- mov ah, [Plane]\r
- and ah, 0000011b ; Mask off unused bits\r
- mov dx, GDC\r
- out dx, ax\r
- .leave ARG_SIZE\r
-mxReadPlane ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXWR.ASM - Wait vertical retrace function\r
-; Copyright (c) 1993,1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxWaitRetrace\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Waits for vertical retrace start.\r
-;\r
-mxWaitRetrace PROC FAR\r
- mov dx, STATUS\r
-@@1: in al,dx\r
- test al, 08h\r
- jz @@1\r
- ret\r
-mxWaitRetrace ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r
+++ /dev/null
-ModeX - A graphical library for DOS programs\r
-Copyright (c) 1993-1994 Alessandro Scotti\r
-http://www.ascotti.org/\r
-\r
-Please look at the above site in the "Art of..." and\r
-then in the "Old programs" section for more information.\r
-\r
-\r